xref: /openbmc/linux/arch/arm/mach-omap2/cm3xxx.c (revision ff4ae5d9)
1ff4ae5d9SPaul Walmsley /*
2ff4ae5d9SPaul Walmsley  * OMAP2/3 CM module functions
3ff4ae5d9SPaul Walmsley  *
4ff4ae5d9SPaul Walmsley  * Copyright (C) 2009 Nokia Corporation
5ff4ae5d9SPaul Walmsley  * Copyright (C) 2012 Texas Instruments, Inc.
6ff4ae5d9SPaul Walmsley  * Paul Walmsley
7ff4ae5d9SPaul Walmsley  *
8ff4ae5d9SPaul Walmsley  * This program is free software; you can redistribute it and/or modify
9ff4ae5d9SPaul Walmsley  * it under the terms of the GNU General Public License version 2 as
10ff4ae5d9SPaul Walmsley  * published by the Free Software Foundation.
11ff4ae5d9SPaul Walmsley  */
12ff4ae5d9SPaul Walmsley 
13ff4ae5d9SPaul Walmsley #include <linux/kernel.h>
14ff4ae5d9SPaul Walmsley #include <linux/types.h>
15ff4ae5d9SPaul Walmsley #include <linux/delay.h>
16ff4ae5d9SPaul Walmsley #include <linux/errno.h>
17ff4ae5d9SPaul Walmsley #include <linux/err.h>
18ff4ae5d9SPaul Walmsley #include <linux/io.h>
19ff4ae5d9SPaul Walmsley 
20ff4ae5d9SPaul Walmsley #include "soc.h"
21ff4ae5d9SPaul Walmsley #include "iomap.h"
22ff4ae5d9SPaul Walmsley #include "common.h"
23ff4ae5d9SPaul Walmsley #include "cm.h"
24ff4ae5d9SPaul Walmsley #include "cm3xxx.h"
25ff4ae5d9SPaul Walmsley #include "cm-regbits-34xx.h"
26ff4ae5d9SPaul Walmsley 
27ff4ae5d9SPaul Walmsley static const u8 omap3xxx_cm_idlest_offs[] = {
28ff4ae5d9SPaul Walmsley 	CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3
29ff4ae5d9SPaul Walmsley };
30ff4ae5d9SPaul Walmsley 
31ff4ae5d9SPaul Walmsley /*
32ff4ae5d9SPaul Walmsley  *
33ff4ae5d9SPaul Walmsley  */
34ff4ae5d9SPaul Walmsley 
35ff4ae5d9SPaul Walmsley static void _write_clktrctrl(u8 c, s16 module, u32 mask)
36ff4ae5d9SPaul Walmsley {
37ff4ae5d9SPaul Walmsley 	u32 v;
38ff4ae5d9SPaul Walmsley 
39ff4ae5d9SPaul Walmsley 	v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
40ff4ae5d9SPaul Walmsley 	v &= ~mask;
41ff4ae5d9SPaul Walmsley 	v |= c << __ffs(mask);
42ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(v, module, OMAP2_CM_CLKSTCTRL);
43ff4ae5d9SPaul Walmsley }
44ff4ae5d9SPaul Walmsley 
45ff4ae5d9SPaul Walmsley bool omap3xxx_cm_is_clkdm_in_hwsup(s16 module, u32 mask)
46ff4ae5d9SPaul Walmsley {
47ff4ae5d9SPaul Walmsley 	u32 v;
48ff4ae5d9SPaul Walmsley 
49ff4ae5d9SPaul Walmsley 	v = omap2_cm_read_mod_reg(module, OMAP2_CM_CLKSTCTRL);
50ff4ae5d9SPaul Walmsley 	v &= mask;
51ff4ae5d9SPaul Walmsley 	v >>= __ffs(mask);
52ff4ae5d9SPaul Walmsley 
53ff4ae5d9SPaul Walmsley 	return (v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ? 1 : 0;
54ff4ae5d9SPaul Walmsley }
55ff4ae5d9SPaul Walmsley 
56ff4ae5d9SPaul Walmsley void omap3xxx_cm_clkdm_enable_hwsup(s16 module, u32 mask)
57ff4ae5d9SPaul Walmsley {
58ff4ae5d9SPaul Walmsley 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_ENABLE_AUTO, module, mask);
59ff4ae5d9SPaul Walmsley }
60ff4ae5d9SPaul Walmsley 
61ff4ae5d9SPaul Walmsley void omap3xxx_cm_clkdm_disable_hwsup(s16 module, u32 mask)
62ff4ae5d9SPaul Walmsley {
63ff4ae5d9SPaul Walmsley 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_DISABLE_AUTO, module, mask);
64ff4ae5d9SPaul Walmsley }
65ff4ae5d9SPaul Walmsley 
66ff4ae5d9SPaul Walmsley void omap3xxx_cm_clkdm_force_sleep(s16 module, u32 mask)
67ff4ae5d9SPaul Walmsley {
68ff4ae5d9SPaul Walmsley 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_SLEEP, module, mask);
69ff4ae5d9SPaul Walmsley }
70ff4ae5d9SPaul Walmsley 
71ff4ae5d9SPaul Walmsley void omap3xxx_cm_clkdm_force_wakeup(s16 module, u32 mask)
72ff4ae5d9SPaul Walmsley {
73ff4ae5d9SPaul Walmsley 	_write_clktrctrl(OMAP34XX_CLKSTCTRL_FORCE_WAKEUP, module, mask);
74ff4ae5d9SPaul Walmsley }
75ff4ae5d9SPaul Walmsley 
76ff4ae5d9SPaul Walmsley /*
77ff4ae5d9SPaul Walmsley  *
78ff4ae5d9SPaul Walmsley  */
79ff4ae5d9SPaul Walmsley 
80ff4ae5d9SPaul Walmsley /**
81ff4ae5d9SPaul Walmsley  * omap3xxx_cm_wait_module_ready - wait for a module to leave idle or standby
82ff4ae5d9SPaul Walmsley  * @prcm_mod: PRCM module offset
83ff4ae5d9SPaul Walmsley  * @idlest_id: CM_IDLESTx register ID (i.e., x = 1, 2, 3)
84ff4ae5d9SPaul Walmsley  * @idlest_shift: shift of the bit in the CM_IDLEST* register to check
85ff4ae5d9SPaul Walmsley  *
86ff4ae5d9SPaul Walmsley  * Wait for the PRCM to indicate that the module identified by
87ff4ae5d9SPaul Walmsley  * (@prcm_mod, @idlest_id, @idlest_shift) is clocked.  Return 0 upon
88ff4ae5d9SPaul Walmsley  * success or -EBUSY if the module doesn't enable in time.
89ff4ae5d9SPaul Walmsley  */
90ff4ae5d9SPaul Walmsley int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
91ff4ae5d9SPaul Walmsley {
92ff4ae5d9SPaul Walmsley 	int ena = 0, i = 0;
93ff4ae5d9SPaul Walmsley 	u8 cm_idlest_reg;
94ff4ae5d9SPaul Walmsley 	u32 mask;
95ff4ae5d9SPaul Walmsley 
96ff4ae5d9SPaul Walmsley 	if (!idlest_id || (idlest_id > ARRAY_SIZE(omap3xxx_cm_idlest_offs)))
97ff4ae5d9SPaul Walmsley 		return -EINVAL;
98ff4ae5d9SPaul Walmsley 
99ff4ae5d9SPaul Walmsley 	cm_idlest_reg = omap3xxx_cm_idlest_offs[idlest_id - 1];
100ff4ae5d9SPaul Walmsley 
101ff4ae5d9SPaul Walmsley 	mask = 1 << idlest_shift;
102ff4ae5d9SPaul Walmsley 	ena = 0;
103ff4ae5d9SPaul Walmsley 
104ff4ae5d9SPaul Walmsley 	omap_test_timeout(((omap2_cm_read_mod_reg(prcm_mod, cm_idlest_reg) &
105ff4ae5d9SPaul Walmsley 			    mask) == ena), MAX_MODULE_READY_TIME, i);
106ff4ae5d9SPaul Walmsley 
107ff4ae5d9SPaul Walmsley 	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
108ff4ae5d9SPaul Walmsley }
109ff4ae5d9SPaul Walmsley 
110ff4ae5d9SPaul Walmsley /*
111ff4ae5d9SPaul Walmsley  * Context save/restore code - OMAP3 only
112ff4ae5d9SPaul Walmsley  */
113ff4ae5d9SPaul Walmsley struct omap3_cm_regs {
114ff4ae5d9SPaul Walmsley 	u32 iva2_cm_clksel1;
115ff4ae5d9SPaul Walmsley 	u32 iva2_cm_clksel2;
116ff4ae5d9SPaul Walmsley 	u32 cm_sysconfig;
117ff4ae5d9SPaul Walmsley 	u32 sgx_cm_clksel;
118ff4ae5d9SPaul Walmsley 	u32 dss_cm_clksel;
119ff4ae5d9SPaul Walmsley 	u32 cam_cm_clksel;
120ff4ae5d9SPaul Walmsley 	u32 per_cm_clksel;
121ff4ae5d9SPaul Walmsley 	u32 emu_cm_clksel;
122ff4ae5d9SPaul Walmsley 	u32 emu_cm_clkstctrl;
123ff4ae5d9SPaul Walmsley 	u32 pll_cm_autoidle;
124ff4ae5d9SPaul Walmsley 	u32 pll_cm_autoidle2;
125ff4ae5d9SPaul Walmsley 	u32 pll_cm_clksel4;
126ff4ae5d9SPaul Walmsley 	u32 pll_cm_clksel5;
127ff4ae5d9SPaul Walmsley 	u32 pll_cm_clken2;
128ff4ae5d9SPaul Walmsley 	u32 cm_polctrl;
129ff4ae5d9SPaul Walmsley 	u32 iva2_cm_fclken;
130ff4ae5d9SPaul Walmsley 	u32 iva2_cm_clken_pll;
131ff4ae5d9SPaul Walmsley 	u32 core_cm_fclken1;
132ff4ae5d9SPaul Walmsley 	u32 core_cm_fclken3;
133ff4ae5d9SPaul Walmsley 	u32 sgx_cm_fclken;
134ff4ae5d9SPaul Walmsley 	u32 wkup_cm_fclken;
135ff4ae5d9SPaul Walmsley 	u32 dss_cm_fclken;
136ff4ae5d9SPaul Walmsley 	u32 cam_cm_fclken;
137ff4ae5d9SPaul Walmsley 	u32 per_cm_fclken;
138ff4ae5d9SPaul Walmsley 	u32 usbhost_cm_fclken;
139ff4ae5d9SPaul Walmsley 	u32 core_cm_iclken1;
140ff4ae5d9SPaul Walmsley 	u32 core_cm_iclken2;
141ff4ae5d9SPaul Walmsley 	u32 core_cm_iclken3;
142ff4ae5d9SPaul Walmsley 	u32 sgx_cm_iclken;
143ff4ae5d9SPaul Walmsley 	u32 wkup_cm_iclken;
144ff4ae5d9SPaul Walmsley 	u32 dss_cm_iclken;
145ff4ae5d9SPaul Walmsley 	u32 cam_cm_iclken;
146ff4ae5d9SPaul Walmsley 	u32 per_cm_iclken;
147ff4ae5d9SPaul Walmsley 	u32 usbhost_cm_iclken;
148ff4ae5d9SPaul Walmsley 	u32 iva2_cm_autoidle2;
149ff4ae5d9SPaul Walmsley 	u32 mpu_cm_autoidle2;
150ff4ae5d9SPaul Walmsley 	u32 iva2_cm_clkstctrl;
151ff4ae5d9SPaul Walmsley 	u32 mpu_cm_clkstctrl;
152ff4ae5d9SPaul Walmsley 	u32 core_cm_clkstctrl;
153ff4ae5d9SPaul Walmsley 	u32 sgx_cm_clkstctrl;
154ff4ae5d9SPaul Walmsley 	u32 dss_cm_clkstctrl;
155ff4ae5d9SPaul Walmsley 	u32 cam_cm_clkstctrl;
156ff4ae5d9SPaul Walmsley 	u32 per_cm_clkstctrl;
157ff4ae5d9SPaul Walmsley 	u32 neon_cm_clkstctrl;
158ff4ae5d9SPaul Walmsley 	u32 usbhost_cm_clkstctrl;
159ff4ae5d9SPaul Walmsley 	u32 core_cm_autoidle1;
160ff4ae5d9SPaul Walmsley 	u32 core_cm_autoidle2;
161ff4ae5d9SPaul Walmsley 	u32 core_cm_autoidle3;
162ff4ae5d9SPaul Walmsley 	u32 wkup_cm_autoidle;
163ff4ae5d9SPaul Walmsley 	u32 dss_cm_autoidle;
164ff4ae5d9SPaul Walmsley 	u32 cam_cm_autoidle;
165ff4ae5d9SPaul Walmsley 	u32 per_cm_autoidle;
166ff4ae5d9SPaul Walmsley 	u32 usbhost_cm_autoidle;
167ff4ae5d9SPaul Walmsley 	u32 sgx_cm_sleepdep;
168ff4ae5d9SPaul Walmsley 	u32 dss_cm_sleepdep;
169ff4ae5d9SPaul Walmsley 	u32 cam_cm_sleepdep;
170ff4ae5d9SPaul Walmsley 	u32 per_cm_sleepdep;
171ff4ae5d9SPaul Walmsley 	u32 usbhost_cm_sleepdep;
172ff4ae5d9SPaul Walmsley 	u32 cm_clkout_ctrl;
173ff4ae5d9SPaul Walmsley };
174ff4ae5d9SPaul Walmsley 
175ff4ae5d9SPaul Walmsley static struct omap3_cm_regs cm_context;
176ff4ae5d9SPaul Walmsley 
177ff4ae5d9SPaul Walmsley void omap3_cm_save_context(void)
178ff4ae5d9SPaul Walmsley {
179ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_clksel1 =
180ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1);
181ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_clksel2 =
182ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2);
183ff4ae5d9SPaul Walmsley 	cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG);
184ff4ae5d9SPaul Walmsley 	cm_context.sgx_cm_clksel =
185ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL);
186ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_clksel =
187ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_CLKSEL);
188ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_clksel =
189ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_CLKSEL);
190ff4ae5d9SPaul Walmsley 	cm_context.per_cm_clksel =
191ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_CLKSEL);
192ff4ae5d9SPaul Walmsley 	cm_context.emu_cm_clksel =
193ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1);
194ff4ae5d9SPaul Walmsley 	cm_context.emu_cm_clkstctrl =
195ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL);
196ff4ae5d9SPaul Walmsley 	/*
197ff4ae5d9SPaul Walmsley 	 * As per erratum i671, ROM code does not respect the PER DPLL
198ff4ae5d9SPaul Walmsley 	 * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
199ff4ae5d9SPaul Walmsley 	 * In this case, even though this register has been saved in
200ff4ae5d9SPaul Walmsley 	 * scratchpad contents, we need to restore AUTO_PERIPH_DPLL
201ff4ae5d9SPaul Walmsley 	 * by ourselves. So, we need to save it anyway.
202ff4ae5d9SPaul Walmsley 	 */
203ff4ae5d9SPaul Walmsley 	cm_context.pll_cm_autoidle =
204ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE);
205ff4ae5d9SPaul Walmsley 	cm_context.pll_cm_autoidle2 =
206ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2);
207ff4ae5d9SPaul Walmsley 	cm_context.pll_cm_clksel4 =
208ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL4);
209ff4ae5d9SPaul Walmsley 	cm_context.pll_cm_clksel5 =
210ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5);
211ff4ae5d9SPaul Walmsley 	cm_context.pll_cm_clken2 =
212ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2);
213ff4ae5d9SPaul Walmsley 	cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL);
214ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_fclken =
215ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN);
216ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_clken_pll =
217ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL);
218ff4ae5d9SPaul Walmsley 	cm_context.core_cm_fclken1 =
219ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
220ff4ae5d9SPaul Walmsley 	cm_context.core_cm_fclken3 =
221ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
222ff4ae5d9SPaul Walmsley 	cm_context.sgx_cm_fclken =
223ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_FCLKEN);
224ff4ae5d9SPaul Walmsley 	cm_context.wkup_cm_fclken =
225ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
226ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_fclken =
227ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_FCLKEN);
228ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_fclken =
229ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_FCLKEN);
230ff4ae5d9SPaul Walmsley 	cm_context.per_cm_fclken =
231ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
232ff4ae5d9SPaul Walmsley 	cm_context.usbhost_cm_fclken =
233ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
234ff4ae5d9SPaul Walmsley 	cm_context.core_cm_iclken1 =
235ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
236ff4ae5d9SPaul Walmsley 	cm_context.core_cm_iclken2 =
237ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN2);
238ff4ae5d9SPaul Walmsley 	cm_context.core_cm_iclken3 =
239ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
240ff4ae5d9SPaul Walmsley 	cm_context.sgx_cm_iclken =
241ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_ICLKEN);
242ff4ae5d9SPaul Walmsley 	cm_context.wkup_cm_iclken =
243ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
244ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_iclken =
245ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_ICLKEN);
246ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_iclken =
247ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_ICLKEN);
248ff4ae5d9SPaul Walmsley 	cm_context.per_cm_iclken =
249ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
250ff4ae5d9SPaul Walmsley 	cm_context.usbhost_cm_iclken =
251ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
252ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_autoidle2 =
253ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
254ff4ae5d9SPaul Walmsley 	cm_context.mpu_cm_autoidle2 =
255ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(MPU_MOD, CM_AUTOIDLE2);
256ff4ae5d9SPaul Walmsley 	cm_context.iva2_cm_clkstctrl =
257ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL);
258ff4ae5d9SPaul Walmsley 	cm_context.mpu_cm_clkstctrl =
259ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(MPU_MOD, OMAP2_CM_CLKSTCTRL);
260ff4ae5d9SPaul Walmsley 	cm_context.core_cm_clkstctrl =
261ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, OMAP2_CM_CLKSTCTRL);
262ff4ae5d9SPaul Walmsley 	cm_context.sgx_cm_clkstctrl =
263ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL);
264ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_clkstctrl =
265ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL);
266ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_clkstctrl =
267ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL);
268ff4ae5d9SPaul Walmsley 	cm_context.per_cm_clkstctrl =
269ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL);
270ff4ae5d9SPaul Walmsley 	cm_context.neon_cm_clkstctrl =
271ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL);
272ff4ae5d9SPaul Walmsley 	cm_context.usbhost_cm_clkstctrl =
273ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
274ff4ae5d9SPaul Walmsley 				      OMAP2_CM_CLKSTCTRL);
275ff4ae5d9SPaul Walmsley 	cm_context.core_cm_autoidle1 =
276ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE1);
277ff4ae5d9SPaul Walmsley 	cm_context.core_cm_autoidle2 =
278ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE2);
279ff4ae5d9SPaul Walmsley 	cm_context.core_cm_autoidle3 =
280ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(CORE_MOD, CM_AUTOIDLE3);
281ff4ae5d9SPaul Walmsley 	cm_context.wkup_cm_autoidle =
282ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(WKUP_MOD, CM_AUTOIDLE);
283ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_autoidle =
284ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, CM_AUTOIDLE);
285ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_autoidle =
286ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, CM_AUTOIDLE);
287ff4ae5d9SPaul Walmsley 	cm_context.per_cm_autoidle =
288ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
289ff4ae5d9SPaul Walmsley 	cm_context.usbhost_cm_autoidle =
290ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
291ff4ae5d9SPaul Walmsley 	cm_context.sgx_cm_sleepdep =
292ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
293ff4ae5d9SPaul Walmsley 				      OMAP3430_CM_SLEEPDEP);
294ff4ae5d9SPaul Walmsley 	cm_context.dss_cm_sleepdep =
295ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP);
296ff4ae5d9SPaul Walmsley 	cm_context.cam_cm_sleepdep =
297ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP);
298ff4ae5d9SPaul Walmsley 	cm_context.per_cm_sleepdep =
299ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP);
300ff4ae5d9SPaul Walmsley 	cm_context.usbhost_cm_sleepdep =
301ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
302ff4ae5d9SPaul Walmsley 				      OMAP3430_CM_SLEEPDEP);
303ff4ae5d9SPaul Walmsley 	cm_context.cm_clkout_ctrl =
304ff4ae5d9SPaul Walmsley 		omap2_cm_read_mod_reg(OMAP3430_CCR_MOD,
305ff4ae5d9SPaul Walmsley 				      OMAP3_CM_CLKOUT_CTRL_OFFSET);
306ff4ae5d9SPaul Walmsley }
307ff4ae5d9SPaul Walmsley 
308ff4ae5d9SPaul Walmsley void omap3_cm_restore_context(void)
309ff4ae5d9SPaul Walmsley {
310ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD,
311ff4ae5d9SPaul Walmsley 			       CM_CLKSEL1);
312ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD,
313ff4ae5d9SPaul Walmsley 			       CM_CLKSEL2);
314ff4ae5d9SPaul Walmsley 	__raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG);
315ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD,
316ff4ae5d9SPaul Walmsley 			       CM_CLKSEL);
317ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD,
318ff4ae5d9SPaul Walmsley 			       CM_CLKSEL);
319ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_clksel, OMAP3430_CAM_MOD,
320ff4ae5d9SPaul Walmsley 			       CM_CLKSEL);
321ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_clksel, OMAP3430_PER_MOD,
322ff4ae5d9SPaul Walmsley 			       CM_CLKSEL);
323ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.emu_cm_clksel, OMAP3430_EMU_MOD,
324ff4ae5d9SPaul Walmsley 			       CM_CLKSEL1);
325ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD,
326ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
327ff4ae5d9SPaul Walmsley 	/*
328ff4ae5d9SPaul Walmsley 	 * As per erratum i671, ROM code does not respect the PER DPLL
329ff4ae5d9SPaul Walmsley 	 * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1.
330ff4ae5d9SPaul Walmsley 	 * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves.
331ff4ae5d9SPaul Walmsley 	 */
332ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD,
333ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE);
334ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD,
335ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE2);
336ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD,
337ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_CM_CLKSEL4);
338ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.pll_cm_clksel5, PLL_MOD,
339ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_CM_CLKSEL5);
340ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD,
341ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_CM_CLKEN2);
342ff4ae5d9SPaul Walmsley 	__raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL);
343ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD,
344ff4ae5d9SPaul Walmsley 			       CM_FCLKEN);
345ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD,
346ff4ae5d9SPaul Walmsley 			       OMAP3430_CM_CLKEN_PLL);
347ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_fclken1, CORE_MOD,
348ff4ae5d9SPaul Walmsley 			       CM_FCLKEN1);
349ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_fclken3, CORE_MOD,
350ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_CM_FCLKEN3);
351ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD,
352ff4ae5d9SPaul Walmsley 			       CM_FCLKEN);
353ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN);
354ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_fclken, OMAP3430_DSS_MOD,
355ff4ae5d9SPaul Walmsley 			       CM_FCLKEN);
356ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_fclken, OMAP3430_CAM_MOD,
357ff4ae5d9SPaul Walmsley 			       CM_FCLKEN);
358ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_fclken, OMAP3430_PER_MOD,
359ff4ae5d9SPaul Walmsley 			       CM_FCLKEN);
360ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.usbhost_cm_fclken,
361ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_USBHOST_MOD, CM_FCLKEN);
362ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_iclken1, CORE_MOD,
363ff4ae5d9SPaul Walmsley 			       CM_ICLKEN1);
364ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_iclken2, CORE_MOD,
365ff4ae5d9SPaul Walmsley 			       CM_ICLKEN2);
366ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_iclken3, CORE_MOD,
367ff4ae5d9SPaul Walmsley 			       CM_ICLKEN3);
368ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD,
369ff4ae5d9SPaul Walmsley 			       CM_ICLKEN);
370ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN);
371ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_iclken, OMAP3430_DSS_MOD,
372ff4ae5d9SPaul Walmsley 			       CM_ICLKEN);
373ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_iclken, OMAP3430_CAM_MOD,
374ff4ae5d9SPaul Walmsley 			       CM_ICLKEN);
375ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_iclken, OMAP3430_PER_MOD,
376ff4ae5d9SPaul Walmsley 			       CM_ICLKEN);
377ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.usbhost_cm_iclken,
378ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_USBHOST_MOD, CM_ICLKEN);
379ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_autoidle2, OMAP3430_IVA2_MOD,
380ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE2);
381ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.mpu_cm_autoidle2, MPU_MOD,
382ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE2);
383ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD,
384ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
385ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.mpu_cm_clkstctrl, MPU_MOD,
386ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
387ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_clkstctrl, CORE_MOD,
388ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
389ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD,
390ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
391ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD,
392ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
393ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD,
394ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
395ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_clkstctrl, OMAP3430_PER_MOD,
396ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
397ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD,
398ff4ae5d9SPaul Walmsley 			       OMAP2_CM_CLKSTCTRL);
399ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.usbhost_cm_clkstctrl,
400ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL);
401ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_autoidle1, CORE_MOD,
402ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE1);
403ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_autoidle2, CORE_MOD,
404ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE2);
405ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.core_cm_autoidle3, CORE_MOD,
406ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE3);
407ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.wkup_cm_autoidle, WKUP_MOD,
408ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE);
409ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_autoidle, OMAP3430_DSS_MOD,
410ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE);
411ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_autoidle, OMAP3430_CAM_MOD,
412ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE);
413ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_autoidle, OMAP3430_PER_MOD,
414ff4ae5d9SPaul Walmsley 			       CM_AUTOIDLE);
415ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.usbhost_cm_autoidle,
416ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE);
417ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD,
418ff4ae5d9SPaul Walmsley 			       OMAP3430_CM_SLEEPDEP);
419ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD,
420ff4ae5d9SPaul Walmsley 			       OMAP3430_CM_SLEEPDEP);
421ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD,
422ff4ae5d9SPaul Walmsley 			       OMAP3430_CM_SLEEPDEP);
423ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.per_cm_sleepdep, OMAP3430_PER_MOD,
424ff4ae5d9SPaul Walmsley 			       OMAP3430_CM_SLEEPDEP);
425ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.usbhost_cm_sleepdep,
426ff4ae5d9SPaul Walmsley 			       OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP);
427ff4ae5d9SPaul Walmsley 	omap2_cm_write_mod_reg(cm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD,
428ff4ae5d9SPaul Walmsley 			       OMAP3_CM_CLKOUT_CTRL_OFFSET);
429ff4ae5d9SPaul Walmsley }
430