aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/omap-wakeupgen.c
diff options
context:
space:
mode:
authorSantosh Shilimkar <santosh.shilimkar@ti.com>2012-05-09 11:08:35 -0400
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2012-07-09 09:44:39 -0400
commit247c445c0fbd52c77e497ff5bfcf0dceb8afea8d (patch)
tree3334a9cd1b573fa5d447cf0876e8904d21aef105 /arch/arm/mach-omap2/omap-wakeupgen.c
parente17933c2c0173ec19aa2450e4be79b7adfd52224 (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.c114
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
44static void __iomem *wakeupgen_base; 46static void __iomem *wakeupgen_base;
45static void __iomem *sar_base; 47static void __iomem *sar_base;
46static DEFINE_SPINLOCK(wakeupgen_lock); 48static DEFINE_SPINLOCK(wakeupgen_lock);
47static unsigned int irq_target_cpu[NR_IRQS]; 49static unsigned int irq_target_cpu[NR_IRQS];
50static unsigned int irq_banks = MAX_NR_REG_BANKS;
51static unsigned int max_irqs = MAX_IRQS;
52static 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
149static DEFINE_PER_CPU(u32 [NR_REG_BANKS], irqmasks); 154static DEFINE_PER_CPU(u32 [MAX_NR_REG_BANKS], irqmasks);
150 155
151static void _wakeupgen_save_masks(unsigned int cpu) 156static 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/* 204static 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 */
207static 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
254static 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 */
289static 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)
262static void irq_sar_clear(void) 303static 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
337static void __init irq_pm_init(void) 383static 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
342static void __init irq_pm_init(void) 390static void __init irq_pm_init(void)
343{} 391{}
344#endif 392#endif
345 393
394void __iomem *omap_get_wakeupgen_base(void)
395{
396 return wakeupgen_base;
397}
398
399int 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();