1 /*
2  * OMAP3 powerdomain definitions
3  *
4  * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
5  * Copyright (C) 2007-2011 Nokia Corporation
6  *
7  * Paul Walmsley, Jouni Högander
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 
17 #include <plat/cpu.h>
18 
19 #include "powerdomain.h"
20 #include "powerdomains2xxx_3xxx_data.h"
21 
22 #include "prcm-common.h"
23 #include "prm2xxx_3xxx.h"
24 #include "prm-regbits-34xx.h"
25 #include "cm2xxx_3xxx.h"
26 #include "cm-regbits-34xx.h"
27 
28 /*
29  * 34XX-specific powerdomains, dependencies
30  */
31 
32 /*
33  * Powerdomains
34  */
35 
36 static struct powerdomain iva2_pwrdm = {
37 	.name		  = "iva2_pwrdm",
38 	.prcm_offs	  = OMAP3430_IVA2_MOD,
39 	.pwrsts		  = PWRSTS_OFF_RET_ON,
40 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
41 	.banks		  = 4,
42 	.pwrsts_mem_ret	  = {
43 		[0] = PWRSTS_OFF_RET,
44 		[1] = PWRSTS_OFF_RET,
45 		[2] = PWRSTS_OFF_RET,
46 		[3] = PWRSTS_OFF_RET,
47 	},
48 	.pwrsts_mem_on	  = {
49 		[0] = PWRSTS_ON,
50 		[1] = PWRSTS_ON,
51 		[2] = PWRSTS_OFF_ON,
52 		[3] = PWRSTS_ON,
53 	},
54 	.voltdm           = { .name = "mpu_iva" },
55 };
56 
57 static struct powerdomain mpu_3xxx_pwrdm = {
58 	.name		  = "mpu_pwrdm",
59 	.prcm_offs	  = MPU_MOD,
60 	.pwrsts		  = PWRSTS_OFF_RET_ON,
61 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
62 	.flags		  = PWRDM_HAS_MPU_QUIRK,
63 	.banks		  = 1,
64 	.pwrsts_mem_ret	  = {
65 		[0] = PWRSTS_OFF_RET,
66 	},
67 	.pwrsts_mem_on	  = {
68 		[0] = PWRSTS_OFF_ON,
69 	},
70 	.voltdm           = { .name = "mpu_iva" },
71 };
72 
73 /*
74  * The USBTLL Save-and-Restore mechanism is broken on
75  * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
76  * needs to be disabled on these chips.
77  * Refer: 3430 errata ID i459 and 3630 errata ID i579
78  *
79  * Note: setting the SAR flag could help for errata ID i478
80  *  which applies to 3430 <= ES3.1, but since the SAR feature
81  *  is broken, do not use it.
82  */
83 static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
84 	.name		  = "core_pwrdm",
85 	.prcm_offs	  = CORE_MOD,
86 	.pwrsts		  = PWRSTS_OFF_RET_ON,
87 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
88 	.banks		  = 2,
89 	.pwrsts_mem_ret	  = {
90 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
91 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
92 	},
93 	.pwrsts_mem_on	  = {
94 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
95 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
96 	},
97 	.voltdm           = { .name = "core" },
98 };
99 
100 static struct powerdomain core_3xxx_es3_1_pwrdm = {
101 	.name		  = "core_pwrdm",
102 	.prcm_offs	  = CORE_MOD,
103 	.pwrsts		  = PWRSTS_OFF_RET_ON,
104 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
105 	/*
106 	 * Setting the SAR flag for errata ID i478 which applies
107 	 *  to 3430 <= ES3.1
108 	 */
109 	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
110 	.banks		  = 2,
111 	.pwrsts_mem_ret	  = {
112 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
113 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
114 	},
115 	.pwrsts_mem_on	  = {
116 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
117 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
118 	},
119 	.voltdm           = { .name = "core" },
120 };
121 
122 static struct powerdomain dss_pwrdm = {
123 	.name		  = "dss_pwrdm",
124 	.prcm_offs	  = OMAP3430_DSS_MOD,
125 	.pwrsts		  = PWRSTS_OFF_RET_ON,
126 	.pwrsts_logic_ret = PWRSTS_RET,
127 	.banks		  = 1,
128 	.pwrsts_mem_ret	  = {
129 		[0] = PWRSTS_RET, /* MEMRETSTATE */
130 	},
131 	.pwrsts_mem_on	  = {
132 		[0] = PWRSTS_ON,  /* MEMONSTATE */
133 	},
134 	.voltdm           = { .name = "core" },
135 };
136 
137 /*
138  * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
139  * possible SGX powerstate, the SGX device itself does not support
140  * retention.
141  */
142 static struct powerdomain sgx_pwrdm = {
143 	.name		  = "sgx_pwrdm",
144 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
145 	/* XXX This is accurate for 3430 SGX, but what about GFX? */
146 	.pwrsts		  = PWRSTS_OFF_ON,
147 	.pwrsts_logic_ret = PWRSTS_RET,
148 	.banks		  = 1,
149 	.pwrsts_mem_ret	  = {
150 		[0] = PWRSTS_RET, /* MEMRETSTATE */
151 	},
152 	.pwrsts_mem_on	  = {
153 		[0] = PWRSTS_ON,  /* MEMONSTATE */
154 	},
155 	.voltdm           = { .name = "core" },
156 };
157 
158 static struct powerdomain cam_pwrdm = {
159 	.name		  = "cam_pwrdm",
160 	.prcm_offs	  = OMAP3430_CAM_MOD,
161 	.pwrsts		  = PWRSTS_OFF_RET_ON,
162 	.pwrsts_logic_ret = PWRSTS_RET,
163 	.banks		  = 1,
164 	.pwrsts_mem_ret	  = {
165 		[0] = PWRSTS_RET, /* MEMRETSTATE */
166 	},
167 	.pwrsts_mem_on	  = {
168 		[0] = PWRSTS_ON,  /* MEMONSTATE */
169 	},
170 	.voltdm           = { .name = "core" },
171 };
172 
173 static struct powerdomain per_pwrdm = {
174 	.name		  = "per_pwrdm",
175 	.prcm_offs	  = OMAP3430_PER_MOD,
176 	.pwrsts		  = PWRSTS_OFF_RET_ON,
177 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
178 	.banks		  = 1,
179 	.pwrsts_mem_ret	  = {
180 		[0] = PWRSTS_RET, /* MEMRETSTATE */
181 	},
182 	.pwrsts_mem_on	  = {
183 		[0] = PWRSTS_ON,  /* MEMONSTATE */
184 	},
185 	.voltdm           = { .name = "core" },
186 };
187 
188 static struct powerdomain emu_pwrdm = {
189 	.name		= "emu_pwrdm",
190 	.prcm_offs	= OMAP3430_EMU_MOD,
191 	.voltdm           = { .name = "core" },
192 };
193 
194 static struct powerdomain neon_pwrdm = {
195 	.name		  = "neon_pwrdm",
196 	.prcm_offs	  = OMAP3430_NEON_MOD,
197 	.pwrsts		  = PWRSTS_OFF_RET_ON,
198 	.pwrsts_logic_ret = PWRSTS_RET,
199 	.voltdm           = { .name = "mpu_iva" },
200 };
201 
202 static struct powerdomain usbhost_pwrdm = {
203 	.name		  = "usbhost_pwrdm",
204 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
205 	.pwrsts		  = PWRSTS_OFF_RET_ON,
206 	.pwrsts_logic_ret = PWRSTS_RET,
207 	/*
208 	 * REVISIT: Enabling usb host save and restore mechanism seems to
209 	 * leave the usb host domain permanently in ACTIVE mode after
210 	 * changing the usb host power domain state from OFF to active once.
211 	 * Disabling for now.
212 	 */
213 	/*.flags	  = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
214 	.banks		  = 1,
215 	.pwrsts_mem_ret	  = {
216 		[0] = PWRSTS_RET, /* MEMRETSTATE */
217 	},
218 	.pwrsts_mem_on	  = {
219 		[0] = PWRSTS_ON,  /* MEMONSTATE */
220 	},
221 	.voltdm           = { .name = "core" },
222 };
223 
224 static struct powerdomain dpll1_pwrdm = {
225 	.name		= "dpll1_pwrdm",
226 	.prcm_offs	= MPU_MOD,
227 	.voltdm           = { .name = "mpu_iva" },
228 };
229 
230 static struct powerdomain dpll2_pwrdm = {
231 	.name		= "dpll2_pwrdm",
232 	.prcm_offs	= OMAP3430_IVA2_MOD,
233 	.voltdm           = { .name = "mpu_iva" },
234 };
235 
236 static struct powerdomain dpll3_pwrdm = {
237 	.name		= "dpll3_pwrdm",
238 	.prcm_offs	= PLL_MOD,
239 	.voltdm           = { .name = "core" },
240 };
241 
242 static struct powerdomain dpll4_pwrdm = {
243 	.name		= "dpll4_pwrdm",
244 	.prcm_offs	= PLL_MOD,
245 	.voltdm           = { .name = "core" },
246 };
247 
248 static struct powerdomain dpll5_pwrdm = {
249 	.name		= "dpll5_pwrdm",
250 	.prcm_offs	= PLL_MOD,
251 	.voltdm           = { .name = "core" },
252 };
253 
254 /* As powerdomains are added or removed above, this list must also be changed */
255 static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
256 	&wkup_omap2_pwrdm,
257 	&iva2_pwrdm,
258 	&mpu_3xxx_pwrdm,
259 	&neon_pwrdm,
260 	&cam_pwrdm,
261 	&dss_pwrdm,
262 	&per_pwrdm,
263 	&emu_pwrdm,
264 	&dpll1_pwrdm,
265 	&dpll2_pwrdm,
266 	&dpll3_pwrdm,
267 	&dpll4_pwrdm,
268 	NULL
269 };
270 
271 static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
272 	&gfx_omap2_pwrdm,
273 	&core_3xxx_pre_es3_1_pwrdm,
274 	NULL
275 };
276 
277 /* also includes 3630ES1.0 */
278 static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
279 	&core_3xxx_pre_es3_1_pwrdm,
280 	&sgx_pwrdm,
281 	&usbhost_pwrdm,
282 	&dpll5_pwrdm,
283 	NULL
284 };
285 
286 /* also includes 3630ES1.1+ */
287 static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
288 	&core_3xxx_es3_1_pwrdm,
289 	&sgx_pwrdm,
290 	&usbhost_pwrdm,
291 	&dpll5_pwrdm,
292 	NULL
293 };
294 
295 void __init omap3xxx_powerdomains_init(void)
296 {
297 	unsigned int rev;
298 
299 	if (!cpu_is_omap34xx())
300 		return;
301 
302 	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
303 	pwrdm_register_pwrdms(powerdomains_omap3430_common);
304 
305 	rev = omap_rev();
306 
307 	if (rev == OMAP3430_REV_ES1_0)
308 		pwrdm_register_pwrdms(powerdomains_omap3430es1);
309 	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
310 		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
311 		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
312 	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
313 		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
314 		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
315 		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
316 	else
317 		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
318 
319 	pwrdm_complete_init();
320 }
321