diff options
author | Tero Kristo <tero.kristo@nokia.com> | 2008-08-28 09:13:31 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2009-11-11 17:42:25 -0500 |
commit | f2d1185824fd3ed631f3164daeff59d0b4e55d79 (patch) | |
tree | de31dfc36411fa43ae1fe99d1402e67b53ade827 | |
parent | 2f5939c3ec9440a9c3a0baf4d0e1b2cc043aad46 (diff) |
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 <tero.kristo@nokia.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 3 | ||||
-rw-r--r-- | arch/arm/plat-omap/dma.c | 39 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dma.h | 5 |
3 files changed, 47 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index bab9b480a089..54fea79b1720 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <plat/sdrc.h> | 34 | #include <plat/sdrc.h> |
35 | #include <plat/prcm.h> | 35 | #include <plat/prcm.h> |
36 | #include <plat/gpmc.h> | 36 | #include <plat/gpmc.h> |
37 | #include <plat/dma.h> | ||
37 | 38 | ||
38 | #include <asm/tlbflush.h> | 39 | #include <asm/tlbflush.h> |
39 | 40 | ||
@@ -95,6 +96,7 @@ static void omap3_core_save_context(void) | |||
95 | omap3_gpmc_save_context(); | 96 | omap3_gpmc_save_context(); |
96 | /* Save the system control module context, padconf already save above*/ | 97 | /* Save the system control module context, padconf already save above*/ |
97 | omap3_control_save_context(); | 98 | omap3_control_save_context(); |
99 | omap_dma_global_context_save(); | ||
98 | } | 100 | } |
99 | 101 | ||
100 | static void omap3_core_restore_context(void) | 102 | static void omap3_core_restore_context(void) |
@@ -105,6 +107,7 @@ static void omap3_core_restore_context(void) | |||
105 | omap3_gpmc_restore_context(); | 107 | omap3_gpmc_restore_context(); |
106 | /* Restore the interrupt controller context */ | 108 | /* Restore the interrupt controller context */ |
107 | omap_intc_restore_context(); | 109 | omap_intc_restore_context(); |
110 | omap_dma_global_context_restore(); | ||
108 | } | 111 | } |
109 | 112 | ||
110 | /* | 113 | /* |
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 3edffde7f439..3105aaa95d75 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 }; | |||
54 | 54 | ||
55 | static int enable_1510_mode; | 55 | static int enable_1510_mode; |
56 | 56 | ||
57 | static 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 | |||
57 | struct omap_dma_lch { | 63 | struct omap_dma_lch { |
58 | int next_lch; | 64 | int next_lch; |
59 | int dev_id; | 65 | int dev_id; |
@@ -2341,6 +2347,39 @@ void omap_stop_lcd_dma(void) | |||
2341 | } | 2347 | } |
2342 | EXPORT_SYMBOL(omap_stop_lcd_dma); | 2348 | EXPORT_SYMBOL(omap_stop_lcd_dma); |
2343 | 2349 | ||
2350 | void omap_dma_global_context_save(void) | ||
2351 | { | ||
2352 | omap_dma_global_context.dma_irqenable_l0 = | ||
2353 | dma_read(IRQENABLE_L0); | ||
2354 | omap_dma_global_context.dma_ocp_sysconfig = | ||
2355 | dma_read(OCP_SYSCONFIG); | ||
2356 | omap_dma_global_context.dma_gcr = dma_read(GCR); | ||
2357 | } | ||
2358 | |||
2359 | void omap_dma_global_context_restore(void) | ||
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); | ||
2365 | dma_write(omap_dma_global_context.dma_ocp_sysconfig, | ||
2366 | OCP_SYSCONFIG); | ||
2367 | dma_write(omap_dma_global_context.dma_irqenable_l0, | ||
2368 | IRQENABLE_L0); | ||
2369 | } | ||
2370 | |||
2371 | void omap_dma_disable_irq(int lch) | ||
2372 | { | ||
2373 | u32 val; | ||
2374 | |||
2375 | if (cpu_class_is_omap2()) { | ||
2376 | /* Disable interrupts */ | ||
2377 | val = dma_read(IRQENABLE_L0); | ||
2378 | val &= ~(1 << lch); | ||
2379 | dma_write(val, IRQENABLE_L0); | ||
2380 | } | ||
2381 | } | ||
2382 | |||
2344 | /*----------------------------------------------------------------------------*/ | 2383 | /*----------------------------------------------------------------------------*/ |
2345 | 2384 | ||
2346 | static int __init omap_init_dma(void) | 2385 | static int __init omap_init_dma(void) |
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h index 72f680b7180d..1c017b29b7e9 100644 --- a/arch/arm/plat-omap/include/plat/dma.h +++ b/arch/arm/plat-omap/include/plat/dma.h | |||
@@ -633,6 +633,11 @@ extern void omap_set_dma_dst_endian_type(int lch, enum end_type etype); | |||
633 | extern void omap_set_dma_src_endian_type(int lch, enum end_type etype); | 633 | extern void omap_set_dma_src_endian_type(int lch, enum end_type etype); |
634 | extern int omap_get_dma_index(int lch, int *ei, int *fi); | 634 | extern int omap_get_dma_index(int lch, int *ei, int *fi); |
635 | 635 | ||
636 | void omap_dma_global_context_save(void); | ||
637 | void omap_dma_global_context_restore(void); | ||
638 | |||
639 | extern void omap_dma_disable_irq(int lch); | ||
640 | |||
636 | /* Chaining APIs */ | 641 | /* Chaining APIs */ |
637 | #ifndef CONFIG_ARCH_OMAP1 | 642 | #ifndef CONFIG_ARCH_OMAP1 |
638 | extern int omap_request_dma_chain(int dev_id, const char *dev_name, | 643 | extern int omap_request_dma_chain(int dev_id, const char *dev_name, |