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 35static 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 56static 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 72static 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 */ 98static 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 115static 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 137static 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 154static 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 169static 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 */ 189static 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 205static 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 220static 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 235static 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 250static 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 265static struct powerdomain emu_pwrdm = { 266 .name = "emu_pwrdm", 267 .prcm_offs = OMAP3430_EMU_MOD, 268 .voltdm = { .name = "core" }, 269}; 270 271static 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 279static 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 287static 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 309static struct powerdomain dpll1_pwrdm = { 310 .name = "dpll1_pwrdm", 311 .prcm_offs = MPU_MOD, 312 .voltdm = { .name = "mpu_iva" }, 313}; 314 315static struct powerdomain dpll2_pwrdm = { 316 .name = "dpll2_pwrdm", 317 .prcm_offs = OMAP3430_IVA2_MOD, 318 .voltdm = { .name = "mpu_iva" }, 319}; 320 321static struct powerdomain dpll3_pwrdm = { 322 .name = "dpll3_pwrdm", 323 .prcm_offs = PLL_MOD, 324 .voltdm = { .name = "core" }, 325}; 326 327static struct powerdomain dpll4_pwrdm = { 328 .name = "dpll4_pwrdm", 329 .prcm_offs = PLL_MOD, 330 .voltdm = { .name = "core" }, 331}; 332 333static struct powerdomain dpll5_pwrdm = { 334 .name = "dpll5_pwrdm", 335 .prcm_offs = PLL_MOD, 336 .voltdm = { .name = "core" }, 337}; 338 339static struct powerdomain alwon_81xx_pwrdm = { 340 .name = "alwon_pwrdm", 341 .prcm_offs = TI81XX_PRM_ALWON_MOD, 342 .pwrsts = PWRSTS_OFF_ON, 343 .voltdm = { .name = "core" }, 344}; 345 346static struct powerdomain device_81xx_pwrdm = { 347 .name = "device_pwrdm", 348 .prcm_offs = TI81XX_PRM_DEVICE_MOD, 349 .voltdm = { .name = "core" }, 350}; 351 352static struct powerdomain active_816x_pwrdm = { 353 .name = "active_pwrdm", 354 .prcm_offs = TI816X_PRM_ACTIVE_MOD, 355 .pwrsts = PWRSTS_OFF_ON, 356 .voltdm = { .name = "core" }, 357}; 358 359static struct powerdomain default_816x_pwrdm = { 360 .name = "default_pwrdm", 361 .prcm_offs = TI81XX_PRM_DEFAULT_MOD, 362 .pwrsts = PWRSTS_OFF_ON, 363 .voltdm = { .name = "core" }, 364}; 365 366static struct powerdomain ivahd0_816x_pwrdm = { 367 .name = "ivahd0_pwrdm", 368 .prcm_offs = TI816X_PRM_IVAHD0_MOD, 369 .pwrsts = PWRSTS_OFF_ON, 370 .voltdm = { .name = "mpu_iva" }, 371}; 372 373static struct powerdomain ivahd1_816x_pwrdm = { 374 .name = "ivahd1_pwrdm", 375 .prcm_offs = TI816X_PRM_IVAHD1_MOD, 376 .pwrsts = PWRSTS_OFF_ON, 377 .voltdm = { .name = "mpu_iva" }, 378}; 379 380static struct powerdomain ivahd2_816x_pwrdm = { 381 .name = "ivahd2_pwrdm", 382 .prcm_offs = TI816X_PRM_IVAHD2_MOD, 383 .pwrsts = PWRSTS_OFF_ON, 384 .voltdm = { .name = "mpu_iva" }, 385}; 386 387static struct powerdomain sgx_816x_pwrdm = { 388 .name = "sgx_pwrdm", 389 .prcm_offs = TI816X_PRM_SGX_MOD, 390 .pwrsts = PWRSTS_OFF_ON, 391 .voltdm = { .name = "core" }, 392}; 393 394/* As powerdomains are added or removed above, this list must also be changed */ 395static struct powerdomain *powerdomains_omap3430_common[] __initdata = { 396 &wkup_omap2_pwrdm, 397 &iva2_pwrdm, 398 &mpu_3xxx_pwrdm, 399 &neon_pwrdm, 400 &cam_pwrdm, 401 &dss_pwrdm, 402 &per_pwrdm, 403 &emu_pwrdm, 404 &dpll1_pwrdm, 405 &dpll2_pwrdm, 406 &dpll3_pwrdm, 407 &dpll4_pwrdm, 408 NULL 409}; 410 411static struct powerdomain *powerdomains_omap3430es1[] __initdata = { 412 &gfx_omap2_pwrdm, 413 &core_3xxx_pre_es3_1_pwrdm, 414 NULL 415}; 416 417/* also includes 3630ES1.0 */ 418static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = { 419 &core_3xxx_pre_es3_1_pwrdm, 420 &sgx_pwrdm, 421 &usbhost_pwrdm, 422 &dpll5_pwrdm, 423 NULL 424}; 425 426/* also includes 3630ES1.1+ */ 427static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = { 428 &core_3xxx_es3_1_pwrdm, 429 &sgx_pwrdm, 430 &usbhost_pwrdm, 431 &dpll5_pwrdm, 432 NULL 433}; 434 435static struct powerdomain *powerdomains_am35x[] __initdata = { 436 &wkup_omap2_pwrdm, 437 &mpu_am35x_pwrdm, 438 &neon_am35x_pwrdm, 439 &core_am35x_pwrdm, 440 &sgx_am35x_pwrdm, 441 &dss_am35x_pwrdm, 442 &per_am35x_pwrdm, 443 &emu_pwrdm, 444 &dpll1_pwrdm, 445 &dpll3_pwrdm, 446 &dpll4_pwrdm, 447 &dpll5_pwrdm, 448 NULL 449}; 450 451static struct powerdomain *powerdomains_ti81xx[] __initdata = { 452 &alwon_81xx_pwrdm, 453 &device_81xx_pwrdm, 454 &active_816x_pwrdm, 455 &default_816x_pwrdm, 456 &ivahd0_816x_pwrdm, 457 &ivahd1_816x_pwrdm, 458 &ivahd2_816x_pwrdm, 459 &sgx_816x_pwrdm, 460 NULL 461}; 462 463void __init omap3xxx_powerdomains_init(void) 464{ 465 unsigned int rev; 466 467 if (!cpu_is_omap34xx() && !cpu_is_ti81xx()) 468 return; 469 470 pwrdm_register_platform_funcs(&omap3_pwrdm_operations); 471 472 rev = omap_rev(); 473 474 if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { 475 pwrdm_register_pwrdms(powerdomains_am35x); 476 } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1 477 || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) { 478 pwrdm_register_pwrdms(powerdomains_ti81xx); 479 } else { 480 pwrdm_register_pwrdms(powerdomains_omap3430_common); 481 482 switch (rev) { 483 case OMAP3430_REV_ES1_0: 484 pwrdm_register_pwrdms(powerdomains_omap3430es1); 485 break; 486 case OMAP3430_REV_ES2_0: 487 case OMAP3430_REV_ES2_1: 488 case OMAP3430_REV_ES3_0: 489 case OMAP3630_REV_ES1_0: 490 pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0); 491 break; 492 case OMAP3430_REV_ES3_1: 493 case OMAP3430_REV_ES3_1_2: 494 case OMAP3630_REV_ES1_1: 495 case OMAP3630_REV_ES1_2: 496 pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus); 497 break; 498 default: 499 WARN(1, "OMAP3 powerdomain init: unknown chip type\n"); 500 } 501 } 502 503 pwrdm_complete_init(); 504} 505