From 7e9bf8475f4cd36e71a42cf5b33626a21ffec007 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 19 Oct 2009 15:25:15 -0700 Subject: omap: Use ioremap in dma.c Use ioremap in dma.c Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'arch/arm/plat-omap/dma.c') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 0eb676d7e80..034686d6689 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -2347,40 +2347,46 @@ EXPORT_SYMBOL(omap_stop_lcd_dma); static int __init omap_init_dma(void) { + unsigned long base; int ch, r; if (cpu_class_is_omap1()) { - omap_dma_base = OMAP1_IO_ADDRESS(OMAP1_DMA_BASE); + base = OMAP1_DMA_BASE; dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; } else if (cpu_is_omap24xx()) { - omap_dma_base = OMAP2_IO_ADDRESS(OMAP24XX_DMA4_BASE); + base = OMAP24XX_DMA4_BASE; dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else if (cpu_is_omap34xx()) { - omap_dma_base = OMAP2_IO_ADDRESS(OMAP34XX_DMA4_BASE); + base = OMAP34XX_DMA4_BASE; dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else if (cpu_is_omap44xx()) { - omap_dma_base = OMAP2_IO_ADDRESS(OMAP44XX_DMA4_BASE); + base = OMAP44XX_DMA4_BASE; dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; } else { pr_err("DMA init failed for unsupported omap\n"); return -ENODEV; } + omap_dma_base = ioremap(base, SZ_4K); + BUG_ON(!omap_dma_base); + if (cpu_class_is_omap2() && omap_dma_reserve_channels && (omap_dma_reserve_channels <= dma_lch_count)) dma_lch_count = omap_dma_reserve_channels; dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, GFP_KERNEL); - if (!dma_chan) - return -ENOMEM; + if (!dma_chan) { + r = -ENOMEM; + goto out_unmap; + } if (cpu_class_is_omap2()) { dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * dma_lch_count, GFP_KERNEL); if (!dma_linked_lch) { - kfree(dma_chan); - return -ENOMEM; + r = -ENOMEM; + goto out_free; } } @@ -2454,7 +2460,7 @@ static int __init omap_init_dma(void) for (i = 0; i < ch; i++) free_irq(omap1_dma_irq[i], (void *) (i + 1)); - return r; + goto out_free; } } } @@ -2496,11 +2502,19 @@ static int __init omap_init_dma(void) "(error %d)\n", r); for (i = 0; i < dma_chan_count; i++) free_irq(omap1_dma_irq[i], (void *) (i + 1)); - return r; + goto out_free; } } return 0; + +out_free: + kfree(dma_chan); + +out_unmap: + iounmap(omap_dma_base); + + return r; } arch_initcall(omap_init_dma); -- cgit v1.2.3 From ce491cf85466c3377228c5a852ea627ec5136956 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 20 Oct 2009 09:40:47 -0700 Subject: omap: headers: Move remaining headers from include/mach to include/plat Move the remaining headers under plat-omap/include/mach to plat-omap/include/plat. Also search and replace the files using these headers to include using the right path. This was done with: #!/bin/bash mach_dir_old="arch/arm/plat-omap/include/mach" plat_dir_new="arch/arm/plat-omap/include/plat" headers=$(cd $mach_dir_old && ls *.h) omap_dirs="arch/arm/*omap*/ \ drivers/video/omap \ sound/soc/omap" other_files="drivers/leds/leds-ams-delta.c \ drivers/mfd/menelaus.c \ drivers/mfd/twl4030-core.c \ drivers/mtd/nand/ams-delta.c" for header in $headers; do old="#include --- arch/arm/plat-omap/dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/plat-omap/dma.c') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 034686d6689..9e11cddf3f7 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -32,9 +32,9 @@ #include #include -#include +#include -#include +#include #undef DEBUG -- cgit v1.2.3 From f2d1185824fd3ed631f3164daeff59d0b4e55d79 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 28 Aug 2008 13:13:31 +0000 Subject: OMAP: PM: DMA context save/restore for off-mode support For HS/EMU devices, these additional features are also used: - DMA interrupt disable routine added - Added DMA controller reset to DMA context restore Signed-off-by: Tero Kristo Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/dma.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'arch/arm/plat-omap/dma.c') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 3edffde7f43..3105aaa95d7 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -54,6 +54,12 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; static int enable_1510_mode; +static struct omap_dma_global_context_registers { + u32 dma_irqenable_l0; + u32 dma_ocp_sysconfig; + u32 dma_gcr; +} omap_dma_global_context; + struct omap_dma_lch { int next_lch; int dev_id; @@ -2341,6 +2347,39 @@ void omap_stop_lcd_dma(void) } EXPORT_SYMBOL(omap_stop_lcd_dma); +void omap_dma_global_context_save(void) +{ + omap_dma_global_context.dma_irqenable_l0 = + dma_read(IRQENABLE_L0); + omap_dma_global_context.dma_ocp_sysconfig = + dma_read(OCP_SYSCONFIG); + omap_dma_global_context.dma_gcr = dma_read(GCR); +} + +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); + } +} + /*----------------------------------------------------------------------------*/ static int __init omap_init_dma(void) -- cgit v1.2.3 From ba50ea7eb9ce663511013b35608cf0753c9ab674 Mon Sep 17 00:00:00 2001 From: Kalle Jokiniemi Date: Thu, 26 Mar 2009 15:59:00 +0200 Subject: 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 Signed-off-by: Jouni Hogander Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/dma.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'arch/arm/plat-omap/dma.c') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 3105aaa95d7..1b5216f1e78 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; + } } -- cgit v1.2.3 From bf07c9f2d869077cc918b4cda861eadac6df6283 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 20 May 2009 16:58:30 +0300 Subject: OMAP: PM: Clear DMA channel state after a wakeup Clear DMA channel states so that users can assume a known initial state. Signed-off-by: Aaro Koskinen Signed-off-by: Kevin Hilman --- arch/arm/plat-omap/dma.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch/arm/plat-omap/dma.c') diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 1b5216f1e78..8836da32d63 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -2358,6 +2358,8 @@ void omap_dma_global_context_save(void) void omap_dma_global_context_restore(void) { + int ch; + dma_write(omap_dma_global_context.dma_gcr, GCR); dma_write(omap_dma_global_context.dma_ocp_sysconfig, OCP_SYSCONFIG); @@ -2372,6 +2374,10 @@ void omap_dma_global_context_restore(void) */ if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) dma_write(0x3 , IRQSTATUS_L0); + + for (ch = 0; ch < dma_chan_count; ch++) + if (dma_chan[ch].dev_id != -1) + omap_clear_dma(ch); } /*----------------------------------------------------------------------------*/ -- cgit v1.2.3