diff options
author | Anson Huang <b20788@freescale.com> | 2012-06-21 20:07:35 +0800 |
---|---|---|
committer | Terry Lv <r65388@freescale.com> | 2012-06-25 15:54:03 +0800 |
commit | 14036084e2027fd9254465559bf95bf0f67264ef (patch) | |
tree | dd9ce231ebd5649171226476c3835b475e4675fd /arch/arm/mach-mx6/clock.c | |
parent | 455748c803d874e54271852ec3124f5de6bb0397 (diff) |
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 <b20788@freescale.com>
Diffstat (limited to 'arch/arm/mach-mx6/clock.c')
-rw-r--r-- | arch/arm/mach-mx6/clock.c | 35 |
1 files changed, 18 insertions, 17 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; |