Add DMA support for MPC83xx.
authorMarian Balakowicz <m8@semihalf.com>
Tue, 14 Mar 2006 15:14:48 +0000 (16:14 +0100)
committerMarian Balakowicz <m8@semihalf.com>
Tue, 14 Mar 2006 15:14:48 +0000 (16:14 +0100)
CHANGELOG
cpu/mpc83xx/cpu.c
include/asm-ppc/immap_83xx.h

index f4819235a8d1ccccf0531decf8adf584040d5898..81e7cf26156a6332d3a07d88f54971eb1aa30bf2 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@
 Changes since U-Boot 1.1.4:
 ======================================================================
 
+* Add DMA support for MPC83xx.
+
 * Add sync in do_reset() routine for MPC83xx after RPR register
   was written to. It is need on some targets when BAT translation
   is enabled.
index 63f82422f5b5bb4a9bbf1a8b95fc10d37e0b63b4..f24d3a4b1cd95eec0884111238bd2a467bf6cc35 100644 (file)
@@ -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*/
index 2b2693c32ffcfa02d1e7057634f1b9a9f0d01710..b0e17ab9be54fd95a48a79c49ba938bc59ab6931 100644 (file)
@@ -847,10 +847,95 @@ typedef struct spi8349
        u8 res1[0xD8];
 } spi8349_t;
 
+
+/*
+ * DMA/Messaging Unit
+ */
 typedef struct dma8349 {
-       u8 fixme[0x300];
+       u32 res0[0xC];  /* 0x0-0x29 reseverd */
+       u32 omisr;      /* 0x30 Outbound message interrupt status register */
+       u32 omimr;      /* 0x34 Outbound message interrupt mask register */
+       u32 res1[0x6];  /* 0x38-0x49 reserved */
+
+       u32 imr0;       /* 0x50 Inbound message register 0 */
+       u32 imr1;       /* 0x54 Inbound message register 1 */
+       u32 omr0;       /* 0x58 Outbound message register 0 */
+       u32 omr1;       /* 0x5C Outbound message register 1 */
+
+       u32 odr;        /* 0x60 Outbound doorbell register */
+       u32 res2;       /* 0x64-0x67 reserved */
+       u32 idr;        /* 0x68 Inbound doorbell register */
+       u32 res3[0x5];  /* 0x6C-0x79 reserved */
+
+       u32 imisr;      /* 0x80 Inbound message interrupt status register */
+       u32 imimr;      /* 0x84 Inbound message interrupt mask register */
+       u32 res4[0x1E]; /* 0x88-0x99 reserved */
+
+       u32 dmamr0;     /* 0x100 DMA 0 mode register */
+       u32 dmasr0;     /* 0x104 DMA 0 status register */
+       u32 dmacdar0;   /* 0x108 DMA 0 current descriptor address register */
+       u32 res5;       /* 0x10C reserved */
+       u32 dmasar0;    /* 0x110 DMA 0 source address register */
+       u32 res6;       /* 0x114 reserved */
+       u32 dmadar0;    /* 0x118 DMA 0 destination address register */
+       u32 res7;       /* 0x11C reserved */
+       u32 dmabcr0;    /* 0x120 DMA 0 byte count register */
+       u32 dmandar0;   /* 0x124 DMA 0 next descriptor address register */
+       u32 res8[0x16]; /* 0x128-0x179 reserved */
+
+       u32 dmamr1;     /* 0x180 DMA 1 mode register */
+       u32 dmasr1;     /* 0x184 DMA 1 status register */
+       u32 dmacdar1;   /* 0x188 DMA 1 current descriptor address register */
+       u32 res9;       /* 0x18C reserved */
+       u32 dmasar1;    /* 0x190 DMA 1 source address register */
+       u32 res10;      /* 0x194 reserved */
+       u32 dmadar1;    /* 0x198 DMA 1 destination address register */
+       u32 res11;      /* 0x19C reserved */
+       u32 dmabcr1;    /* 0x1A0 DMA 1 byte count register */
+       u32 dmandar1;   /* 0x1A4 DMA 1 next descriptor address register */
+       u32 res12[0x16];/* 0x1A8-0x199 reserved */
+
+       u32 dmamr2;     /* 0x200 DMA 2 mode register */
+       u32 dmasr2;     /* 0x204 DMA 2 status register */
+       u32 dmacdar2;   /* 0x208 DMA 2 current descriptor address register */
+       u32 res13;      /* 0x20C reserved */
+       u32 dmasar2;    /* 0x210 DMA 2 source address register */
+       u32 res14;      /* 0x214 reserved */
+       u32 dmadar2;    /* 0x218 DMA 2 destination address register */
+       u32 res15;      /* 0x21C reserved */
+       u32 dmabcr2;    /* 0x220 DMA 2 byte count register */
+       u32 dmandar2;   /* 0x224 DMA 2 next descriptor address register */
+       u32 res16[0x16];/* 0x228-0x279 reserved */
+
+       u32 dmamr3;     /* 0x280 DMA 3 mode register */
+       u32 dmasr3;     /* 0x284 DMA 3 status register */
+       u32 dmacdar3;   /* 0x288 DMA 3 current descriptor address register */
+       u32 res17;      /* 0x28C reserved */
+       u32 dmasar3;    /* 0x290 DMA 3 source address register */
+       u32 res18;      /* 0x294 reserved */
+       u32 dmadar3;    /* 0x298 DMA 3 destination address register */
+       u32 res19;      /* 0x29C reserved */
+       u32 dmabcr3;    /* 0x2A0 DMA 3 byte count register */
+       u32 dmandar3;   /* 0x2A4 DMA 3 next descriptor address register */
+
+       u32 dmagsr;     /* 0x2A8 DMA general status register */
+       u32 res20[0x15];/* 0x2AC-0x2FF reserved */
 } dma8349_t;
 
+/* DMAMRn bits */
+#define DMA_CHANNEL_START                      (0x00000001)            /* Bit - DMAMRn CS */
+#define DMA_CHANNEL_TRANSFER_MODE_DIRECT       (0x00000004)            /* Bit - DMAMRn CTM */
+#define DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN     (0x00001000)            /* Bit - DMAMRn SAHE */
+#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_1B     (0x00000000)            /* 2Bit- DMAMRn SAHTS 1byte */
+#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_2B     (0x00004000)            /* 2Bit- DMAMRn SAHTS 2bytes */
+#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_4B     (0x00008000)            /* 2Bit- DMAMRn SAHTS 4bytes */
+#define DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B     (0x0000c000)            /* 2Bit- DMAMRn SAHTS 8bytes */
+#define DMA_CHANNEL_SNOOP                      (0x00010000)            /* Bit - DMAMRn DMSEN */
+
+/* DMASRn bits */
+#define DMA_CHANNEL_BUSY                       (0x00000004)            /* Bit - DMASRn CB */
+#define DMA_CHANNEL_TRANSFER_ERROR             (0x00000080)            /* Bit - DMASRn TE */
+
 /*
  * PCI Software Configuration Registers
  */