diff options
author | Anson Huang <b20788@freescale.com> | 2014-01-09 03:03:16 -0500 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2014-03-04 21:35:01 -0500 |
commit | 751f7e999afcef157527f5f6f06529c93f8a4022 (patch) | |
tree | 49dae752f037aa96d2a61ec88ee5179a75c0d86d /arch/arm/mach-imx/clk-imx6sl.c | |
parent | 848db4a0a17aaf97b8ba5b1f754d635ff622670a (diff) |
ARM: imx: add cpuidle support for i.mx6sl
Add cpuidle support for i.MX6SL, currently only support
two cpuidle levels(ARM wfi and WAIT mode), and add software
workaround for WAIT mode errata as below:
ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken
during WAIT mode entry process could cause cache memory
corruption.
Software workaround:
To prevent this issue from occurring, software should ensure that
the ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before
entering WAIT mode.
Signed-off-by: Anson Huang <b20788@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'arch/arm/mach-imx/clk-imx6sl.c')
-rw-r--r-- | arch/arm/mach-imx/clk-imx6sl.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c index c5f17c2d4951..6f21a1333fe4 100644 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ b/arch/arm/mach-imx/clk-imx6sl.c | |||
@@ -66,6 +66,32 @@ static struct clk_div_table video_div_table[] = { | |||
66 | static struct clk *clks[IMX6SL_CLK_END]; | 66 | static struct clk *clks[IMX6SL_CLK_END]; |
67 | static struct clk_onecell_data clk_data; | 67 | static struct clk_onecell_data clk_data; |
68 | 68 | ||
69 | /* | ||
70 | * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken | ||
71 | * during WAIT mode entry process could cause cache memory | ||
72 | * corruption. | ||
73 | * | ||
74 | * Software workaround: | ||
75 | * To prevent this issue from occurring, software should ensure that the | ||
76 | * ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before | ||
77 | * entering WAIT mode. | ||
78 | * | ||
79 | * This function will set the ARM clk to max value within the 12:5 limit. | ||
80 | */ | ||
81 | void imx6sl_set_wait_clk(bool enter) | ||
82 | { | ||
83 | static unsigned long saved_arm_rate; | ||
84 | |||
85 | if (enter) { | ||
86 | unsigned long ipg_rate = clk_get_rate(clks[IMX6SL_CLK_IPG]); | ||
87 | unsigned long max_arm_wait_rate = (12 * ipg_rate) / 5; | ||
88 | saved_arm_rate = clk_get_rate(clks[IMX6SL_CLK_ARM]); | ||
89 | clk_set_rate(clks[IMX6SL_CLK_ARM], max_arm_wait_rate); | ||
90 | } else { | ||
91 | clk_set_rate(clks[IMX6SL_CLK_ARM], saved_arm_rate); | ||
92 | } | ||
93 | } | ||
94 | |||
69 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) | 95 | static void __init imx6sl_clocks_init(struct device_node *ccm_node) |
70 | { | 96 | { |
71 | struct device_node *np; | 97 | struct device_node *np; |