aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2016-03-09 21:16:50 -0500
committerShawn Guo <shawnguo@kernel.org>2016-03-31 05:02:06 -0400
commit4cfe6aebb272d7c75a2c21ce5db3a9e10f57901a (patch)
treeef73409542b962251822ff8344a67cda1f3176a0
parent349efbeedb2b79292eee12cf6b9a2422ef93853d (diff)
clk: imx: vf610: add suspend/resume support
The clock register are lost when enterying LPSTOPx, hence provide suspend/resume functions restoring them. The clock gates get restored by the individual driver, hence we do not need to restore them here. Signed-off-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Shawn Guo <shawnguo@kernel.org>
-rw-r--r--drivers/clk/imx/clk-vf610.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 610a72464f1e..66e6faede8e5 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -10,6 +10,7 @@
10 10
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/syscore_ops.h>
13#include <dt-bindings/clock/vf610-clock.h> 14#include <dt-bindings/clock/vf610-clock.h>
14 15
15#include "clk.h" 16#include "clk.h"
@@ -40,6 +41,7 @@
40#define CCM_CCGR9 (ccm_base + 0x64) 41#define CCM_CCGR9 (ccm_base + 0x64)
41#define CCM_CCGR10 (ccm_base + 0x68) 42#define CCM_CCGR10 (ccm_base + 0x68)
42#define CCM_CCGR11 (ccm_base + 0x6c) 43#define CCM_CCGR11 (ccm_base + 0x6c)
44#define CCM_CCGRx(x) (CCM_CCGR0 + (x) * 4)
43#define CCM_CMEOR0 (ccm_base + 0x70) 45#define CCM_CMEOR0 (ccm_base + 0x70)
44#define CCM_CMEOR1 (ccm_base + 0x74) 46#define CCM_CMEOR1 (ccm_base + 0x74)
45#define CCM_CMEOR2 (ccm_base + 0x78) 47#define CCM_CMEOR2 (ccm_base + 0x78)
@@ -115,6 +117,13 @@ static struct clk_div_table pll4_audio_div_table[] = {
115static struct clk *clk[VF610_CLK_END]; 117static struct clk *clk[VF610_CLK_END];
116static struct clk_onecell_data clk_data; 118static struct clk_onecell_data clk_data;
117 119
120static u32 cscmr1;
121static u32 cscmr2;
122static u32 cscdr1;
123static u32 cscdr2;
124static u32 cscdr3;
125static u32 ccgr[12];
126
118static unsigned int const clks_init_on[] __initconst = { 127static unsigned int const clks_init_on[] __initconst = {
119 VF610_CLK_SYS_BUS, 128 VF610_CLK_SYS_BUS,
120 VF610_CLK_DDR_SEL, 129 VF610_CLK_DDR_SEL,
@@ -134,6 +143,43 @@ static struct clk * __init vf610_get_fixed_clock(
134 return clk; 143 return clk;
135}; 144};
136 145
146static int vf610_clk_suspend(void)
147{
148 int i;
149
150 cscmr1 = readl_relaxed(CCM_CSCMR1);
151 cscmr2 = readl_relaxed(CCM_CSCMR2);
152
153 cscdr1 = readl_relaxed(CCM_CSCDR1);
154 cscdr2 = readl_relaxed(CCM_CSCDR2);
155 cscdr3 = readl_relaxed(CCM_CSCDR3);
156
157 for (i = 0; i < 12; i++)
158 ccgr[i] = readl_relaxed(CCM_CCGRx(i));
159
160 return 0;
161}
162
163static void vf610_clk_resume(void)
164{
165 int i;
166
167 writel_relaxed(cscmr1, CCM_CSCMR1);
168 writel_relaxed(cscmr2, CCM_CSCMR2);
169
170 writel_relaxed(cscdr1, CCM_CSCDR1);
171 writel_relaxed(cscdr2, CCM_CSCDR2);
172 writel_relaxed(cscdr3, CCM_CSCDR3);
173
174 for (i = 0; i < 12; i++)
175 writel_relaxed(ccgr[i], CCM_CCGRx(i));
176}
177
178static struct syscore_ops vf610_clk_syscore_ops = {
179 .suspend = vf610_clk_suspend,
180 .resume = vf610_clk_resume,
181};
182
137static void __init vf610_clocks_init(struct device_node *ccm_node) 183static void __init vf610_clocks_init(struct device_node *ccm_node)
138{ 184{
139 struct device_node *np; 185 struct device_node *np;
@@ -414,6 +460,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
414 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) 460 for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
415 clk_prepare_enable(clk[clks_init_on[i]]); 461 clk_prepare_enable(clk[clks_init_on[i]]);
416 462
463 register_syscore_ops(&vf610_clk_syscore_ops);
464
417 /* Add the clocks to provider list */ 465 /* Add the clocks to provider list */
418 clk_data.clks = clk; 466 clk_data.clks = clk;
419 clk_data.clk_num = ARRAY_SIZE(clk); 467 clk_data.clk_num = ARRAY_SIZE(clk);