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 == AM35XX_REV_ES1_0 || rev == AM35XX_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