summaryrefslogtreecommitdiff
path: root/arch/arm/plat-omap/dma.c
diff options
context:
space:
mode:
authorKalle Jokiniemi <kalle.jokiniemi@digia.com>2009-03-26 15:59:00 +0200
committerKevin Hilman <khilman@deeprootsystems.com>2009-11-11 14:42:26 -0800
commitba50ea7eb9ce663511013b35608cf0753c9ab674 (patch)
treee3dc023dd370a66ece98ba3fdae2f90db871cdbf /arch/arm/plat-omap/dma.c
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>
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r--arch/arm/plat-omap/dma.c31
1 files changed, 16 insertions, 15 deletions
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)
void omap_dma_global_context_restore(void)
{
- dma_write(0x2, OCP_SYSCONFIG);
- while (!__raw_readl(omap_dma_base + OMAP_DMA4_SYSSTATUS))
- ;
dma_write(omap_dma_global_context.dma_gcr, GCR);
dma_write(omap_dma_global_context.dma_ocp_sysconfig,
OCP_SYSCONFIG);
dma_write(omap_dma_global_context.dma_irqenable_l0,
IRQENABLE_L0);
-}
-
-void omap_dma_disable_irq(int lch)
-{
- u32 val;
- if (cpu_class_is_omap2()) {
- /* Disable interrupts */
- val = dma_read(IRQENABLE_L0);
- val &= ~(1 << lch);
- dma_write(val, IRQENABLE_L0);
- }
+ /*
+ * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
+ * after secure sram context save and restore. Hence we need to
+ * manually clear those IRQs to avoid spurious interrupts. This
+ * affects only secure devices.
+ */
+ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+ dma_write(0x3 , IRQSTATUS_L0);
}
/*----------------------------------------------------------------------------*/
@@ -2515,8 +2509,8 @@ static int __init omap_init_dma(void)
setup_irq(irq, &omap24xx_dma_irq);
}
- /* Enable smartidle idlemodes and autoidle */
if (cpu_is_omap34xx()) {
+ /* Enable smartidle idlemodes and autoidle */
u32 v = dma_read(OCP_SYSCONFIG);
v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
DMA_SYSCONFIG_SIDLEMODE_MASK |
@@ -2525,6 +2519,13 @@ static int __init omap_init_dma(void)
DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
DMA_SYSCONFIG_AUTOIDLE);
dma_write(v , OCP_SYSCONFIG);
+ /* reserve dma channels 0 and 1 in high security devices */
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+ printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
+ "HS ROM code\n");
+ dma_chan[0].dev_id = 0;
+ dma_chan[1].dev_id = 1;
+ }
}