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