From 7dc0b3f5269bfa056e25f944eb2a4925a56da9fa Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=99=88=E4=BA=AE?= Date: Wed, 21 May 2014 02:11:06 -0700 Subject: [PATCH] ddrfreq: separate ddr from clk frame to fix dead lock and advance performance --- arch/arm/mach-rockchip/ddr_freq.c | 17 +++++++++++++++++ arch/arm/mach-rockchip/dvfs.c | 12 ++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-rockchip/ddr_freq.c b/arch/arm/mach-rockchip/ddr_freq.c index 9daf0b5833ef..6284eac31677 100644 --- a/arch/arm/mach-rockchip/ddr_freq.c +++ b/arch/arm/mach-rockchip/ddr_freq.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "../../../drivers/clk/rockchip/clk-pd.h" extern int rockchip_cpufreq_reboot_limit_freq(void); @@ -734,6 +735,20 @@ int of_init_ddr_freq_table(void) return 0; } +static int ddrfreq_scale_rate_for_dvfs(struct clk *clk, unsigned long rate) +{ + unsigned long real_rate; + + real_rate = ddr_change_freq(rate/MHZ); + real_rate *= MHZ; + if (!real_rate) + return -EAGAIN; + + clk->parent->rate = clk->rate = real_rate; + + return 0; +} + #if defined(CONFIG_RK_PM_TESTS) static void ddrfreq_tst_init(void); #endif @@ -758,6 +773,8 @@ static int ddrfreq_init(void) return -EINVAL; } clk_enable_dvfs(ddr.clk_dvfs_node); + + dvfs_clk_register_set_rate_callback(ddr.clk_dvfs_node, ddrfreq_scale_rate_for_dvfs); init_waitqueue_head(&ddr.wait); INIT_LIST_HEAD(&ddr.video_info_list); diff --git a/arch/arm/mach-rockchip/dvfs.c b/arch/arm/mach-rockchip/dvfs.c index aa24b246fa94..e2922a141d21 100644 --- a/arch/arm/mach-rockchip/dvfs.c +++ b/arch/arm/mach-rockchip/dvfs.c @@ -341,7 +341,7 @@ static void dvfs_table_round_clk_rate(struct dvfs_node *clk_dvfs_node) //ddr rate = real rate+flags flags = clk_dvfs_node->dvfs_table[i].frequency%1000; rate = (clk_dvfs_node->dvfs_table[i].frequency/1000)*1000; - temp_rate = clk_round_rate(clk_dvfs_node->clk, rate*1000); + temp_rate = __clk_round_rate(clk_dvfs_node->clk, rate*1000); if(temp_rate <= 0){ DVFS_WARNING("%s: clk(%s) rate %d round return %d\n", __func__, clk_dvfs_node->name, clk_dvfs_node->dvfs_table[i].frequency, temp_rate); @@ -564,7 +564,7 @@ int dvfs_clk_enable_limit(struct dvfs_node *clk_dvfs_node, unsigned int min_rate } if (clk_dvfs_node->last_set_rate == 0) - rate = clk_get_rate(clk_dvfs_node->clk); + rate = __clk_get_rate(clk_dvfs_node->clk); else rate = clk_dvfs_node->last_set_rate; ret = clk_dvfs_node->vd->vd_dvfs_target(clk_dvfs_node, rate); @@ -865,8 +865,8 @@ static int dvfs_target(struct dvfs_node *clk_dvfs_node, unsigned long rate) } rate = dvfs_get_limit_rate(clk_dvfs_node, rate); - new_rate = clk_round_rate(clk, rate); - old_rate = clk_get_rate(clk); + new_rate = __clk_round_rate(clk, rate); + old_rate = __clk_get_rate(clk); if (new_rate == old_rate) return 0; @@ -908,7 +908,7 @@ static int dvfs_target(struct dvfs_node *clk_dvfs_node, unsigned long rate) clk_dvfs_node->set_freq = new_rate / 1000; DVFS_DBG("%s:dvfs clk(%s) set rate %lu ok\n", - __func__, clk_dvfs_node->name, clk_get_rate(clk)); + __func__, clk_dvfs_node->name, __clk_get_rate(clk)); /* if down the rate */ if (new_rate < old_rate) { @@ -926,7 +926,7 @@ out: unsigned long dvfs_clk_get_rate(struct dvfs_node *clk_dvfs_node) { - return clk_get_rate(clk_dvfs_node->clk); + return __clk_get_rate(clk_dvfs_node->clk); } EXPORT_SYMBOL_GPL(dvfs_clk_get_rate); -- 2.34.1