From 5f07ea237d155f6dac98a58b31b40b6476ef1573 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 21 Jun 2012 20:07:35 +0800 Subject: [PATCH] ENGR00214607 [MX6]Fix CPUFreq change flow issue Previous flow when we change PLL1_SW_CLK from 400M PFD to PLL1_MAIN_CLK is as below: 1. move PLL1_SW_CLK from 400M PFD to PLL1_MAIN_CLK; 2. change PLL1_MAIN_CLK's freq if necessary; There is chance that the PLL1_MAIN_CLK freq is higher than what we want, then after step1, system may hang as we use low voltage to run high freq. The correct flow should be as below: 1. make sure PLL1_MAIN_CLK is enabled; 2. make sure pLL1_MAIN_CLK freq is what we want; 3. move PLL1_SW_CLK from 400M PFD to PLL1_MAIN_CLK. Signed-off-by: Anson Huang --- arch/arm/mach-mx6/clock.c | 35 +++++++++++++++++---------------- arch/arm/mach-mx6/clock_mx6sl.c | 32 ++++++++++++++---------------- arch/arm/mach-mx6/cpu_op-mx6.c | 2 +- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c index 81456655032e..d0f37d60de89 100644 --- a/arch/arm/mach-mx6/clock.c +++ b/arch/arm/mach-mx6/clock.c @@ -1260,26 +1260,27 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sw_clk.parent = &pll2_pfd_400M; } } else { - if (pll1_sw_clk.parent != &pll1_sys_main_clk) { - /* pll1_sw_clk was being sourced from pll2_400M. */ - /* Enable PLL1 and set pll1_sw_clk parent as PLL1 */ - if (!pll1_enabled) - pll1_sys_main_clk.enable(&pll1_sys_main_clk); - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); - pll1_sw_clk.parent = &pll1_sys_main_clk; - arm_needs_pll2_400 = false; - if (pll2_pfd_400M.usecount == 0) - pll2_pfd_400M.disable(&pll2_pfd_400M); - } + /* Make sure PLL1 is enabled */ + if (!pll1_enabled) + pll1_sys_main_clk.enable(&pll1_sys_main_clk); + /* Make sure PLL1 rate is what we want */ if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) { - /* Change the PLL1 rate. */ - if (pll2_pfd_400M.usecount != 0) - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); - else - pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); + /* If pll1_sw_clk is from pll1_sys_main_clk, switch it */ + if (pll1_sw_clk.parent == &pll1_sys_main_clk) { + /* Change the PLL1 rate. */ + if (pll2_pfd_400M.usecount != 0) + pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M); + else + pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); + } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); } + /* Make sure pll1_sw_clk is from pll1_sys_main_clk */ + pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); + pll1_sw_clk.parent = &pll1_sys_main_clk; + arm_needs_pll2_400 = false; + if (pll2_pfd_400M.usecount == 0) + pll2_pfd_400M.disable(&pll2_pfd_400M); } parent_rate = clk_get_rate(clk->parent); div = parent_rate / rate; diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index be00867f729c..42621f73dbbc 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -1149,26 +1149,24 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate) pll1_sw_clk.parent = &pll2_pfd2_400M; } } else { - if (pll1_sw_clk.parent != &pll1_sys_main_clk) { - /* pll1_sw_clk was being sourced from pll2_400M. */ - /* Enable PLL1 and set pll1_sw_clk parent as PLL1 */ - if (!pll1_enabled) - pll1_sys_main_clk.enable(&pll1_sys_main_clk); - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); - pll1_sw_clk.parent = &pll1_sys_main_clk; - arm_needs_pll2_400 = false; - if (pll2_pfd2_400M.usecount == 0) - pll2_pfd2_400M.disable(&pll2_pfd2_400M); - } + /* Make sure PLL1 is enabled */ + if (!pll1_enabled) + pll1_sys_main_clk.enable(&pll1_sys_main_clk); if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) { - /* Change the PLL1 rate. */ - if (pll2_pfd2_400M.usecount != 0) - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); - else - pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); + if (pll1_sw_clk.parent == &pll1_sys_main_clk) { + /* Change the PLL1 rate. */ + if (pll2_pfd2_400M.usecount != 0) + pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd2_400M); + else + pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk); + } pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate); - pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); } + pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk); + pll1_sw_clk.parent = &pll1_sys_main_clk; + arm_needs_pll2_400 = false; + if (pll2_pfd2_400M.usecount == 0) + pll2_pfd2_400M.disable(&pll2_pfd2_400M); } parent_rate = clk_get_rate(clk->parent); div = parent_rate / rate; diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c index faa65fa00934..6fe2fd8e7cbb 100644 --- a/arch/arm/mach-mx6/cpu_op-mx6.c +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -66,7 +66,7 @@ static struct cpu_op mx6_cpu_op_1G[] = { { .pll_rate = 672000000, .cpu_rate = 672000000, - .cpu_voltage = 1100000,}, + .cpu_voltage = 1050000,}, { .pll_rate = 396000000, .cpu_rate = 396000000, -- 2.39.5