From 9d8cad781ad58668eff2e4b904a522223417990a Mon Sep 17 00:00:00 2001 From: xxx Date: Wed, 9 May 2012 17:48:40 -0700 Subject: [PATCH] suport gpu dvs --- arch/arm/mach-rk30/board-rk30-sdk.c | 13 +++++++++++ arch/arm/mach-rk30/clock.c | 5 ++++ arch/arm/mach-rk30/clock.h | 1 + arch/arm/mach-rk30/cpufreq.c | 14 +++++++++++ arch/arm/mach-rk30/dvfs.c | 32 ++++++++++++++++++-------- arch/arm/mach-rk30/include/mach/dvfs.h | 2 +- 6 files changed, 56 insertions(+), 11 deletions(-) mode change 100755 => 100644 arch/arm/mach-rk30/board-rk30-sdk.c mode change 100755 => 100644 arch/arm/mach-rk30/clock.c mode change 100755 => 100644 arch/arm/mach-rk30/clock.h mode change 100755 => 100644 arch/arm/mach-rk30/cpufreq.c mode change 100755 => 100644 arch/arm/mach-rk30/dvfs.c diff --git a/arch/arm/mach-rk30/board-rk30-sdk.c b/arch/arm/mach-rk30/board-rk30-sdk.c old mode 100755 new mode 100644 index ba0b818243b8..c295625b592f --- a/arch/arm/mach-rk30/board-rk30-sdk.c +++ b/arch/arm/mach-rk30/board-rk30-sdk.c @@ -1440,6 +1440,17 @@ static struct dvfs_arm_table dvfs_cpu_logic_table[] = { {.frequency = 1608 * 1000, .cpu_volt = 1350 * 1000, .logic_volt = 1200 * 1000},//1.325V/1.175V {.frequency = CPUFREQ_TABLE_END}, }; +static struct cpufreq_frequency_table dvfs_gpu_table[] = { + {.frequency = 266 * 1000, .index = 1000 * 1000}, + {.frequency = 400 * 1000, .index = 1350 * 1000}, + {.frequency = CPUFREQ_TABLE_END}, +}; + +static struct cpufreq_frequency_table dvfs_ddr_table[] = { + {.frequency = 300 * 1000, .index = 1000 * 1000}, + {.frequency = 400 * 1000, .index = 1100 * 1000}, + {.frequency = CPUFREQ_TABLE_END}, +}; #define DVFS_CPU_TABLE_SIZE (ARRAY_SIZE(dvfs_cpu_logic_table)) static struct cpufreq_frequency_table cpu_dvfs_table[DVFS_CPU_TABLE_SIZE]; @@ -1449,6 +1460,8 @@ void __init board_clock_init(void) { rk30_clock_data_init(periph_pll_default, codec_pll_default, RK30_CLOCKS_DEFAULT_FLAGS); dvfs_set_arm_logic_volt(dvfs_cpu_logic_table, cpu_dvfs_table, dep_cpu2core_table); + dvfs_set_freq_volt_table(clk_get(NULL, "gpu"), dvfs_gpu_table); + dvfs_set_freq_volt_table(clk_get(NULL, "ddr"), dvfs_ddr_table); } MACHINE_START(RK30, "RK30board") diff --git a/arch/arm/mach-rk30/clock.c b/arch/arm/mach-rk30/clock.c old mode 100755 new mode 100644 index 6950186b5cf3..e0afe5b05819 --- a/arch/arm/mach-rk30/clock.c +++ b/arch/arm/mach-rk30/clock.c @@ -244,6 +244,11 @@ long clk_round_rate_nolock(struct clk *clk, unsigned long rate) return clk->rate; } +int is_suport_round_rate(struct clk *clk) +{ + return (clk->round_rate) ? 0:(-1); +} + int clk_set_rate_nolock(struct clk *clk, unsigned long rate) { int ret; diff --git a/arch/arm/mach-rk30/clock.h b/arch/arm/mach-rk30/clock.h old mode 100755 new mode 100644 index 7bf2696eaa48..fdecd15d4975 --- a/arch/arm/mach-rk30/clock.h +++ b/arch/arm/mach-rk30/clock.h @@ -73,6 +73,7 @@ int clk_set_parent_nolock(struct clk *clk, struct clk *parent); int clk_set_rate_locked(struct clk * clk,unsigned long rate); void clk_register_dvfs(struct clk_node *dvfs_clk, struct clk *clk); struct clk_node *clk_get_dvfs_info(struct clk *clk); +int is_suport_round_rate(struct clk *clk); #ifdef RK30_CLK_OFFBOARD_TEST #include diff --git a/arch/arm/mach-rk30/cpufreq.c b/arch/arm/mach-rk30/cpufreq.c old mode 100755 new mode 100644 index b05a842a5d38..cdc8c7f21f4b --- a/arch/arm/mach-rk30/cpufreq.c +++ b/arch/arm/mach-rk30/cpufreq.c @@ -202,6 +202,20 @@ static int rk30_verify_speed(struct cpufreq_policy *policy) static int rk30_cpu_init(struct cpufreq_policy *policy) { if (policy->cpu == 0) { + struct clk *gpu_clk; + struct clk *ddr_clk; + + gpu_clk = clk_get(NULL, "gpu"); + if (!IS_ERR(gpu_clk)) + clk_enable_dvfs(gpu_clk); + + ddr_clk = clk_get(NULL, "ddr"); + if (!IS_ERR(ddr_clk)) + { + clk_enable_dvfs(ddr_clk); + clk_set_rate(ddr_clk,clk_get_rate(ddr_clk)+1); + } + cpu_clk = clk_get(NULL, "cpu"); if (IS_ERR(cpu_clk)) return PTR_ERR(cpu_clk); diff --git a/arch/arm/mach-rk30/dvfs.c b/arch/arm/mach-rk30/dvfs.c old mode 100755 new mode 100644 index d7d48b50bfda..40ef00fcd436 --- a/arch/arm/mach-rk30/dvfs.c +++ b/arch/arm/mach-rk30/dvfs.c @@ -51,6 +51,7 @@ static LIST_HEAD(rk_dvfs_tree); static DEFINE_MUTEX(mutex); +static DEFINE_MUTEX(rk_dvfs_mutex); extern int rk30_clk_notifier_register(struct clk *clk, struct notifier_block *nb); extern int rk30_clk_notifier_unregister(struct clk *clk, struct notifier_block *nb); @@ -78,9 +79,11 @@ int dvfs_set_rate(struct clk *clk, unsigned long rate) ret = -1; } else { vd = clk->dvfs_info->vd; - mutex_lock(&vd->dvfs_mutex); + // mutex_lock(&vd->dvfs_mutex); + mutex_lock(&rk_dvfs_mutex); ret = vd->vd_dvfs_target(clk, rate); - mutex_unlock(&vd->dvfs_mutex); + mutex_unlock(&rk_dvfs_mutex); + // mutex_unlock(&vd->dvfs_mutex); } DVFS_DBG("%s(%s(%lu)),is end\n", __func__, clk->name, rate); return ret; @@ -439,7 +442,7 @@ static int rk_regist_vd(struct vd_node *vd) if (!vd) return -1; mutex_lock(&mutex); - mutex_init(&vd->dvfs_mutex); + //mutex_init(&vd->dvfs_mutex); list_add(&vd->node, &rk_dvfs_tree); INIT_LIST_HEAD(&vd->pd_list); INIT_LIST_HEAD(&vd->req_volt_list); @@ -665,10 +668,16 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz) DVFS_ERR("%s can't get dvfs regulater\n", clk->name); return -1; } - - // clk_round_rate_nolock(clk, rate_hz); + rate_new = rate_hz; rate_old = clk_get_rate(clk); + if(!is_suport_round_rate(clk)) + { + rate_new=clk_round_rate_nolock(clk, rate_hz); + } + if(rate_new==rate_old) + return 0; + // DVFS_DBG("dvfs(%s) round rate(%lu)(rount %lu)\n",dvfs_clk->name,rate_hz,rate_new); @@ -679,11 +688,8 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz) return -1; } volt_old = dvfs_clk->vd->cur_volt; - volt_clk_old = dvfs_clk->set_volt; - dvfs_clk->set_volt = clk_fv.index; - volt_new = dvfs_vd_get_newvolt_byclk(dvfs_clk); DVFS_DBG("dvfs--(%s),volt=%d(was %dmV),rate=%lu(was %lu),vd%u=(was%u)\n", @@ -692,6 +698,12 @@ int dvfs_target_core(struct clk *clk, unsigned long rate_hz) if (flag_core_set_volt_err) { /* It means the last time set voltage error */ + if (!IS_ERR(dvfs_clk->vd->regulator)) + flag_set_volt_correct = dvfs_regulator_get_voltage(dvfs_clk->vd->regulator); + else { + DVFS_ERR("dvfs regulator is ERROR\n"); + } + flag_set_volt_correct = dvfs_regulator_get_voltage(dvfs_clk->vd->regulator); if (flag_set_volt_correct <= 0) { DVFS_ERR("%s (clk:%s),volt=%d(was %dmV),rate=%lu(was %lu), try to reload core_volt error %d!!! stop scaling\n", @@ -937,8 +949,8 @@ static struct cpufreq_frequency_table ddr_dvfs_table[] = { }; static struct cpufreq_frequency_table gpu_dvfs_table[] = { - {.frequency = 100 * DVFS_KHZ, .index = 1000 * DVFS_MV}, - {.frequency = 200 * DVFS_KHZ, .index = 1050 * DVFS_MV}, + {.frequency = 90 * DVFS_KHZ, .index = 1100 * DVFS_MV}, + {.frequency = 180 * DVFS_KHZ, .index = 1150 * DVFS_MV}, {.frequency = 300 * DVFS_KHZ, .index = 1100 * DVFS_MV}, {.frequency = 400 * DVFS_KHZ, .index = 1150 * DVFS_MV}, {.frequency = 500 * DVFS_KHZ, .index = 1200 * DVFS_MV}, diff --git a/arch/arm/mach-rk30/include/mach/dvfs.h b/arch/arm/mach-rk30/include/mach/dvfs.h index 256e6adbdb0b..e20c992c5531 100755 --- a/arch/arm/mach-rk30/include/mach/dvfs.h +++ b/arch/arm/mach-rk30/include/mach/dvfs.h @@ -43,7 +43,7 @@ struct vd_node { struct list_head node; struct list_head pd_list; struct list_head req_volt_list; - struct mutex dvfs_mutex; + //struct mutex dvfs_mutex; vd_dvfs_target_callback vd_dvfs_target; }; -- 2.34.1