83xx: Add support for fsl_dma driver
authorPeter Tyser <ptyser@xes-inc.com>
Tue, 30 Jun 2009 22:15:51 +0000 (17:15 -0500)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 2 Jul 2009 16:15:57 +0000 (11:15 -0500)
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Reviewed-by: Ira W. Snyder <iws@ovro.caltech.edu>
Tested-by: Ira W. Snyder <iws@ovro.caltech.edu>
Acked-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
cpu/mpc83xx/cpu.c
cpu/mpc83xx/spd_sdram.c
drivers/dma/fsl_dma.c
include/asm-ppc/config.h
include/asm-ppc/fsl_dma.h
include/asm-ppc/immap_83xx.h
include/mpc83xx.h

index a5c1f00b10b143b531cbc4bc460924dfbe8dcea6..e38a3722ca25f6fc7c8f082cbb787f770b6d28e5 100644 (file)
@@ -276,91 +276,6 @@ void watchdog_reset (void)
 }
 #endif
 
-#if defined(CONFIG_DDR_ECC)
-void dma_init(void)
-{
-       volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
-       volatile dma83xx_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 *)CONFIG_SYS_IMMR;
-       volatile dma83xx_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 dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count)
-{
-       volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
-       volatile dma83xx_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((u32)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*/
-
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
index 824396835a3532422a528dea10c4499cb3d44f8c..0f611804a0712e1b41db6e2b5da35b3d3d0293ee 100644 (file)
@@ -64,13 +64,6 @@ void board_add_ram_info(int use_default)
 }
 
 #ifdef CONFIG_SPD_EEPROM
-
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
-extern void dma_init(void);
-extern uint dma_check(void);
-extern int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t n);
-#endif
-
 #ifndef        CONFIG_SYS_READ_SPD
 #define CONFIG_SYS_READ_SPD    i2c_read
 #endif
@@ -863,7 +856,6 @@ static __inline__ unsigned long get_tbms (void)
 /*
  * Initialize all of memory for ECC, then enable errors.
  */
-/* #define CONFIG_DDR_ECC_INIT_VIA_DMA */
 void ddr_enable_ecc(unsigned int dram_size)
 {
        volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
@@ -872,45 +864,21 @@ void ddr_enable_ecc(unsigned int dram_size)
        register u64 *p;
        register uint size;
        unsigned int pattern[2];
-#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
-       uint i;
-#endif
+
        icache_enable();
        t_start = get_tbms();
        pattern[0] = 0xdeadbeef;
        pattern[1] = 0xdeadbeef;
 
-#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
+       dma_meminit(pattern[0], dram_size);
+#else
        debug("ddr init: CPU FP write method\n");
        size = dram_size;
        for (p = 0; p < (u64*)(size); p++) {
                ppcDWstore((u32*)p, pattern);
        }
        __asm__ __volatile__ ("sync");
-#else
-       debug("ddr init: DMA method\n");
-       size = 0x2000;
-       for (p = 0; p < (u64*)(size); p++) {
-               ppcDWstore((u32*)p, pattern);
-       }
-       __asm__ __volatile__ ("sync");
-
-       /* Initialise DMA for direct transfer */
-       dma_init();
-       /* Start DMA to transfer */
-       dmacpy(0x2000, 0, 0x2000); /* 8K */
-       dmacpy(0x4000, 0, 0x4000); /* 16K */
-       dmacpy(0x8000, 0, 0x8000); /* 32K */
-       dmacpy(0x10000, 0, 0x10000); /* 64K */
-       dmacpy(0x20000, 0, 0x20000); /* 128K */
-       dmacpy(0x40000, 0, 0x40000); /* 256K */
-       dmacpy(0x80000, 0, 0x80000); /* 512K */
-       dmacpy(0x100000, 0, 0x100000); /* 1M */
-       dmacpy(0x200000, 0, 0x200000); /* 2M */
-       dmacpy(0x400000, 0, 0x400000); /* 4M */
-
-       for (i = 1; i < dram_size / 0x800000; i++)
-               dmacpy(0x800000 * i, 0, 0x800000);
 #endif
 
        t_end = get_tbms();
index cba5d5b8a840a16d453963398b10d4e79bef3062..df33e7a3eec7a41a19f8186c5083d643e136ef40 100644 (file)
 /* Controller can only transfer 2^26 - 1 bytes at a time */
 #define FSL_DMA_MAX_SIZE       (0x3ffffff)
 
-#if defined(CONFIG_MPC85xx)
+#if defined(CONFIG_MPC83xx)
+#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN)
+#else
+#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT)
+#endif
+
+
+#if defined(CONFIG_MPC83xx)
+dma83xx_t *dma_base = (void *)(CONFIG_SYS_MPC83xx_DMA_ADDR);
+#elif defined(CONFIG_MPC85xx)
 ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR);
 #elif defined(CONFIG_MPC86xx)
 ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR);
@@ -50,17 +59,35 @@ static void dma_sync(void)
 #endif
 }
 
+static void out_dma32(volatile unsigned *addr, int val)
+{
+#if defined(CONFIG_MPC83xx)
+       out_le32(addr, val);
+#else
+       out_be32(addr, val);
+#endif
+}
+
+static uint in_dma32(volatile unsigned *addr)
+{
+#if defined(CONFIG_MPC83xx)
+       return in_le32(addr);
+#else
+       return in_be32(addr);
+#endif
+}
+
 static uint dma_check(void) {
        volatile fsl_dma_t *dma = &dma_base->dma[0];
        uint status;
 
        /* While the channel is busy, spin */
        do {
-               status = in_be32(&dma->sr);
+               status = in_dma32(&dma->sr);
        } while (status & FSL_DMA_SR_CB);
 
        /* clear MR[CS] channel start bit */
-       out_be32(&dma->mr, in_be32(&dma->mr) & ~FSL_DMA_MR_CS);
+       out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS);
        dma_sync();
 
        if (status != 0)
@@ -69,14 +96,16 @@ static uint dma_check(void) {
        return status;
 }
 
+#if !defined(CONFIG_MPC83xx)
 void dma_init(void) {
        volatile fsl_dma_t *dma = &dma_base->dma[0];
 
-       out_be32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
-       out_be32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
-       out_be32(&dma->sr, 0xffffffff); /* clear any errors */
+       out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
+       out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
+       out_dma32(&dma->sr, 0xffffffff); /* clear any errors */
        dma_sync();
 }
+#endif
 
 int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
        volatile fsl_dma_t *dma = &dma_base->dma[0];
@@ -85,18 +114,17 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
        while (count) {
                xfer_size = MIN(FSL_DMA_MAX_SIZE, count);
 
-               out_be32(&dma->dar, (uint) dest);
-               out_be32(&dma->sar, (uint) src);
-               out_be32(&dma->bcr, xfer_size);
+               out_dma32(&dma->dar, (uint) dest);
+               out_dma32(&dma->sar, (uint) src);
+               out_dma32(&dma->bcr, xfer_size);
+               dma_sync();
 
-               /* Disable bandwidth control, use direct transfer mode */
-               out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT);
+               /* Prepare mode register */
+               out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT);
                dma_sync();
 
                /* Start the transfer */
-               out_be32(&dma->mr, FSL_DMA_MR_BWC_DIS |
-                               FSL_DMA_MR_CTM_DIRECT |
-                               FSL_DMA_MR_CS);
+               out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS);
 
                count -= xfer_size;
                src += xfer_size;
@@ -111,7 +139,13 @@ int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
        return 0;
 }
 
-#if (defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER))
+/*
+ * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER
+ * while 83xx uses dma to initialize SDRAM when CONFIG_DDR_ECC_INIT_VIA_DMA
+ */
+#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&    \
+       !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) ||         \
+       (defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA)))
 void dma_meminit(uint val, uint size)
 {
        uint *p = 0;
index 9c358aa4135aae4f918639ce0b509080c63d13d0..ca143c7fef7aaf818864a6e468b7f5d07f7e8e23 100644 (file)
@@ -30,8 +30,9 @@
 #endif
 
 #ifndef CONFIG_FSL_DMA
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER) && \
-       (defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx))
+#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&    \
+       !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) ||         \
+       (defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA)))
 #define CONFIG_FSL_DMA
 #endif
 #endif
index 043669e4336e69ea9e49f981a369cc8e47681e43..11641912a65e5cb8a64aca4807b160c5566ebc5e 100644 (file)
 
 #include <asm/types.h>
 
+#ifdef CONFIG_MPC83xx
+typedef struct fsl_dma {
+       uint    mr;             /* DMA mode register */
+#define FSL_DMA_MR_CS          0x00000001      /* Channel start */
+#define FSL_DMA_MR_CC          0x00000002      /* Channel continue */
+#define FSL_DMA_MR_CTM         0x00000004      /* Channel xfer mode */
+#define FSL_DMA_MR_CTM_DIRECT  0x00000004      /* Direct channel xfer mode */
+#define FSL_DMA_MR_EOTIE       0x00000080      /* End-of-transfer interrupt en */
+#define FSL_DMA_MR_PRC_MASK    0x00000c00      /* PCI read command */
+#define FSL_DMA_MR_SAHE                0x00001000      /* Source addr hold enable */
+#define FSL_DMA_MR_DAHE                0x00002000      /* Dest addr hold enable */
+#define FSL_DMA_MR_SAHTS_MASK  0x0000c000      /* Source addr hold xfer size */
+#define FSL_DMA_MR_DAHTS_MASK  0x00030000      /* Dest addr hold xfer size */
+#define FSL_DMA_MR_EMS_EN      0x00040000      /* Ext master start en */
+#define FSL_DMA_MR_IRQS                0x00080000      /* Interrupt steer */
+#define FSL_DMA_MR_DMSEN       0x00100000      /* Direct mode snooping en */
+#define FSL_DMA_MR_BWC_MASK    0x00e00000      /* Bandwidth/pause ctl */
+#define FSL_DMA_MR_DRCNT       0x0f000000      /* DMA request count */
+       uint    sr;             /* DMA status register */
+#define FSL_DMA_SR_EOCDI       0x00000001      /* End-of-chain/direct interrupt */
+#define FSL_DMA_SR_EOSI                0x00000002      /* End-of-segment interrupt */
+#define FSL_DMA_SR_CB          0x00000004      /* Channel busy */
+#define FSL_DMA_SR_TE          0x00000080      /* Transfer error */
+       uint    cdar;           /* DMA current descriptor address register */
+       char    res0[4];
+       uint    sar;            /* DMA source address register */
+       char    res1[4];
+       uint    dar;            /* DMA destination address register */
+       char    res2[4];
+       uint    bcr;            /* DMA byte count register */
+       uint    ndar;           /* DMA next descriptor address register */
+       uint    gsr;            /* DMA general status register (DMA3 ONLY!) */
+       char    res3[84];
+} fsl_dma_t;
+#else
 typedef struct fsl_dma {
        uint    mr;             /* DMA mode register */
 #define FSL_DMA_MR_CS          0x00000001      /* Channel start */
@@ -93,6 +128,7 @@ typedef struct fsl_dma {
        uint    dsr;            /* DMA destination stride register */
        char    res4[56];
 } fsl_dma_t;
+#endif /* !CONFIG_MPC83xx */
 
 #ifdef CONFIG_FSL_DMA
 void dma_init(void);
index 8f945a15196f598ef57456acbad8a769aaa548eb..7c6a15185e1ef86bba0d7ea0508c6611d194cda6 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/fsl_i2c.h>
 #include <asm/mpc8xxx_spi.h>
 #include <asm/fsl_lbc.h>
+#include <asm/fsl_dma.h>
 
 /*
  * Local Access Window
@@ -367,51 +368,7 @@ typedef struct dma83xx {
        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 */
+       struct fsl_dma dma[4];
 } dma83xx_t;
 
 /*
@@ -895,6 +852,8 @@ typedef struct immap {
 } immap_t;
 #endif
 
+#define CONFIG_SYS_MPC83xx_DMA_OFFSET  (0x8000)
+#define CONFIG_SYS_MPC83xx_DMA_ADDR    (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
 #define CONFIG_SYS_MPC83xx_ESDHC_OFFSET        (0x2e000)
 #define CONFIG_SYS_MPC83xx_ESDHC_ADDR  (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
 #define CONFIG_SYS_MPC83xx_USB_OFFSET  0x23000
index c5bd6cb16ab064843d5fd63c7a433640445e6a7e..fd742c7809d493660c362bcfdc148024851502c1 100644 (file)
 #define ECC_ERROR_MAN_SBEC             (0xff000000>>24)        /* Single Bit Error Counter 0..255 */
 #define ECC_ERROR_MAN_SBEC_SHIFT       0
 
-/* DMAMR - DMA Mode Register
- */
-#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 */
-
-/* DMASR - DMA Status Register
- */
-#define DMA_CHANNEL_BUSY                       0x00000004      /* Bit - DMASRn CB */
-#define DMA_CHANNEL_TRANSFER_ERROR             0x00000080      /* Bit - DMASRn TE */
-
 /* CONFIG_ADDRESS - PCI Config Address Register
  */
 #define PCI_CONFIG_ADDRESS_EN          0x80000000