From f0a1404739d7e0e63e8e2745bf92af10faeb0fc4 Mon Sep 17 00:00:00 2001 From: chenxing Date: Fri, 6 Jul 2012 15:09:02 +0800 Subject: [PATCH] rk30:sdk: store clock request frequency and auto scale frequency when limit clock frequency --- arch/arm/mach-rk30/dvfs.c | 32 +++++++++++++++++++++++++- arch/arm/mach-rk30/include/mach/dvfs.h | 7 +++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-rk30/dvfs.c b/arch/arm/mach-rk30/dvfs.c index fe6cf1e225f0..ba21ee29a758 100644 --- a/arch/arm/mach-rk30/dvfs.c +++ b/arch/arm/mach-rk30/dvfs.c @@ -102,25 +102,52 @@ struct regulator* dvfs_get_regulator(char *regulator_name) return NULL; } -int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate) +int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned int max_rate) { struct clk_node* dvfs_clk; + if (!clk->dvfs_info) { + DVFS_ERR("%s bad dvfs clock\n", __func__); + return -1; + } dvfs_clk = clk->dvfs_info; dvfs_clk->freq_limit_en = 1; dvfs_clk->min_rate = min_rate; dvfs_clk->max_rate = max_rate; + if (!dvfs_clk->enable_dvfs) { + DVFS_ERR("%s dvfs not enable yet\n", __func__); + return -1; + } + + if (dvfs_clk->req_freq != 0) + dvfs_set_rate(clk, dvfs_clk->req_freq); + else + dvfs_set_rate(clk, dvfs_clk->set_freq); return 0; } int dvfs_clk_disable_limit(struct clk *clk) { struct clk_node* dvfs_clk; + if (!clk->dvfs_info) { + DVFS_ERR("%s bad dvfs clock\n", __func__); + return -1; + } dvfs_clk = clk->dvfs_info; dvfs_clk->freq_limit_en = 0; + if (!dvfs_clk->enable_dvfs) { + DVFS_ERR("%s dvfs not enable yet\n", __func__); + return -1; + } + + if (dvfs_clk->req_freq != 0) + dvfs_set_rate(clk, dvfs_clk->req_freq); + else + dvfs_set_rate(clk, dvfs_clk->set_freq); + return 0; } @@ -543,6 +570,7 @@ static int rk_regist_clk(struct clk_node *dvfs_clk) return -1; mutex_lock(&mutex); dvfs_clk->enable_dvfs = 0; + dvfs_clk->req_freq = 0; dvfs_clk->vd = dvfs_clk->pds[0].pd->vd; for (i = 0; dvfs_clk->pds[i].pd != NULL; i++) { child = &(dvfs_clk->pds[i].clk_list); @@ -728,6 +756,7 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz) return -1; } + dvfs_clk->req_freq = rate_hz; /* Check limit rate */ if (dvfs_clk->freq_limit_en) { if (rate_hz < dvfs_clk->min_rate) { @@ -874,6 +903,7 @@ int dvfs_target_cpu(struct clk *clk, unsigned long rate_hz) return -1; } + dvfs_clk->req_freq = rate_hz; /* Check limit rate */ if (dvfs_clk->freq_limit_en) { if (rate_hz < dvfs_clk->min_rate) { diff --git a/arch/arm/mach-rk30/include/mach/dvfs.h b/arch/arm/mach-rk30/include/mach/dvfs.h index d20eb9954eb7..8a984c3e3a5e 100644 --- a/arch/arm/mach-rk30/include/mach/dvfs.h +++ b/arch/arm/mach-rk30/include/mach/dvfs.h @@ -116,7 +116,8 @@ struct depend_lookup { */ struct clk_node { char *name; - int set_freq; //KHZ + int req_freq; //KHZ, frequency request + int set_freq; //KHZ, frequency be set int set_volt; //MV int enable_dvfs; int freq_limit_en; //sign if use limit frequency @@ -151,7 +152,7 @@ int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *ta int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequency_table *table); int dvfs_set_arm_logic_volt(struct dvfs_arm_table *dvfs_cpu_logic_table, struct cpufreq_frequency_table *cpu_dvfs_table, struct cpufreq_frequency_table *dep_cpu2core_table); struct regulator* dvfs_get_regulator(char *regulator_name); -int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate); +int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned int max_rate); int dvfs_clk_disable_limit(struct clk *clk); void avs_init(void); @@ -170,7 +171,7 @@ static inline int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequ static inline int dvfs_set_depend_table(struct clk *clk, char *vd_name, struct cpufreq_frequency_table *table) {return 0;} static inline int dvfs_set_arm_logic_volt(struct dvfs_arm_table *dvfs_cpu_logic_table, struct cpufreq_frequency_table *cpu_dvfs_table, struct cpufreq_frequency_table *dep_cpu2core_table){ return 0; } static inline struct regulator* dvfs_get_regulator(char *regulator_name){ return NULL; } -static inline int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate){ return 0; } +static inline int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned int max_rate){ return 0; } static inline int dvfs_clk_disable_limit(struct clk *clk){ return 0; }; static inline void avs_init(void){}; -- 2.34.1