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