summaryrefslogtreecommitdiffstats
path: root/cpu
diff options
context:
space:
mode:
authorMarian Balakowicz <m8@semihalf.com>2006-03-14 16:14:48 +0100
committerMarian Balakowicz <m8@semihalf.com>2006-03-14 16:14:48 +0100
commit61f25155acd99caef08897da390382d5c7fbfd74 (patch)
treed2646b46390c337489b5088e7ed76daa80f791ab /cpu
parent6d8ae5abb5311bd8e306a5a060dcfbeb0874a169 (diff)
downloadbootable_bootloader_goldelico_gta04-61f25155acd99caef08897da390382d5c7fbfd74.zip
bootable_bootloader_goldelico_gta04-61f25155acd99caef08897da390382d5c7fbfd74.tar.gz
bootable_bootloader_goldelico_gta04-61f25155acd99caef08897da390382d5c7fbfd74.tar.bz2
Add DMA support for MPC83xx.
Diffstat (limited to 'cpu')
-rw-r--r--cpu/mpc83xx/cpu.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 63f8242..f24d3a4 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -191,3 +191,88 @@ ft_cpu_setup(void *blob, bd_t *bd)
#endif
}
#endif
+
+#if defined(CONFIG_DDR_ECC)
+void dma_init(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 status = swab32(dma->dmasr0);
+ volatile u32 dmamr0 = swab32(dma->dmamr0);
+
+ debug("DMA-init\n");
+
+ /* initialize DMASARn, DMADAR and DMAABCRn */
+ dma->dmadar0 = (u32)0;
+ dma->dmasar0 = (u32)0;
+ dma->dmabcr0 = 0;
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* clear CS bit */
+ dmamr0 &= ~DMA_CHANNEL_START;
+ dma->dmamr0 = swab32(dmamr0);
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* while the channel is busy, spin */
+ while(status & DMA_CHANNEL_BUSY) {
+ status = swab32(dma->dmasr0);
+ }
+
+ debug("DMA-init end\n");
+}
+
+uint dma_check(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 status = swab32(dma->dmasr0);
+ volatile u32 byte_count = swab32(dma->dmabcr0);
+
+ /* while the channel is busy, spin */
+ while (status & DMA_CHANNEL_BUSY) {
+ status = swab32(dma->dmasr0);
+ }
+
+ if (status & DMA_CHANNEL_TRANSFER_ERROR) {
+ printf ("DMA Error: status = %x @ %d\n", status, byte_count);
+ }
+
+ return status;
+}
+
+int dma_xfer(void *dest, u32 count, void *src)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_t *dma = &immap->dma;
+ volatile u32 dmamr0;
+
+ /* initialize DMASARn, DMADAR and DMAABCRn */
+ dma->dmadar0 = swab32((u32)dest);
+ dma->dmasar0 = swab32((u32)src);
+ dma->dmabcr0 = swab32(count);
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* init direct transfer, clear CS bit */
+ dmamr0 = (DMA_CHANNEL_TRANSFER_MODE_DIRECT |
+ DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B |
+ DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN);
+
+ dma->dmamr0 = swab32(dmamr0);
+
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ /* set CS to start DMA transfer */
+ dmamr0 |= DMA_CHANNEL_START;
+ dma->dmamr0 = swab32(dmamr0);
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
+
+ return ((int)dma_check());
+}
+#endif /*CONFIG_DDR_ECC*/