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 #include <linux/bug.h>
17 
18 #include <plat/cpu.h>
19 
20 #include "powerdomain.h"
21 #include "powerdomains2xxx_3xxx_data.h"
22 
23 #include "prcm-common.h"
24 #include "prm2xxx_3xxx.h"
25 #include "prm-regbits-34xx.h"
26 #include "cm2xxx_3xxx.h"
27 #include "cm-regbits-34xx.h"
28 
29 /*
30  * 34XX-specific powerdomains, dependencies
31  */
32 
33 /*
34  * Powerdomains
35  */
36 
37 static struct powerdomain iva2_pwrdm = {
38 	.name		  = "iva2_pwrdm",
39 	.prcm_offs	  = OMAP3430_IVA2_MOD,
40 	.pwrsts		  = PWRSTS_OFF_RET_ON,
41 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
42 	.banks		  = 4,
43 	.pwrsts_mem_ret	  = {
44 		[0] = PWRSTS_OFF_RET,
45 		[1] = PWRSTS_OFF_RET,
46 		[2] = PWRSTS_OFF_RET,
47 		[3] = PWRSTS_OFF_RET,
48 	},
49 	.pwrsts_mem_on	  = {
50 		[0] = PWRSTS_ON,
51 		[1] = PWRSTS_ON,
52 		[2] = PWRSTS_OFF_ON,
53 		[3] = PWRSTS_ON,
54 	},
55 	.voltdm           = { .name = "mpu_iva" },
56 };
57 
58 static struct powerdomain mpu_3xxx_pwrdm = {
59 	.name		  = "mpu_pwrdm",
60 	.prcm_offs	  = MPU_MOD,
61 	.pwrsts		  = PWRSTS_OFF_RET_ON,
62 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
63 	.flags		  = PWRDM_HAS_MPU_QUIRK,
64 	.banks		  = 1,
65 	.pwrsts_mem_ret	  = {
66 		[0] = PWRSTS_OFF_RET,
67 	},
68 	.pwrsts_mem_on	  = {
69 		[0] = PWRSTS_OFF_ON,
70 	},
71 	.voltdm           = { .name = "mpu_iva" },
72 };
73 
74 static struct powerdomain mpu_am35x_pwrdm = {
75 	.name		  = "mpu_pwrdm",
76 	.prcm_offs	  = MPU_MOD,
77 	.pwrsts		  = PWRSTS_ON,
78 	.pwrsts_logic_ret = PWRSTS_ON,
79 	.flags		  = PWRDM_HAS_MPU_QUIRK,
80 	.banks		  = 1,
81 	.pwrsts_mem_ret	  = {
82 		[0] = PWRSTS_ON,
83 	},
84 	.pwrsts_mem_on	  = {
85 		[0] = PWRSTS_ON,
86 	},
87 	.voltdm           = { .name = "mpu_iva" },
88 };
89 
90 /*
91  * The USBTLL Save-and-Restore mechanism is broken on
92  * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
93  * needs to be disabled on these chips.
94  * Refer: 3430 errata ID i459 and 3630 errata ID i579
95  *
96  * Note: setting the SAR flag could help for errata ID i478
97  *  which applies to 3430 <= ES3.1, but since the SAR feature
98  *  is broken, do not use it.
99  */
100 static struct powerdomain core_3xxx_pre_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 	.banks		  = 2,
106 	.pwrsts_mem_ret	  = {
107 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
108 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
109 	},
110 	.pwrsts_mem_on	  = {
111 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
112 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
113 	},
114 	.voltdm           = { .name = "core" },
115 };
116 
117 static struct powerdomain core_3xxx_es3_1_pwrdm = {
118 	.name		  = "core_pwrdm",
119 	.prcm_offs	  = CORE_MOD,
120 	.pwrsts		  = PWRSTS_OFF_RET_ON,
121 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
122 	/*
123 	 * Setting the SAR flag for errata ID i478 which applies
124 	 *  to 3430 <= ES3.1
125 	 */
126 	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
127 	.banks		  = 2,
128 	.pwrsts_mem_ret	  = {
129 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
130 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
131 	},
132 	.pwrsts_mem_on	  = {
133 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
134 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
135 	},
136 	.voltdm           = { .name = "core" },
137 };
138 
139 static struct powerdomain core_am35x_pwrdm = {
140 	.name		  = "core_pwrdm",
141 	.prcm_offs	  = CORE_MOD,
142 	.pwrsts		  = PWRSTS_ON,
143 	.pwrsts_logic_ret = PWRSTS_ON,
144 	.banks		  = 2,
145 	.pwrsts_mem_ret	  = {
146 		[0] = PWRSTS_ON,	 /* MEM1RETSTATE */
147 		[1] = PWRSTS_ON,	 /* MEM2RETSTATE */
148 	},
149 	.pwrsts_mem_on	  = {
150 		[0] = PWRSTS_ON, /* MEM1ONSTATE */
151 		[1] = PWRSTS_ON, /* MEM2ONSTATE */
152 	},
153 	.voltdm           = { .name = "core" },
154 };
155 
156 static struct powerdomain dss_pwrdm = {
157 	.name		  = "dss_pwrdm",
158 	.prcm_offs	  = OMAP3430_DSS_MOD,
159 	.pwrsts		  = PWRSTS_OFF_RET_ON,
160 	.pwrsts_logic_ret = PWRSTS_RET,
161 	.banks		  = 1,
162 	.pwrsts_mem_ret	  = {
163 		[0] = PWRSTS_RET, /* MEMRETSTATE */
164 	},
165 	.pwrsts_mem_on	  = {
166 		[0] = PWRSTS_ON,  /* MEMONSTATE */
167 	},
168 	.voltdm           = { .name = "core" },
169 };
170 
171 static struct powerdomain dss_am35x_pwrdm = {
172 	.name		  = "dss_pwrdm",
173 	.prcm_offs	  = OMAP3430_DSS_MOD,
174 	.pwrsts		  = PWRSTS_ON,
175 	.pwrsts_logic_ret = PWRSTS_ON,
176 	.banks		  = 1,
177 	.pwrsts_mem_ret	  = {
178 		[0] = PWRSTS_ON, /* MEMRETSTATE */
179 	},
180 	.pwrsts_mem_on	  = {
181 		[0] = PWRSTS_ON,  /* MEMONSTATE */
182 	},
183 	.voltdm           = { .name = "core" },
184 };
185 
186 /*
187  * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
188  * possible SGX powerstate, the SGX device itself does not support
189  * retention.
190  */
191 static struct powerdomain sgx_pwrdm = {
192 	.name		  = "sgx_pwrdm",
193 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
194 	/* XXX This is accurate for 3430 SGX, but what about GFX? */
195 	.pwrsts		  = PWRSTS_OFF_ON,
196 	.pwrsts_logic_ret = PWRSTS_RET,
197 	.banks		  = 1,
198 	.pwrsts_mem_ret	  = {
199 		[0] = PWRSTS_RET, /* MEMRETSTATE */
200 	},
201 	.pwrsts_mem_on	  = {
202 		[0] = PWRSTS_ON,  /* MEMONSTATE */
203 	},
204 	.voltdm           = { .name = "core" },
205 };
206 
207 static struct powerdomain sgx_am35x_pwrdm = {
208 	.name		  = "sgx_pwrdm",
209 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
210 	.pwrsts		  = PWRSTS_ON,
211 	.pwrsts_logic_ret = PWRSTS_ON,
212 	.banks		  = 1,
213 	.pwrsts_mem_ret	  = {
214 		[0] = PWRSTS_ON, /* MEMRETSTATE */
215 	},
216 	.pwrsts_mem_on	  = {
217 		[0] = PWRSTS_ON,  /* MEMONSTATE */
218 	},
219 	.voltdm           = { .name = "core" },
220 };
221 
222 static struct powerdomain cam_pwrdm = {
223 	.name		  = "cam_pwrdm",
224 	.prcm_offs	  = OMAP3430_CAM_MOD,
225 	.pwrsts		  = PWRSTS_OFF_RET_ON,
226 	.pwrsts_logic_ret = PWRSTS_RET,
227 	.banks		  = 1,
228 	.pwrsts_mem_ret	  = {
229 		[0] = PWRSTS_RET, /* MEMRETSTATE */
230 	},
231 	.pwrsts_mem_on	  = {
232 		[0] = PWRSTS_ON,  /* MEMONSTATE */
233 	},
234 	.voltdm           = { .name = "core" },
235 };
236 
237 static struct powerdomain per_pwrdm = {
238 	.name		  = "per_pwrdm",
239 	.prcm_offs	  = OMAP3430_PER_MOD,
240 	.pwrsts		  = PWRSTS_OFF_RET_ON,
241 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
242 	.banks		  = 1,
243 	.pwrsts_mem_ret	  = {
244 		[0] = PWRSTS_RET, /* MEMRETSTATE */
245 	},
246 	.pwrsts_mem_on	  = {
247 		[0] = PWRSTS_ON,  /* MEMONSTATE */
248 	},
249 	.voltdm           = { .name = "core" },
250 };
251 
252 static struct powerdomain per_am35x_pwrdm = {
253 	.name		  = "per_pwrdm",
254 	.prcm_offs	  = OMAP3430_PER_MOD,
255 	.pwrsts		  = PWRSTS_ON,
256 	.pwrsts_logic_ret = PWRSTS_ON,
257 	.banks		  = 1,
258 	.pwrsts_mem_ret	  = {
259 		[0] = PWRSTS_ON, /* MEMRETSTATE */
260 	},
261 	.pwrsts_mem_on	  = {
262 		[0] = PWRSTS_ON,  /* MEMONSTATE */
263 	},
264 	.voltdm           = { .name = "core" },
265 };
266 
267 static struct powerdomain emu_pwrdm = {
268 	.name		= "emu_pwrdm",
269 	.prcm_offs	= OMAP3430_EMU_MOD,
270 	.voltdm           = { .name = "core" },
271 };
272 
273 static struct powerdomain neon_pwrdm = {
274 	.name		  = "neon_pwrdm",
275 	.prcm_offs	  = OMAP3430_NEON_MOD,
276 	.pwrsts		  = PWRSTS_OFF_RET_ON,
277 	.pwrsts_logic_ret = PWRSTS_RET,
278 	.voltdm           = { .name = "mpu_iva" },
279 };
280 
281 static struct powerdomain neon_am35x_pwrdm = {
282 	.name		  = "neon_pwrdm",
283 	.prcm_offs	  = OMAP3430_NEON_MOD,
284 	.pwrsts		  = PWRSTS_ON,
285 	.pwrsts_logic_ret = PWRSTS_ON,
286 	.voltdm           = { .name = "mpu_iva" },
287 };
288 
289 static struct powerdomain usbhost_pwrdm = {
290 	.name		  = "usbhost_pwrdm",
291 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
292 	.pwrsts		  = PWRSTS_OFF_RET_ON,
293 	.pwrsts_logic_ret = PWRSTS_RET,
294 	/*
295 	 * REVISIT: Enabling usb host save and restore mechanism seems to
296 	 * leave the usb host domain permanently in ACTIVE mode after
297 	 * changing the usb host power domain state from OFF to active once.
298 	 * Disabling for now.
299 	 */
300 	/*.flags	  = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
301 	.banks		  = 1,
302 	.pwrsts_mem_ret	  = {
303 		[0] = PWRSTS_RET, /* MEMRETSTATE */
304 	},
305 	.pwrsts_mem_on	  = {
306 		[0] = PWRSTS_ON,  /* MEMONSTATE */
307 	},
308 	.voltdm           = { .name = "core" },
309 };
310 
311 static struct powerdomain dpll1_pwrdm = {
312 	.name		= "dpll1_pwrdm",
313 	.prcm_offs	= MPU_MOD,
314 	.voltdm           = { .name = "mpu_iva" },
315 };
316 
317 static struct powerdomain dpll2_pwrdm = {
318 	.name		= "dpll2_pwrdm",
319 	.prcm_offs	= OMAP3430_IVA2_MOD,
320 	.voltdm           = { .name = "mpu_iva" },
321 };
322 
323 static struct powerdomain dpll3_pwrdm = {
324 	.name		= "dpll3_pwrdm",
325 	.prcm_offs	= PLL_MOD,
326 	.voltdm           = { .name = "core" },
327 };
328 
329 static struct powerdomain dpll4_pwrdm = {
330 	.name		= "dpll4_pwrdm",
331 	.prcm_offs	= PLL_MOD,
332 	.voltdm           = { .name = "core" },
333 };
334 
335 static struct powerdomain dpll5_pwrdm = {
336 	.name		= "dpll5_pwrdm",
337 	.prcm_offs	= PLL_MOD,
338 	.voltdm           = { .name = "core" },
339 };
340 
341 /* As powerdomains are added or removed above, this list must also be changed */
342 static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
343 	&wkup_omap2_pwrdm,
344 	&iva2_pwrdm,
345 	&mpu_3xxx_pwrdm,
346 	&neon_pwrdm,
347 	&cam_pwrdm,
348 	&dss_pwrdm,
349 	&per_pwrdm,
350 	&emu_pwrdm,
351 	&dpll1_pwrdm,
352 	&dpll2_pwrdm,
353 	&dpll3_pwrdm,
354 	&dpll4_pwrdm,
355 	NULL
356 };
357 
358 static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
359 	&gfx_omap2_pwrdm,
360 	&core_3xxx_pre_es3_1_pwrdm,
361 	NULL
362 };
363 
364 /* also includes 3630ES1.0 */
365 static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
366 	&core_3xxx_pre_es3_1_pwrdm,
367 	&sgx_pwrdm,
368 	&usbhost_pwrdm,
369 	&dpll5_pwrdm,
370 	NULL
371 };
372 
373 /* also includes 3630ES1.1+ */
374 static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
375 	&core_3xxx_es3_1_pwrdm,
376 	&sgx_pwrdm,
377 	&usbhost_pwrdm,
378 	&dpll5_pwrdm,
379 	NULL
380 };
381 
382 static struct powerdomain *powerdomains_am35x[] __initdata = {
383 	&wkup_omap2_pwrdm,
384 	&mpu_am35x_pwrdm,
385 	&neon_am35x_pwrdm,
386 	&core_am35x_pwrdm,
387 	&sgx_am35x_pwrdm,
388 	&dss_am35x_pwrdm,
389 	&per_am35x_pwrdm,
390 	&emu_pwrdm,
391 	&dpll1_pwrdm,
392 	&dpll3_pwrdm,
393 	&dpll4_pwrdm,
394 	&dpll5_pwrdm,
395 	NULL
396 };
397 
398 void __init omap3xxx_powerdomains_init(void)
399 {
400 	unsigned int rev;
401 
402 	if (!cpu_is_omap34xx())
403 		return;
404 
405 	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
406 
407 	rev = omap_rev();
408 
409 	if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) {
410 		pwrdm_register_pwrdms(powerdomains_am35x);
411 	} else {
412 		pwrdm_register_pwrdms(powerdomains_omap3430_common);
413 
414 		switch (rev) {
415 		case OMAP3430_REV_ES1_0:
416 			pwrdm_register_pwrdms(powerdomains_omap3430es1);
417 			break;
418 		case OMAP3430_REV_ES2_0:
419 		case OMAP3430_REV_ES2_1:
420 		case OMAP3430_REV_ES3_0:
421 		case OMAP3630_REV_ES1_0:
422 			pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
423 			break;
424 		case OMAP3430_REV_ES3_1:
425 		case OMAP3430_REV_ES3_1_2:
426 		case OMAP3630_REV_ES1_1:
427 		case OMAP3630_REV_ES1_2:
428 			pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
429 			break;
430 		default:
431 			WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
432 		}
433 	}
434 
435 	pwrdm_complete_init();
436 }
437