summaryrefslogtreecommitdiff
path: root/arch/arm/mach-mx6/clock.c
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2012-06-21 20:07:35 +0800
committerTerry Lv <r65388@freescale.com>2012-06-25 15:54:03 +0800
commit14036084e2027fd9254465559bf95bf0f67264ef (patch)
treedd9ce231ebd5649171226476c3835b475e4675fd /arch/arm/mach-mx6/clock.c
parent455748c803d874e54271852ec3124f5de6bb0397 (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.c35
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;