aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Jokiniemi <kalle.jokiniemi@digia.com>2009-03-26 09:59:00 -0400
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 17:42:26 -0500
commitba50ea7eb9ce663511013b35608cf0753c9ab674 (patch)
treee3dc023dd370a66ece98ba3fdae2f90db871cdbf
parent133464dc30846282b5f852433d7b6a31f292f886 (diff)
OMAP3: PM: Fix secure SRAM context save/restore
The secure sram context save uses dma channels 0 and 1. In order to avoid collision between kernel DMA transfers and ROM code dma transfers, we need to reserve DMA channels 0 1 on high security devices. A bug in ROM code leaves dma irq status bits uncleared. Hence those irq status bits need to be cleared when restoring DMA context after off mode. There was also a faulty parameter given to PPA in the secure ram context save assembly code, which caused interrupts to be enabled during secure ram context save. This caused the save to fail sometimes, which resulted the saved context to be corrupted, but also left DMA channels in secure mode. The secure mode DMA channels caused "DMA secure error with device 0" errors to be displayed. Signed-off-by: Kalle Jokiniemi <kalle.jokiniemi@digia.com> Signed-off-by: Jouni Hogander <jouni.hogander@nokia.com> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r--arch/arm/mach-omap2/pm34xx.c3
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S2
-rw-r--r--arch/arm/plat-omap/dma.c31
3 files changed, 17 insertions, 19 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 3f1f656348fc..a9f4034aa70a 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -130,9 +130,6 @@ static void omap3_save_secure_ram_context(u32 target_mpu_state)
130 u32 ret; 130 u32 ret;
131 131
132 if (omap_type() != OMAP2_DEVICE_TYPE_GP) { 132 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
133 /* Disable dma irq before calling secure rom code API */
134 omap_dma_disable_irq(0);
135 omap_dma_disable_irq(1);
136 /* 133 /*
137 * MPU next state must be set to POWER_ON temporarily, 134 * MPU next state must be set to POWER_ON temporarily,
138 * otherwise the WFI executed inside the ROM code 135 * otherwise the WFI executed inside the ROM code
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index db75167bc52d..b6abadccb1c6 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -68,7 +68,7 @@ save_secure_ram_debug:
68 mov r0, #25 @ set service ID for PPA 68 mov r0, #25 @ set service ID for PPA
69 mov r12, r0 @ copy secure service ID in r12 69 mov r12, r0 @ copy secure service ID in r12
70 mov r1, #0 @ set task id for ROM code in r1 70 mov r1, #0 @ set task id for ROM code in r1
71 mov r2, #7 @ set some flags in r2, r6 71 mov r2, #4 @ set some flags in r2, r6
72 mov r6, #0xff 72 mov r6, #0xff
73 mcr p15, 0, r0, c7, c10, 4 @ data write barrier 73 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
74 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier 74 mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 3105aaa95d75..1b5216f1e78d 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2358,26 +2358,20 @@ void omap_dma_global_context_save(void)
2358 2358
2359void omap_dma_global_context_restore(void) 2359void omap_dma_global_context_restore(void)
2360{ 2360{
2361 dma_write(0x2, OCP_SYSCONFIG);
2362 while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
2363 ;
2364 dma_write(omap_dma_global_context.dma_gcr, GCR); 2361 dma_write(omap_dma_global_context.dma_gcr, GCR);
2365 dma_write(omap_dma_global_context.dma_ocp_sysconfig, 2362 dma_write(omap_dma_global_context.dma_ocp_sysconfig,
2366 OCP_SYSCONFIG); 2363 OCP_SYSCONFIG);
2367 dma_write(omap_dma_global_context.dma_irqenable_l0, 2364 dma_write(omap_dma_global_context.dma_irqenable_l0,
2368 IRQENABLE_L0); 2365 IRQENABLE_L0);
2369}
2370
2371void omap_dma_disable_irq(int lch)
2372{
2373 u32 val;
2374 2366
2375 if (cpu_class_is_omap2()) { 2367 /*
2376 /* Disable interrupts */ 2368 * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
2377 val = dma_read(IRQENABLE_L0); 2369 * after secure sram context save and restore. Hence we need to
2378 val &= ~(1 << lch); 2370 * manually clear those IRQs to avoid spurious interrupts. This
2379 dma_write(val, IRQENABLE_L0); 2371 * affects only secure devices.
2380 } 2372 */
2373 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
2374 dma_write(0x3 , IRQSTATUS_L0);
2381} 2375}
2382 2376
2383/*----------------------------------------------------------------------------*/ 2377/*----------------------------------------------------------------------------*/
@@ -2515,8 +2509,8 @@ static int __init omap_init_dma(void)
2515 setup_irq(irq, &omap24xx_dma_irq); 2509 setup_irq(irq, &omap24xx_dma_irq);
2516 } 2510 }
2517 2511
2518 /* Enable smartidle idlemodes and autoidle */
2519 if (cpu_is_omap34xx()) { 2512 if (cpu_is_omap34xx()) {
2513 /* Enable smartidle idlemodes and autoidle */
2520 u32 v = dma_read(OCP_SYSCONFIG); 2514 u32 v = dma_read(OCP_SYSCONFIG);
2521 v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK | 2515 v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
2522 DMA_SYSCONFIG_SIDLEMODE_MASK | 2516 DMA_SYSCONFIG_SIDLEMODE_MASK |
@@ -2525,6 +2519,13 @@ static int __init omap_init_dma(void)
2525 DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | 2519 DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
2526 DMA_SYSCONFIG_AUTOIDLE); 2520 DMA_SYSCONFIG_AUTOIDLE);
2527 dma_write(v , OCP_SYSCONFIG); 2521 dma_write(v , OCP_SYSCONFIG);
2522 /* reserve dma channels 0 and 1 in high security devices */
2523 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
2524 printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
2525 "HS ROM code\n");
2526 dma_chan[0].dev_id = 0;
2527 dma_chan[1].dev_id = 1;
2528 }
2528 } 2529 }
2529 2530
2530 2531