diff options
| -rw-r--r-- | arch/arm/mach-omap2/pm44xx.c | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 5ba6d888d6ff..228deca8fb93 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * OMAP4 Power Management Routines | 2 | * OMAP4+ Power Management Routines |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2010-2011 Texas Instruments, Inc. | 4 | * Copyright (C) 2010-2013 Texas Instruments, Inc. |
| 5 | * Rajendra Nayak <rnayak@ti.com> | 5 | * Rajendra Nayak <rnayak@ti.com> |
| 6 | * Santosh Shilimkar <santosh.shilimkar@ti.com> | 6 | * Santosh Shilimkar <santosh.shilimkar@ti.com> |
| 7 | * | 7 | * |
| @@ -135,16 +135,16 @@ static void omap_default_idle(void) | |||
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | /** | 137 | /** |
| 138 | * omap4_pm_init - Init routine for OMAP4 PM | 138 | * omap4_init_static_deps - Add OMAP4 static dependencies |
| 139 | * | 139 | * |
| 140 | * Initializes all powerdomain and clockdomain target states | 140 | * Add needed static clockdomain dependencies on OMAP4 devices. |
| 141 | * and all PRCM settings. | 141 | * Return: 0 on success or 'err' on failures |
| 142 | */ | 142 | */ |
| 143 | int __init omap4_pm_init(void) | 143 | static inline int omap4_init_static_deps(void) |
| 144 | { | 144 | { |
| 145 | int ret; | ||
| 146 | struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; | 145 | struct clockdomain *emif_clkdm, *mpuss_clkdm, *l3_1_clkdm; |
| 147 | struct clockdomain *ducati_clkdm, *l3_2_clkdm; | 146 | struct clockdomain *ducati_clkdm, *l3_2_clkdm; |
| 147 | int ret = 0; | ||
| 148 | 148 | ||
| 149 | if (omap_rev() == OMAP4430_REV_ES1_0) { | 149 | if (omap_rev() == OMAP4430_REV_ES1_0) { |
| 150 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); | 150 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); |
| @@ -163,7 +163,7 @@ int __init omap4_pm_init(void) | |||
| 163 | ret = pwrdm_for_each(pwrdms_setup, NULL); | 163 | ret = pwrdm_for_each(pwrdms_setup, NULL); |
| 164 | if (ret) { | 164 | if (ret) { |
| 165 | pr_err("Failed to setup powerdomains\n"); | 165 | pr_err("Failed to setup powerdomains\n"); |
| 166 | goto err2; | 166 | return ret; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | /* | 169 | /* |
| @@ -171,6 +171,10 @@ int __init omap4_pm_init(void) | |||
| 171 | * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as | 171 | * MPUSS -> L4_PER/L3_* and DUCATI -> L3_* doesn't work as |
| 172 | * expected. The hardware recommendation is to enable static | 172 | * expected. The hardware recommendation is to enable static |
| 173 | * dependencies for these to avoid system lock ups or random crashes. | 173 | * dependencies for these to avoid system lock ups or random crashes. |
| 174 | * The L4 wakeup depedency is added to workaround the OCP sync hardware | ||
| 175 | * BUG with 32K synctimer which lead to incorrect timer value read | ||
| 176 | * from the 32K counter. The BUG applies for GPTIMER1 and WDT2 which | ||
| 177 | * are part of L4 wakeup clockdomain. | ||
| 174 | */ | 178 | */ |
| 175 | mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); | 179 | mpuss_clkdm = clkdm_lookup("mpuss_clkdm"); |
| 176 | emif_clkdm = clkdm_lookup("l3_emif_clkdm"); | 180 | emif_clkdm = clkdm_lookup("l3_emif_clkdm"); |
| @@ -179,7 +183,7 @@ int __init omap4_pm_init(void) | |||
| 179 | ducati_clkdm = clkdm_lookup("ducati_clkdm"); | 183 | ducati_clkdm = clkdm_lookup("ducati_clkdm"); |
| 180 | if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || | 184 | if ((!mpuss_clkdm) || (!emif_clkdm) || (!l3_1_clkdm) || |
| 181 | (!l3_2_clkdm) || (!ducati_clkdm)) | 185 | (!l3_2_clkdm) || (!ducati_clkdm)) |
| 182 | goto err2; | 186 | return -EINVAL; |
| 183 | 187 | ||
| 184 | ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); | 188 | ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm); |
| 185 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); | 189 | ret |= clkdm_add_wkdep(mpuss_clkdm, l3_1_clkdm); |
| @@ -188,9 +192,42 @@ int __init omap4_pm_init(void) | |||
| 188 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); | 192 | ret |= clkdm_add_wkdep(ducati_clkdm, l3_2_clkdm); |
| 189 | if (ret) { | 193 | if (ret) { |
| 190 | pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); | 194 | pr_err("Failed to add MPUSS -> L3/EMIF/L4PER, DUCATI -> L3 wakeup dependency\n"); |
| 195 | return -EINVAL; | ||
| 196 | } | ||
| 197 | |||
| 198 | return ret; | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 202 | * omap4_pm_init - Init routine for OMAP4+ devices | ||
| 203 | * | ||
| 204 | * Initializes all powerdomain and clockdomain target states | ||
| 205 | * and all PRCM settings. | ||
| 206 | * Return: Returns the error code returned by called functions. | ||
| 207 | */ | ||
| 208 | int __init omap4_pm_init(void) | ||
| 209 | { | ||
| 210 | int ret = 0; | ||
| 211 | |||
| 212 | if (omap_rev() == OMAP4430_REV_ES1_0) { | ||
| 213 | WARN(1, "Power Management not supported on OMAP4430 ES1.0\n"); | ||
| 214 | return -ENODEV; | ||
| 215 | } | ||
| 216 | |||
| 217 | pr_info("Power Management for TI OMAP4+ devices.\n"); | ||
| 218 | |||
| 219 | ret = pwrdm_for_each(pwrdms_setup, NULL); | ||
| 220 | if (ret) { | ||
| 221 | pr_err("Failed to setup powerdomains.\n"); | ||
| 191 | goto err2; | 222 | goto err2; |
| 192 | } | 223 | } |
| 193 | 224 | ||
| 225 | if (cpu_is_omap44xx()) { | ||
| 226 | ret = omap4_init_static_deps(); | ||
| 227 | if (ret) | ||
| 228 | goto err2; | ||
| 229 | } | ||
| 230 | |||
| 194 | ret = omap4_mpuss_init(); | 231 | ret = omap4_mpuss_init(); |
| 195 | if (ret) { | 232 | if (ret) { |
| 196 | pr_err("Failed to initialise OMAP4 MPUSS\n"); | 233 | pr_err("Failed to initialise OMAP4 MPUSS\n"); |
| @@ -206,7 +243,8 @@ int __init omap4_pm_init(void) | |||
| 206 | /* Overwrite the default cpu_do_idle() */ | 243 | /* Overwrite the default cpu_do_idle() */ |
| 207 | arm_pm_idle = omap_default_idle; | 244 | arm_pm_idle = omap_default_idle; |
| 208 | 245 | ||
| 209 | omap4_idle_init(); | 246 | if (cpu_is_omap44xx()) |
| 247 | omap4_idle_init(); | ||
| 210 | 248 | ||
| 211 | err2: | 249 | err2: |
| 212 | return ret; | 250 | return ret; |
