diff options
author | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-05-09 11:08:35 -0400 |
---|---|---|
committer | Santosh Shilimkar <santosh.shilimkar@ti.com> | 2012-07-09 09:44:39 -0400 |
commit | 247c445c0fbd52c77e497ff5bfcf0dceb8afea8d (patch) | |
tree | 3334a9cd1b573fa5d447cf0876e8904d21aef105 /arch/arm/mach-omap2/omap-wakeupgen.c | |
parent | e17933c2c0173ec19aa2450e4be79b7adfd52224 (diff) |
ARM: OMAP5: Add the WakeupGen IP updates
OMAP4 and OMAP5 share same WakeupGen IP with below few udpates on OMAP5.
- Additional 32 interrupt support is added w.r.t OMAP4 design.
- The AUX CORE boot registers are now made accessible from non-secure SW.
- SAR offset are changed and PTMSYNC* registers are removed from SAR.
Patch updates the WakeupGen code accordingly.
Signed-off-by: R Sricharan <r.sricharan@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/omap-wakeupgen.c')
-rw-r--r-- | arch/arm/mach-omap2/omap-wakeupgen.c | 114 |
1 files changed, 89 insertions, 25 deletions
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index d811c7790350..05fdebfaa195 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -33,18 +33,23 @@ | |||
33 | #include "omap4-sar-layout.h" | 33 | #include "omap4-sar-layout.h" |
34 | #include "common.h" | 34 | #include "common.h" |
35 | 35 | ||
36 | #define NR_REG_BANKS 4 | 36 | #define MAX_NR_REG_BANKS 5 |
37 | #define MAX_IRQS 128 | 37 | #define MAX_IRQS 160 |
38 | #define WKG_MASK_ALL 0x00000000 | 38 | #define WKG_MASK_ALL 0x00000000 |
39 | #define WKG_UNMASK_ALL 0xffffffff | 39 | #define WKG_UNMASK_ALL 0xffffffff |
40 | #define CPU_ENA_OFFSET 0x400 | 40 | #define CPU_ENA_OFFSET 0x400 |
41 | #define CPU0_ID 0x0 | 41 | #define CPU0_ID 0x0 |
42 | #define CPU1_ID 0x1 | 42 | #define CPU1_ID 0x1 |
43 | #define OMAP4_NR_BANKS 4 | ||
44 | #define OMAP4_NR_IRQS 128 | ||
43 | 45 | ||
44 | static void __iomem *wakeupgen_base; | 46 | static void __iomem *wakeupgen_base; |
45 | static void __iomem *sar_base; | 47 | static void __iomem *sar_base; |
46 | static DEFINE_SPINLOCK(wakeupgen_lock); | 48 | static DEFINE_SPINLOCK(wakeupgen_lock); |
47 | static unsigned int irq_target_cpu[NR_IRQS]; | 49 | static unsigned int irq_target_cpu[NR_IRQS]; |
50 | static unsigned int irq_banks = MAX_NR_REG_BANKS; | ||
51 | static unsigned int max_irqs = MAX_IRQS; | ||
52 | static unsigned int omap_secure_apis; | ||
48 | 53 | ||
49 | /* | 54 | /* |
50 | * Static helper functions. | 55 | * Static helper functions. |
@@ -146,13 +151,13 @@ static void wakeupgen_unmask(struct irq_data *d) | |||
146 | } | 151 | } |
147 | 152 | ||
148 | #ifdef CONFIG_HOTPLUG_CPU | 153 | #ifdef CONFIG_HOTPLUG_CPU |
149 | static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); | 154 | static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks); |
150 | 155 | ||
151 | static void _wakeupgen_save_masks(unsigned int cpu) | 156 | static void _wakeupgen_save_masks(unsigned int cpu) |
152 | { | 157 | { |
153 | u8 i; | 158 | u8 i; |
154 | 159 | ||
155 | for (i = 0; i < NR_REG_BANKS; i++) | 160 | for (i = 0; i < irq_banks; i++) |
156 | per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); | 161 | per_cpu(irqmasks, cpu)[i] = wakeupgen_readl(i, cpu); |
157 | } | 162 | } |
158 | 163 | ||
@@ -160,7 +165,7 @@ static void _wakeupgen_restore_masks(unsigned int cpu) | |||
160 | { | 165 | { |
161 | u8 i; | 166 | u8 i; |
162 | 167 | ||
163 | for (i = 0; i < NR_REG_BANKS; i++) | 168 | for (i = 0; i < irq_banks; i++) |
164 | wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); | 169 | wakeupgen_writel(per_cpu(irqmasks, cpu)[i], i, cpu); |
165 | } | 170 | } |
166 | 171 | ||
@@ -168,7 +173,7 @@ static void _wakeupgen_set_all(unsigned int cpu, unsigned int reg) | |||
168 | { | 173 | { |
169 | u8 i; | 174 | u8 i; |
170 | 175 | ||
171 | for (i = 0; i < NR_REG_BANKS; i++) | 176 | for (i = 0; i < irq_banks; i++) |
172 | wakeupgen_writel(reg, i, cpu); | 177 | wakeupgen_writel(reg, i, cpu); |
173 | } | 178 | } |
174 | 179 | ||
@@ -196,25 +201,14 @@ static void wakeupgen_irqmask_all(unsigned int cpu, unsigned int set) | |||
196 | #endif | 201 | #endif |
197 | 202 | ||
198 | #ifdef CONFIG_CPU_PM | 203 | #ifdef CONFIG_CPU_PM |
199 | /* | 204 | static inline void omap4_irq_save_context(void) |
200 | * Save WakeupGen interrupt context in SAR BANK3. Restore is done by | ||
201 | * ROM code. WakeupGen IP is integrated along with GIC to manage the | ||
202 | * interrupt wakeups from CPU low power states. It manages | ||
203 | * masking/unmasking of Shared peripheral interrupts(SPI). So the | ||
204 | * interrupt enable/disable control should be in sync and consistent | ||
205 | * at WakeupGen and GIC so that interrupts are not lost. | ||
206 | */ | ||
207 | static void irq_save_context(void) | ||
208 | { | 205 | { |
209 | u32 i, val; | 206 | u32 i, val; |
210 | 207 | ||
211 | if (omap_rev() == OMAP4430_REV_ES1_0) | 208 | if (omap_rev() == OMAP4430_REV_ES1_0) |
212 | return; | 209 | return; |
213 | 210 | ||
214 | if (!sar_base) | 211 | for (i = 0; i < irq_banks; i++) { |
215 | sar_base = omap4_get_sar_ram_base(); | ||
216 | |||
217 | for (i = 0; i < NR_REG_BANKS; i++) { | ||
218 | /* Save the CPUx interrupt mask for IRQ 0 to 127 */ | 212 | /* Save the CPUx interrupt mask for IRQ 0 to 127 */ |
219 | val = wakeupgen_readl(i, 0); | 213 | val = wakeupgen_readl(i, 0); |
220 | sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); | 214 | sar_writel(val, WAKEUPGENENB_OFFSET_CPU0, i); |
@@ -254,6 +248,53 @@ static void irq_save_context(void) | |||
254 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); | 248 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); |
255 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; | 249 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; |
256 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); | 250 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); |
251 | |||
252 | } | ||
253 | |||
254 | static inline void omap5_irq_save_context(void) | ||
255 | { | ||
256 | u32 i, val; | ||
257 | |||
258 | for (i = 0; i < irq_banks; i++) { | ||
259 | /* Save the CPUx interrupt mask for IRQ 0 to 159 */ | ||
260 | val = wakeupgen_readl(i, 0); | ||
261 | sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU0, i); | ||
262 | val = wakeupgen_readl(i, 1); | ||
263 | sar_writel(val, OMAP5_WAKEUPGENENB_OFFSET_CPU1, i); | ||
264 | sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0, i); | ||
265 | sar_writel(0x0, OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1, i); | ||
266 | } | ||
267 | |||
268 | /* Save AuxBoot* registers */ | ||
269 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
270 | __raw_writel(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); | ||
271 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | ||
272 | __raw_writel(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); | ||
273 | |||
274 | /* Set the Backup Bit Mask status */ | ||
275 | val = __raw_readl(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); | ||
276 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; | ||
277 | __raw_writel(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); | ||
278 | |||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Save WakeupGen interrupt context in SAR BANK3. Restore is done by | ||
283 | * ROM code. WakeupGen IP is integrated along with GIC to manage the | ||
284 | * interrupt wakeups from CPU low power states. It manages | ||
285 | * masking/unmasking of Shared peripheral interrupts(SPI). So the | ||
286 | * interrupt enable/disable control should be in sync and consistent | ||
287 | * at WakeupGen and GIC so that interrupts are not lost. | ||
288 | */ | ||
289 | static void irq_save_context(void) | ||
290 | { | ||
291 | if (!sar_base) | ||
292 | sar_base = omap4_get_sar_ram_base(); | ||
293 | |||
294 | if (soc_is_omap54xx()) | ||
295 | omap5_irq_save_context(); | ||
296 | else | ||
297 | omap4_irq_save_context(); | ||
257 | } | 298 | } |
258 | 299 | ||
259 | /* | 300 | /* |
@@ -262,9 +303,14 @@ static void irq_save_context(void) | |||
262 | static void irq_sar_clear(void) | 303 | static void irq_sar_clear(void) |
263 | { | 304 | { |
264 | u32 val; | 305 | u32 val; |
265 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); | 306 | u32 offset = SAR_BACKUP_STATUS_OFFSET; |
307 | |||
308 | if (soc_is_omap54xx()) | ||
309 | offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; | ||
310 | |||
311 | val = __raw_readl(sar_base + offset); | ||
266 | val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; | 312 | val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; |
267 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); | 313 | __raw_writel(val, sar_base + offset); |
268 | } | 314 | } |
269 | 315 | ||
270 | /* | 316 | /* |
@@ -336,13 +382,25 @@ static struct notifier_block irq_notifier_block = { | |||
336 | 382 | ||
337 | static void __init irq_pm_init(void) | 383 | static void __init irq_pm_init(void) |
338 | { | 384 | { |
339 | cpu_pm_register_notifier(&irq_notifier_block); | 385 | /* FIXME: Remove this when MPU OSWR support is added */ |
386 | if (!soc_is_omap54xx()) | ||
387 | cpu_pm_register_notifier(&irq_notifier_block); | ||
340 | } | 388 | } |
341 | #else | 389 | #else |
342 | static void __init irq_pm_init(void) | 390 | static void __init irq_pm_init(void) |
343 | {} | 391 | {} |
344 | #endif | 392 | #endif |
345 | 393 | ||
394 | void __iomem *omap_get_wakeupgen_base(void) | ||
395 | { | ||
396 | return wakeupgen_base; | ||
397 | } | ||
398 | |||
399 | int omap_secure_apis_support(void) | ||
400 | { | ||
401 | return omap_secure_apis; | ||
402 | } | ||
403 | |||
346 | /* | 404 | /* |
347 | * Initialise the wakeupgen module. | 405 | * Initialise the wakeupgen module. |
348 | */ | 406 | */ |
@@ -358,12 +416,18 @@ int __init omap_wakeupgen_init(void) | |||
358 | } | 416 | } |
359 | 417 | ||
360 | /* Static mapping, never released */ | 418 | /* Static mapping, never released */ |
361 | wakeupgen_base = ioremap(OMAP44XX_WKUPGEN_BASE, SZ_4K); | 419 | wakeupgen_base = ioremap(OMAP_WKUPGEN_BASE, SZ_4K); |
362 | if (WARN_ON(!wakeupgen_base)) | 420 | if (WARN_ON(!wakeupgen_base)) |
363 | return -ENOMEM; | 421 | return -ENOMEM; |
364 | 422 | ||
423 | if (cpu_is_omap44xx()) { | ||
424 | irq_banks = OMAP4_NR_BANKS; | ||
425 | max_irqs = OMAP4_NR_IRQS; | ||
426 | omap_secure_apis = 1; | ||
427 | } | ||
428 | |||
365 | /* Clear all IRQ bitmasks at wakeupGen level */ | 429 | /* Clear all IRQ bitmasks at wakeupGen level */ |
366 | for (i = 0; i < NR_REG_BANKS; i++) { | 430 | for (i = 0; i < irq_banks; i++) { |
367 | wakeupgen_writel(0, i, CPU0_ID); | 431 | wakeupgen_writel(0, i, CPU0_ID); |
368 | wakeupgen_writel(0, i, CPU1_ID); | 432 | wakeupgen_writel(0, i, CPU1_ID); |
369 | } | 433 | } |
@@ -382,7 +446,7 @@ int __init omap_wakeupgen_init(void) | |||
382 | */ | 446 | */ |
383 | 447 | ||
384 | /* Associate all the IRQs to boot CPU like GIC init does. */ | 448 | /* Associate all the IRQs to boot CPU like GIC init does. */ |
385 | for (i = 0; i < NR_IRQS; i++) | 449 | for (i = 0; i < max_irqs; i++) |
386 | irq_target_cpu[i] = boot_cpu; | 450 | irq_target_cpu[i] = boot_cpu; |
387 | 451 | ||
388 | irq_hotplug_init(); | 452 | irq_hotplug_init(); |