aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dma.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2009-11-22 13:08:43 -0500
committerTony Lindgren <tony@atomide.com>2009-11-22 13:08:43 -0500
commita76df42a675c9936e8bf3607226e74c8a5e2d847 (patch)
tree96d93706d884dea956393653452fa4d78d8d7f76 /arch/arm/plat-omap/dma.c
parent648f4e3e50c4793d9dbf9a09afa193631f76fa26 (diff)
parent8171d88089ad63fc442b2bf32af7c18653adc5cb (diff)
Merge 7xx-iosplit-plat-merge with omap-fixes
Merge branch '7xx-iosplit-plat-merge' into omap-for-linus
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r--arch/arm/plat-omap/dma.c86
1 files changed, 73 insertions, 13 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 68eaae324b6a..be4ce070fb4c 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -32,9 +32,9 @@
32 32
33#include <asm/system.h> 33#include <asm/system.h>
34#include <mach/hardware.h> 34#include <mach/hardware.h>
35#include <mach/dma.h> 35#include <plat/dma.h>
36 36
37#include <mach/tc.h> 37#include <plat/tc.h>
38 38
39#undef DEBUG 39#undef DEBUG
40 40
@@ -54,6 +54,12 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
54 54
55static int enable_1510_mode; 55static int enable_1510_mode;
56 56
57static struct omap_dma_global_context_registers {
58 u32 dma_irqenable_l0;
59 u32 dma_ocp_sysconfig;
60 u32 dma_gcr;
61} omap_dma_global_context;
62
57struct omap_dma_lch { 63struct omap_dma_lch {
58 int next_lch; 64 int next_lch;
59 int dev_id; 65 int dev_id;
@@ -2355,44 +2361,83 @@ void omap_stop_lcd_dma(void)
2355} 2361}
2356EXPORT_SYMBOL(omap_stop_lcd_dma); 2362EXPORT_SYMBOL(omap_stop_lcd_dma);
2357 2363
2364void omap_dma_global_context_save(void)
2365{
2366 omap_dma_global_context.dma_irqenable_l0 =
2367 dma_read(IRQENABLE_L0);
2368 omap_dma_global_context.dma_ocp_sysconfig =
2369 dma_read(OCP_SYSCONFIG);
2370 omap_dma_global_context.dma_gcr = dma_read(GCR);
2371}
2372
2373void omap_dma_global_context_restore(void)
2374{
2375 int ch;
2376
2377 dma_write(omap_dma_global_context.dma_gcr, GCR);
2378 dma_write(omap_dma_global_context.dma_ocp_sysconfig,
2379 OCP_SYSCONFIG);
2380 dma_write(omap_dma_global_context.dma_irqenable_l0,
2381 IRQENABLE_L0);
2382
2383 /*
2384 * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared
2385 * after secure sram context save and restore. Hence we need to
2386 * manually clear those IRQs to avoid spurious interrupts. This
2387 * affects only secure devices.
2388 */
2389 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
2390 dma_write(0x3 , IRQSTATUS_L0);
2391
2392 for (ch = 0; ch < dma_chan_count; ch++)
2393 if (dma_chan[ch].dev_id != -1)
2394 omap_clear_dma(ch);
2395}
2396
2358/*----------------------------------------------------------------------------*/ 2397/*----------------------------------------------------------------------------*/
2359 2398
2360static int __init omap_init_dma(void) 2399static int __init omap_init_dma(void)
2361{ 2400{
2401 unsigned long base;
2362 int ch, r; 2402 int ch, r;
2363 2403
2364 if (cpu_class_is_omap1()) { 2404 if (cpu_class_is_omap1()) {
2365 omap_dma_base = OMAP1_IO_ADDRESS(OMAP1_DMA_BASE); 2405 base = OMAP1_DMA_BASE;
2366 dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; 2406 dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
2367 } else if (cpu_is_omap24xx()) { 2407 } else if (cpu_is_omap24xx()) {
2368 omap_dma_base = OMAP2_IO_ADDRESS(OMAP24XX_DMA4_BASE); 2408 base = OMAP24XX_DMA4_BASE;
2369 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; 2409 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2370 } else if (cpu_is_omap34xx()) { 2410 } else if (cpu_is_omap34xx()) {
2371 omap_dma_base = OMAP2_IO_ADDRESS(OMAP34XX_DMA4_BASE); 2411 base = OMAP34XX_DMA4_BASE;
2372 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; 2412 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2373 } else if (cpu_is_omap44xx()) { 2413 } else if (cpu_is_omap44xx()) {
2374 omap_dma_base = OMAP2_IO_ADDRESS(OMAP44XX_DMA4_BASE); 2414 base = OMAP44XX_DMA4_BASE;
2375 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT; 2415 dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
2376 } else { 2416 } else {
2377 pr_err("DMA init failed for unsupported omap\n"); 2417 pr_err("DMA init failed for unsupported omap\n");
2378 return -ENODEV; 2418 return -ENODEV;
2379 } 2419 }
2380 2420
2421 omap_dma_base = ioremap(base, SZ_4K);
2422 BUG_ON(!omap_dma_base);
2423
2381 if (cpu_class_is_omap2() && omap_dma_reserve_channels 2424 if (cpu_class_is_omap2() && omap_dma_reserve_channels
2382 && (omap_dma_reserve_channels <= dma_lch_count)) 2425 && (omap_dma_reserve_channels <= dma_lch_count))
2383 dma_lch_count = omap_dma_reserve_channels; 2426 dma_lch_count = omap_dma_reserve_channels;
2384 2427
2385 dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count, 2428 dma_chan = kzalloc(sizeof(struct omap_dma_lch) * dma_lch_count,
2386 GFP_KERNEL); 2429 GFP_KERNEL);
2387 if (!dma_chan) 2430 if (!dma_chan) {
2388 return -ENOMEM; 2431 r = -ENOMEM;
2432 goto out_unmap;
2433 }
2389 2434
2390 if (cpu_class_is_omap2()) { 2435 if (cpu_class_is_omap2()) {
2391 dma_linked_lch = kzalloc(sizeof(struct dma_link_info) * 2436 dma_linked_lch = kzalloc(sizeof(struct dma_link_info) *
2392 dma_lch_count, GFP_KERNEL); 2437 dma_lch_count, GFP_KERNEL);
2393 if (!dma_linked_lch) { 2438 if (!dma_linked_lch) {
2394 kfree(dma_chan); 2439 r = -ENOMEM;
2395 return -ENOMEM; 2440 goto out_free;
2396 } 2441 }
2397 } 2442 }
2398 2443
@@ -2466,7 +2511,7 @@ static int __init omap_init_dma(void)
2466 for (i = 0; i < ch; i++) 2511 for (i = 0; i < ch; i++)
2467 free_irq(omap1_dma_irq[i], 2512 free_irq(omap1_dma_irq[i],
2468 (void *) (i + 1)); 2513 (void *) (i + 1));
2469 return r; 2514 goto out_free;
2470 } 2515 }
2471 } 2516 }
2472 } 2517 }
@@ -2484,8 +2529,8 @@ static int __init omap_init_dma(void)
2484 setup_irq(irq, &omap24xx_dma_irq); 2529 setup_irq(irq, &omap24xx_dma_irq);
2485 } 2530 }
2486 2531
2487 /* Enable smartidle idlemodes and autoidle */
2488 if (cpu_is_omap34xx()) { 2532 if (cpu_is_omap34xx()) {
2533 /* Enable smartidle idlemodes and autoidle */
2489 u32 v = dma_read(OCP_SYSCONFIG); 2534 u32 v = dma_read(OCP_SYSCONFIG);
2490 v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK | 2535 v &= ~(DMA_SYSCONFIG_MIDLEMODE_MASK |
2491 DMA_SYSCONFIG_SIDLEMODE_MASK | 2536 DMA_SYSCONFIG_SIDLEMODE_MASK |
@@ -2494,6 +2539,13 @@ static int __init omap_init_dma(void)
2494 DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) | 2539 DMA_SYSCONFIG_SIDLEMODE(DMA_IDLEMODE_SMARTIDLE) |
2495 DMA_SYSCONFIG_AUTOIDLE); 2540 DMA_SYSCONFIG_AUTOIDLE);
2496 dma_write(v , OCP_SYSCONFIG); 2541 dma_write(v , OCP_SYSCONFIG);
2542 /* reserve dma channels 0 and 1 in high security devices */
2543 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
2544 printk(KERN_INFO "Reserving DMA channels 0 and 1 for "
2545 "HS ROM code\n");
2546 dma_chan[0].dev_id = 0;
2547 dma_chan[1].dev_id = 1;
2548 }
2497 } 2549 }
2498 2550
2499 2551
@@ -2508,11 +2560,19 @@ static int __init omap_init_dma(void)
2508 "(error %d)\n", r); 2560 "(error %d)\n", r);
2509 for (i = 0; i < dma_chan_count; i++) 2561 for (i = 0; i < dma_chan_count; i++)
2510 free_irq(omap1_dma_irq[i], (void *) (i + 1)); 2562 free_irq(omap1_dma_irq[i], (void *) (i + 1));
2511 return r; 2563 goto out_free;
2512 } 2564 }
2513 } 2565 }
2514 2566
2515 return 0; 2567 return 0;
2568
2569out_free:
2570 kfree(dma_chan);
2571
2572out_unmap:
2573 iounmap(omap_dma_base);
2574
2575 return r;
2516} 2576}
2517 2577
2518arch_initcall(omap_init_dma); 2578arch_initcall(omap_init_dma);