rk: freq limit resume when disable_limit
authorchenxing <chenxing@rock-chips.com>
Wed, 10 Jul 2013 10:58:15 +0000 (18:58 +0800)
committerchenxing <chenxing@rock-chips.com>
Wed, 10 Jul 2013 10:59:38 +0000 (18:59 +0800)
arch/arm/plat-rk/clock.c
arch/arm/plat-rk/dvfs.c
arch/arm/plat-rk/include/plat/clock.h

index c8054b302304b5db84a4ee8e8a11239ce9fd8d1d..9c4e8badb3b3fdbcf9da914559fac40da5b91bb7 100644 (file)
@@ -280,6 +280,8 @@ int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
                __propagate_rate(clk);
        }
 
+       clk->last_set_rate = rate;
+
        if (clk->notifier_count)
                clk_notify(clk, ret ? CLK_ABORT_RATE_CHANGE : CLK_POST_RATE_CHANGE, old_rate, clk->rate);
 
index f43e959d02583265ff457cc9acb4ba672564ab7c..224bdaadba24584124b55daa8fadd9c70378bb87 100644 (file)
@@ -256,28 +256,56 @@ struct regulator *dvfs_get_regulator(char *regulator_name)
 int dvfs_clk_enable_limit(struct clk *clk, unsigned int min_rate, unsigned max_rate)\r
 {\r
        struct clk_node *dvfs_clk;\r
-       u32 rate = 0;\r
-       dvfs_clk = clk->dvfs_info;\r
+       u32 rate = 0, ret = 0;\r
+       dvfs_clk = clk_get_dvfs_info(clk);\r
+       if (IS_ERR_OR_NULL(dvfs_clk)) {\r
+               DVFS_ERR("%s: can not get dvfs clk(%s)\n", __func__, clk->name);\r
+               return -1;\r
+\r
+       }\r
 \r
-       dvfs_clk->freq_limit_en = 1;\r
-       dvfs_clk->min_rate = min_rate;\r
-       dvfs_clk->max_rate = max_rate;\r
+       if (dvfs_clk->vd && dvfs_clk->vd->vd_dvfs_target){\r
+               mutex_lock(&rk_dvfs_mutex);\r
+\r
+               dvfs_clk->freq_limit_en = 1;\r
+               dvfs_clk->min_rate = min_rate;\r
+               dvfs_clk->max_rate = max_rate;\r
+               rate = clk_get_rate(clk);\r
+               ret = dvfs_clk->vd->vd_dvfs_target(clk, rate);\r
+               clk->last_set_rate = rate;\r
+\r
+               mutex_unlock(&rk_dvfs_mutex);\r
+       }\r
 \r
-       rate = clk_get_rate(clk);\r
-       if (rate < min_rate)\r
-               dvfs_clk_set_rate(clk, min_rate);\r
-       else if (rate > max_rate)\r
-               dvfs_clk_set_rate(clk, max_rate);\r
+       DVFS_DBG("%s: clk(%s) last_set_rate=%d; [min_rate, max_rate]=[%d, %d]\n",\r
+                       __func__, clk->name, clk->last_set_rate, dvfs_clk->min_rate, dvfs_clk->max_rate);\r
        return 0;\r
 }\r
 \r
 int dvfs_clk_disable_limit(struct clk *clk)\r
 {\r
        struct clk_node *dvfs_clk;\r
-       dvfs_clk = clk->dvfs_info;\r
+       u32 ret = 0;\r
+       dvfs_clk = clk_get_dvfs_info(clk);\r
+       if (IS_ERR_OR_NULL(dvfs_clk)) {\r
+               DVFS_ERR("%s: can not get dvfs clk(%s)\n", __func__, clk->name);\r
+               return -1;\r
 \r
-       dvfs_clk->freq_limit_en = 0;\r
+       }\r
+\r
+       if (dvfs_clk->vd && dvfs_clk->vd->vd_dvfs_target){\r
+               mutex_lock(&rk_dvfs_mutex);\r
+               /* To reset dvfs_clk->min_rate/max_rate */\r
+               dvfs_set_freq_volt_table(clk, dvfs_clk->dvfs_table);\r
 \r
+               dvfs_clk->freq_limit_en = 0;\r
+               ret = dvfs_clk->vd->vd_dvfs_target(clk, clk->last_set_rate);\r
+\r
+               mutex_unlock(&rk_dvfs_mutex);\r
+       }\r
+\r
+       DVFS_DBG("%s: clk(%s) last_set_rate=%d; [min_rate, max_rate]=[%d, %d]\n",\r
+                       __func__, clk->name, clk->last_set_rate, dvfs_clk->min_rate, dvfs_clk->max_rate);\r
        return 0;\r
 }\r
 \r
@@ -539,6 +567,7 @@ int dvfs_set_freq_volt_table(struct clk *clk, struct cpufreq_frequency_table *ta
        {\r
                info->min_rate=0;       \r
                info->max_rate=0;       \r
+               mutex_unlock(&mutex);\r
                return -1;\r
        }\r
 \r
@@ -1145,9 +1174,14 @@ static int dump_dbg_map(char *buf)
 \r
                        list_for_each_entry(child, &pd->clk_list, node) {\r
                                dvfs_clk = child->dvfs_clk;\r
-                               printk( "|  |  |\n|  |  |- clock: %s current: rate %d, volt = %d, enable_dvfs = %s\n",\r
+                               printk( "|  |  |\n|  |  |- clock: %s current: rate %d, volt = %d,"\r
+                                               " enable_dvfs = %s\n",\r
                                                dvfs_clk->name, dvfs_clk->set_freq, dvfs_clk->set_volt,\r
                                                dvfs_clk->enable_dvfs == 0 ? "DISABLE" : "ENABLE");\r
+                               printk( "|  |  |- clk limit:[%d, %d]; last set rate = %lu\n",\r
+                                               dvfs_clk->min_rate, dvfs_clk->max_rate,\r
+                                               dvfs_clk->clk->last_set_rate);\r
+\r
                                for (i = 0; dvfs_clk->pds[i].pd != NULL; i++) {\r
                                        clkparent = dvfs_clk->pds[i].pd;\r
                                        printk( "|  |  |  |- clock parents: %s, vd_parent = %s\n",\r
index bc2f7fae2a1276e128a2b46ca9163f73d9e104bb..00ddb36ca2bb9304d1a70ca7cfc4a2f1f0a2a779 100644 (file)
@@ -39,6 +39,7 @@ struct clk {
        int                     (*set_parent)(struct clk *, struct clk *);      /* default is clksel_set_parent if parents present */
 
        unsigned long           rate;
+       unsigned long           last_set_rate;
        u32                     flags;
        s16                     usecount;
        u16                     notifier_count;