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 /*
75  * The USBTLL Save-and-Restore mechanism is broken on
76  * 3430s up to ES3.0 and 3630ES1.0. Hence this feature
77  * needs to be disabled on these chips.
78  * Refer: 3430 errata ID i459 and 3630 errata ID i579
79  *
80  * Note: setting the SAR flag could help for errata ID i478
81  *  which applies to 3430 <= ES3.1, but since the SAR feature
82  *  is broken, do not use it.
83  */
84 static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
85 	.name		  = "core_pwrdm",
86 	.prcm_offs	  = CORE_MOD,
87 	.pwrsts		  = PWRSTS_OFF_RET_ON,
88 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
89 	.banks		  = 2,
90 	.pwrsts_mem_ret	  = {
91 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
92 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
93 	},
94 	.pwrsts_mem_on	  = {
95 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
96 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
97 	},
98 	.voltdm           = { .name = "core" },
99 };
100 
101 static struct powerdomain core_3xxx_es3_1_pwrdm = {
102 	.name		  = "core_pwrdm",
103 	.prcm_offs	  = CORE_MOD,
104 	.pwrsts		  = PWRSTS_OFF_RET_ON,
105 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
106 	/*
107 	 * Setting the SAR flag for errata ID i478 which applies
108 	 *  to 3430 <= ES3.1
109 	 */
110 	.flags		  = PWRDM_HAS_HDWR_SAR, /* for USBTLL only */
111 	.banks		  = 2,
112 	.pwrsts_mem_ret	  = {
113 		[0] = PWRSTS_OFF_RET,	 /* MEM1RETSTATE */
114 		[1] = PWRSTS_OFF_RET,	 /* MEM2RETSTATE */
115 	},
116 	.pwrsts_mem_on	  = {
117 		[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
118 		[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
119 	},
120 	.voltdm           = { .name = "core" },
121 };
122 
123 static struct powerdomain dss_pwrdm = {
124 	.name		  = "dss_pwrdm",
125 	.prcm_offs	  = OMAP3430_DSS_MOD,
126 	.pwrsts		  = PWRSTS_OFF_RET_ON,
127 	.pwrsts_logic_ret = PWRSTS_RET,
128 	.banks		  = 1,
129 	.pwrsts_mem_ret	  = {
130 		[0] = PWRSTS_RET, /* MEMRETSTATE */
131 	},
132 	.pwrsts_mem_on	  = {
133 		[0] = PWRSTS_ON,  /* MEMONSTATE */
134 	},
135 	.voltdm           = { .name = "core" },
136 };
137 
138 /*
139  * Although the 34XX TRM Rev K Table 4-371 notes that retention is a
140  * possible SGX powerstate, the SGX device itself does not support
141  * retention.
142  */
143 static struct powerdomain sgx_pwrdm = {
144 	.name		  = "sgx_pwrdm",
145 	.prcm_offs	  = OMAP3430ES2_SGX_MOD,
146 	/* XXX This is accurate for 3430 SGX, but what about GFX? */
147 	.pwrsts		  = PWRSTS_OFF_ON,
148 	.pwrsts_logic_ret = PWRSTS_RET,
149 	.banks		  = 1,
150 	.pwrsts_mem_ret	  = {
151 		[0] = PWRSTS_RET, /* MEMRETSTATE */
152 	},
153 	.pwrsts_mem_on	  = {
154 		[0] = PWRSTS_ON,  /* MEMONSTATE */
155 	},
156 	.voltdm           = { .name = "core" },
157 };
158 
159 static struct powerdomain cam_pwrdm = {
160 	.name		  = "cam_pwrdm",
161 	.prcm_offs	  = OMAP3430_CAM_MOD,
162 	.pwrsts		  = PWRSTS_OFF_RET_ON,
163 	.pwrsts_logic_ret = PWRSTS_RET,
164 	.banks		  = 1,
165 	.pwrsts_mem_ret	  = {
166 		[0] = PWRSTS_RET, /* MEMRETSTATE */
167 	},
168 	.pwrsts_mem_on	  = {
169 		[0] = PWRSTS_ON,  /* MEMONSTATE */
170 	},
171 	.voltdm           = { .name = "core" },
172 };
173 
174 static struct powerdomain per_pwrdm = {
175 	.name		  = "per_pwrdm",
176 	.prcm_offs	  = OMAP3430_PER_MOD,
177 	.pwrsts		  = PWRSTS_OFF_RET_ON,
178 	.pwrsts_logic_ret = PWRSTS_OFF_RET,
179 	.banks		  = 1,
180 	.pwrsts_mem_ret	  = {
181 		[0] = PWRSTS_RET, /* MEMRETSTATE */
182 	},
183 	.pwrsts_mem_on	  = {
184 		[0] = PWRSTS_ON,  /* MEMONSTATE */
185 	},
186 	.voltdm           = { .name = "core" },
187 };
188 
189 static struct powerdomain emu_pwrdm = {
190 	.name		= "emu_pwrdm",
191 	.prcm_offs	= OMAP3430_EMU_MOD,
192 	.voltdm           = { .name = "core" },
193 };
194 
195 static struct powerdomain neon_pwrdm = {
196 	.name		  = "neon_pwrdm",
197 	.prcm_offs	  = OMAP3430_NEON_MOD,
198 	.pwrsts		  = PWRSTS_OFF_RET_ON,
199 	.pwrsts_logic_ret = PWRSTS_RET,
200 	.voltdm           = { .name = "mpu_iva" },
201 };
202 
203 static struct powerdomain usbhost_pwrdm = {
204 	.name		  = "usbhost_pwrdm",
205 	.prcm_offs	  = OMAP3430ES2_USBHOST_MOD,
206 	.pwrsts		  = PWRSTS_OFF_RET_ON,
207 	.pwrsts_logic_ret = PWRSTS_RET,
208 	/*
209 	 * REVISIT: Enabling usb host save and restore mechanism seems to
210 	 * leave the usb host domain permanently in ACTIVE mode after
211 	 * changing the usb host power domain state from OFF to active once.
212 	 * Disabling for now.
213 	 */
214 	/*.flags	  = PWRDM_HAS_HDWR_SAR,*/ /* for USBHOST ctrlr only */
215 	.banks		  = 1,
216 	.pwrsts_mem_ret	  = {
217 		[0] = PWRSTS_RET, /* MEMRETSTATE */
218 	},
219 	.pwrsts_mem_on	  = {
220 		[0] = PWRSTS_ON,  /* MEMONSTATE */
221 	},
222 	.voltdm           = { .name = "core" },
223 };
224 
225 static struct powerdomain dpll1_pwrdm = {
226 	.name		= "dpll1_pwrdm",
227 	.prcm_offs	= MPU_MOD,
228 	.voltdm           = { .name = "mpu_iva" },
229 };
230 
231 static struct powerdomain dpll2_pwrdm = {
232 	.name		= "dpll2_pwrdm",
233 	.prcm_offs	= OMAP3430_IVA2_MOD,
234 	.voltdm           = { .name = "mpu_iva" },
235 };
236 
237 static struct powerdomain dpll3_pwrdm = {
238 	.name		= "dpll3_pwrdm",
239 	.prcm_offs	= PLL_MOD,
240 	.voltdm           = { .name = "core" },
241 };
242 
243 static struct powerdomain dpll4_pwrdm = {
244 	.name		= "dpll4_pwrdm",
245 	.prcm_offs	= PLL_MOD,
246 	.voltdm           = { .name = "core" },
247 };
248 
249 static struct powerdomain dpll5_pwrdm = {
250 	.name		= "dpll5_pwrdm",
251 	.prcm_offs	= PLL_MOD,
252 	.voltdm           = { .name = "core" },
253 };
254 
255 /* As powerdomains are added or removed above, this list must also be changed */
256 static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
257 	&wkup_omap2_pwrdm,
258 	&iva2_pwrdm,
259 	&mpu_3xxx_pwrdm,
260 	&neon_pwrdm,
261 	&cam_pwrdm,
262 	&dss_pwrdm,
263 	&per_pwrdm,
264 	&emu_pwrdm,
265 	&dpll1_pwrdm,
266 	&dpll2_pwrdm,
267 	&dpll3_pwrdm,
268 	&dpll4_pwrdm,
269 	NULL
270 };
271 
272 static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
273 	&gfx_omap2_pwrdm,
274 	&core_3xxx_pre_es3_1_pwrdm,
275 	NULL
276 };
277 
278 /* also includes 3630ES1.0 */
279 static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
280 	&core_3xxx_pre_es3_1_pwrdm,
281 	&sgx_pwrdm,
282 	&usbhost_pwrdm,
283 	&dpll5_pwrdm,
284 	NULL
285 };
286 
287 /* also includes 3630ES1.1+ */
288 static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
289 	&core_3xxx_es3_1_pwrdm,
290 	&sgx_pwrdm,
291 	&usbhost_pwrdm,
292 	&dpll5_pwrdm,
293 	NULL
294 };
295 
296 void __init omap3xxx_powerdomains_init(void)
297 {
298 	unsigned int rev;
299 
300 	if (!cpu_is_omap34xx())
301 		return;
302 
303 	pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
304 	pwrdm_register_pwrdms(powerdomains_omap3430_common);
305 
306 	rev = omap_rev();
307 
308 	if (rev == OMAP3430_REV_ES1_0)
309 		pwrdm_register_pwrdms(powerdomains_omap3430es1);
310 	else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
311 		 rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
312 		pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
313 	else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
314 		 rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
315 		 rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
316 		pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
317 	else
318 		WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
319 
320 	pwrdm_complete_init();
321 }
322