diff options
author | Gary King <gking@nvidia.com> | 2010-05-27 16:41:01 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-27 21:40:57 -0700 |
commit | 2931ae96bea6f5f4b8573e483231a5899af3fe87 (patch) | |
tree | 52df97a444256447efed18c5b1a220c92ab339b3 /arch | |
parent | 7d76a13011874ab1d56479f7c18d1d6095a5d550 (diff) |
[ARM/tegra] dma: add suspend and resume functions for tegra DMA
Change-Id: Iac4642b534c75f2b9252866b331062e461f82f78
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/dma.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index 43f8622ee12f..1d44073ce541 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -38,6 +38,8 @@ #define APB_DMA_CNTRL 0x010 +#define APB_DMA_IRQ_MASK 0x01c + #define APB_DMA_IRQ_MASK_SET 0x020 #define APB_DMA_CHAN_CSR 0x000 @@ -95,9 +97,11 @@ #define APB_SEQ_WRAP_SHIFT 16 #define APB_SEQ_WRAP_MASK (0x7<<APB_SEQ_WRAP_SHIFT) +#define TEGRA_SYSTEM_DMA_CH_NR 16 #define TEGRA_SYSTEM_DMA_AVP_CH_NUM 3 #define TEGRA_SYSTEM_DMA_CH_MIN 0 -#define TEGRA_SYSTEM_DMA_CH_MAX (15 - TEGRA_SYSTEM_DMA_AVP_CH_NUM) +#define TEGRA_SYSTEM_DMA_CH_MAX \ + (TEGRA_SYSTEM_DMA_CH_NR - TEGRA_SYSTEM_DMA_AVP_CH_NUM - 1) #define NV_DMA_MAX_TRASFER_SIZE 0x10000 @@ -730,3 +734,54 @@ fail: } return ret; } + +#ifdef CONFIG_PM +static u32 apb_dma[6*TEGRA_SYSTEM_DMA_CH_NR + 3]; + +void tegra_dma_suspend(void) +{ + void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); + u32 *ctx = apb_dma; + int i; + + *ctx++ = readl(addr + APB_DMA_GEN); + *ctx++ = readl(addr + APB_DMA_CNTRL); + *ctx++ = readl(addr + APB_DMA_IRQ_MASK); + + for (i=0; i<TEGRA_SYSTEM_DMA_CH_NR; i++) { + addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + + TEGRA_APB_DMA_CH0_SIZE * i); + + *ctx++ = readl(addr + APB_DMA_CHAN_CSR); + *ctx++ = readl(addr + APB_DMA_CHAN_STA); + *ctx++ = readl(addr + APB_DMA_CHAN_AHB_PTR); + *ctx++ = readl(addr + APB_DMA_CHAN_AHB_SEQ); + *ctx++ = readl(addr + APB_DMA_CHAN_APB_PTR); + *ctx++ = readl(addr + APB_DMA_CHAN_APB_SEQ); + } +} + +void tegra_dma_resume(void) +{ + void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE); + u32 *ctx = apb_dma; + int i; + + writel(*ctx++, addr + APB_DMA_GEN); + writel(*ctx++, addr + APB_DMA_CNTRL); + writel(*ctx++, addr + APB_DMA_IRQ_MASK); + + for (i=0; i<TEGRA_SYSTEM_DMA_CH_NR; i++) { + addr = IO_ADDRESS(TEGRA_APB_DMA_CH0_BASE + + TEGRA_APB_DMA_CH0_SIZE * i); + + writel(*ctx++, addr + APB_DMA_CHAN_CSR); + writel(*ctx++, addr + APB_DMA_CHAN_STA); + writel(*ctx++, addr + APB_DMA_CHAN_AHB_PTR); + writel(*ctx++, addr + APB_DMA_CHAN_AHB_SEQ); + writel(*ctx++, addr + APB_DMA_CHAN_APB_PTR); + writel(*ctx++, addr + APB_DMA_CHAN_APB_SEQ); + } +} + +#endif |