From: Bob Liu <lliu...@gmail.com>

Add dma support for bf60x.

Fix review issues from Wolfgang:
1) Fix all checkpatch issues.
2) Remove unrelated dma structure change to separate patch.
3) The DMA config MMR on BF60x is 32 bits while it is 16 bits on BF5xx.
The different type of config MMR is correct.
4) Replace unreable macro in dma structures with normal types.

Signed-off-by: Bob Liu <lliu...@gmail.com>
Signed-off-by: Sonic Zhang <sonic.zh...@analog.com>
---
 arch/blackfin/include/asm/dma.h                  |   81 ++++++++++++------
 arch/blackfin/include/asm/mach-common/bits/dma.h |   54 +++++++++++-
 arch/blackfin/lib/string.c                       |   97 ++++++++++++----------
 3 files changed, 156 insertions(+), 76 deletions(-)

diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
index 21ff1cf..ef1db6e 100644
--- a/arch/blackfin/include/asm/dma.h
+++ b/arch/blackfin/include/asm/dma.h
@@ -8,7 +8,12 @@
 #ifndef _BLACKFIN_DMA_H_
 #define _BLACKFIN_DMA_H_
 
+#include <linux/types.h>
+#ifdef __ADSPBF60x__
+#include <asm/mach-common/bits/dde.h>
+#else
 #include <asm/mach-common/bits/dma.h>
+#endif
 
 struct dmasg_large {
        void *next_desc_addr;
@@ -30,46 +35,70 @@ struct dmasg {
 } __attribute__((packed));
 
 struct dma_register {
+#ifdef __ADSPBF60x__
+       void *next_desc_ptr;    /* DMA Next Descriptor Pointer register */
+       u32 start_addr;         /* DMA Start address  register */
+       u32 config;             /* DMA Configuration register */
+
+       u32 x_count;            /* DMA x_count register */
+       s32 x_modify;           /* DMA x_modify register */
+       u32 y_count;            /* DMA y_count register */
+       s32 y_modify;           /* DMA y_modify register */
+       u32 __pad0[2];
+
+       void *curr_desc_ptr;    /* DMA Curr Descriptor Pointer register */
+       void *prev_desc_ptr;    /* DMA Prev Descriptor Pointer register */
+       void *curr_addr;        /* DMA Current Address Pointer register */
+       u32 status;             /* DMA irq status register */
+       u32 curr_x_count;       /* DMA Current x-count register */
+       u32 curr_y_count;       /* DMA Current y-count register */
+       u32 __pad1[2];
+
+       u32 bw_limit;           /* DMA Bandwidth Limit Count */
+       u32 curr_bw_limit;      /* DMA curr Bandwidth Limit Count */
+       u32 bw_monitor;         /* DMA Bandwidth Monitor Count */
+       u32 curr_bw_monitor;    /* DMA curr Bandwidth Monitor Count */
+#else
        void *next_desc_ptr;    /* DMA Next Descriptor Pointer register */
-       unsigned long start_addr;       /* DMA Start address  register */
+       u32 start_addr;         /* DMA Start address  register */
 
-       unsigned short cfg;     /* DMA Configuration register */
-       unsigned short dummy1;  /* DMA Configuration register */
+       u16 config;             /* DMA Configuration register */
+       u16 dummy1;             /* DMA Configuration register */
 
-       unsigned long reserved;
+       u32 reserved;
 
-       unsigned short x_count; /* DMA x_count register */
-       unsigned short dummy2;
+       u16 x_count;            /* DMA x_count register */
+       u16 dummy2;
 
-       short x_modify; /* DMA x_modify register */
-       unsigned short dummy3;
+       s16 x_modify;           /* DMA x_modify register */
+       u16 dummy3;
 
-       unsigned short y_count; /* DMA y_count register */
-       unsigned short dummy4;
+       u16 y_count;            /* DMA y_count register */
+       u16 dummy4;
 
-       short y_modify; /* DMA y_modify register */
-       unsigned short dummy5;
+       s16 y_modify;           /* DMA y_modify register */
+       u16 dummy5;
 
-       void *curr_desc_ptr;    /* DMA Current Descriptor Pointer
-                                          register */
-       unsigned long curr_addr_ptr;    /* DMA Current Address Pointer
-                                                  register */
-       unsigned short irq_status;      /* DMA irq status register */
-       unsigned short dummy6;
+       void *curr_desc_ptr;    /* DMA Current Descriptor Pointer register */
 
-       unsigned short peripheral_map;  /* DMA peripheral map register */
-       unsigned short dummy7;
+       u32 curr_addr_ptr;      /* DMA Current Address Pointer register */
 
-       unsigned short curr_x_count;    /* DMA Current x-count register */
-       unsigned short dummy8;
+       u16 status;             /* DMA irq status register */
+       u16 dummy6;
 
-       unsigned long reserved2;
+       u16 peripheral_map;     /* DMA peripheral map register */
+       u16 dummy7;
 
-       unsigned short curr_y_count;    /* DMA Current y-count register */
-       unsigned short dummy9;
+       u16 curr_x_count;       /* DMA Current x-count register */
+       u16 dummy8;
 
-       unsigned long reserved3;
+       u32 reserved2;
 
+       u16 curr_y_count;       /* DMA Current y-count register */
+       u16 dummy9;
+
+       u32 reserved3;
+#endif
 };
 
 #endif
diff --git a/arch/blackfin/include/asm/mach-common/bits/dma.h 
b/arch/blackfin/include/asm/mach-common/bits/dma.h
index 136313e..ac426ad 100644
--- a/arch/blackfin/include/asm/mach-common/bits/dma.h
+++ b/arch/blackfin/include/asm/mach-common/bits/dma.h
@@ -9,14 +9,54 @@
 #define DMAEN                  0x0001  /* DMA Channel Enable */
 #define WNR                    0x0002  /* Channel Direction (W/R*) */
 #define WDSIZE_8               0x0000  /* Transfer Word Size = 8 */
+
+#ifdef CONFIG_BF60x
+
+#define PSIZE_8                        0x00000000      /* Transfer Word Size = 
16 */
+#define PSIZE_16               0x00000010      /* Transfer Word Size = 16 */
+#define PSIZE_32               0x00000020      /* Transfer Word Size = 32 */
+#define PSIZE_64               0x00000030      /* Transfer Word Size = 32 */
+#define WDSIZE_16              0x00000100      /* Transfer Word Size = 16 */
+#define WDSIZE_32              0x00000200      /* Transfer Word Size = 32 */
+#define WDSIZE_64              0x00000300      /* Transfer Word Size = 32 */
+#define WDSIZE_128             0x00000400      /* Transfer Word Size = 32 */
+#define WDSIZE_256             0x00000500      /* Transfer Word Size = 32 */
+#define DMA2D                  0x04000000      /* DMA Mode (2D/1D*) */
+#define RESTART                        0x00000004      /* DMA Buffer Clear 
SYNC */
+#define DI_EN_X                        0x00100000      /* Data Int Enable in X 
count */
+#define DI_EN_Y                        0x00200000      /* Data Int Enable in Y 
count */
+#define DI_EN_P                        0x00300000      /* Data Int Enable in 
Peri */
+#define DI_EN                  DI_EN_X         /* Data Int Enable */
+#define NDSIZE_0               0x00000000      /* Next Desc Size = 0 */
+#define NDSIZE_1               0x00010000      /* Next Desc Size = 1 */
+#define NDSIZE_2               0x00020000      /* Next Desc Size = 2 */
+#define NDSIZE_3               0x00030000      /* Next Desc Size = 3 */
+#define NDSIZE_4               0x00040000      /* Next Desc Size = 4 */
+#define NDSIZE_5               0x00050000      /* Next Desc Size = 5 */
+#define NDSIZE_6               0x00060000      /* Next Desc Size = 6 */
+#define NDSIZE                 0x00070000      /* Next Desc Size */
+#define NDSIZE_OFFSET          16              /* Next Desc Size Offset */
+#define DMAFLOW_LIST           0x00004000      /* Desc List Mode */
+#define DMAFLOW_ARRAY          0x00005000      /* Desc Array Mode */
+#define DMAFLOW_LIST_DEMAND    0x00006000      /* Desc Demand List Mode */
+#define DMAFLOW_ARRAY_DEMAND   0x00007000      /* Desc Demand Array Mode */
+#define DMA_RUN_DFETCH         0x00000100      /* DMA Channel Run (DFETCH) */
+#define DMA_RUN                        0x00000200      /* DMA Channel Run */
+#define DMA_RUN_WAIT_TRIG      0x00000300      /* DMA Channel Run (WAIT TRIG)*/
+#define DMA_RUN_WAIT_ACK       0x00000400      /* DMA Channel Run (WAIT ACK) */
+
+#else
+
 #define WDSIZE_16              0x0004  /* Transfer Word Size = 16 */
 #define WDSIZE_32              0x0008  /* Transfer Word Size = 32 */
+#define PSIZE_16               WDSIZE_16
+#define PSIZE_32               WDSIZE_32
 #define DMA2D                  0x0010  /* DMA Mode (2D/1D*) */
 #define RESTART                        0x0020  /* DMA Buffer Clear */
 #define DI_SEL                 0x0040  /* Data Interrupt Timing Select */
 #define DI_EN                  0x0080  /* Data Interrupt Enable */
 #define NDSIZE                 0x0F00  /* Next Descriptor bitmask */
-#define NDSIZE_0               0x0000  /* Next Descriptor Size = 0 
(Stop/Autobuffer) */
+#define NDSIZE_0               0x0000  /* Next Descriptor Size = 0 */
 #define NDSIZE_1               0x0100  /* Next Descriptor Size = 1 */
 #define NDSIZE_2               0x0200  /* Next Descriptor Size = 2 */
 #define NDSIZE_3               0x0300  /* Next Descriptor Size = 3 */
@@ -26,14 +66,13 @@
 #define NDSIZE_7               0x0700  /* Next Descriptor Size = 7 */
 #define NDSIZE_8               0x0800  /* Next Descriptor Size = 8 */
 #define NDSIZE_9               0x0900  /* Next Descriptor Size = 9 */
-#define FLOW_STOP              0x0000  /* Stop Mode */
-#define FLOW_AUTO              0x1000  /* Autobuffer Mode */
 #define FLOW_ARRAY             0x4000  /* Descriptor Array Mode */
 #define FLOW_SMALL             0x6000  /* Small Model Descriptor List Mode */
 #define FLOW_LARGE             0x7000  /* Large Model Descriptor List Mode */
 
 #define DMAEN_P                        0       /* Channel Enable */
 #define WNR_P                  1       /* Channel Direction (W/R*) */
+#define WDSIZE_P               2       /* Transfer Word Size */
 #define DMA2D_P                        4       /* 2D/1D* Mode */
 #define RESTART_P              5       /* Restart */
 #define DI_SEL_P               6       /* Data Interrupt Select */
@@ -45,14 +84,19 @@
 #define DFETCH                 0x0004  /* DMA Descriptor Fetch Indicator */
 #define DMA_RUN                        0x0008  /* DMA Channel Running 
Indicator */
 
+#endif
+#define DMAFLOW                        0x7000  /* Flow Control */
+#define FLOW_STOP              0x0000  /* Stop Mode */
+#define FLOW_AUTO              0x1000  /* Autobuffer Mode */
+
 #define DMA_DONE_P             0       /* DMA Done Indicator */
 #define DMA_ERR_P              1       /* DMA Error Indicator */
 #define DFETCH_P               2       /* Descriptor Fetch Indicator */
 #define DMA_RUN_P              3       /* DMA Running Indicator */
 
 /* DMAx_PERIPHERAL_MAP, MDMA_yy_PERIPHERAL_MAP Masks */
-#define CTYPE                  0x0040  /* DMA Channel Type Indicator 
(Memory/Peripheral*) */
-#define CTYPE_P                        6       /* DMA Channel Type Indicator 
BIT POSITION */
+#define CTYPE                  0x0040  /* DMA Channel Type (Mem/Peri) */
+#define CTYPE_P                        6       /* DMA Channel Type BIT 
POSITION */
 #define PMAP                   0xF000  /* Peripheral Mapped To This Channel */
 
 #endif
diff --git a/arch/blackfin/lib/string.c b/arch/blackfin/lib/string.c
index e344d3b..44d8c6d 100644
--- a/arch/blackfin/lib/string.c
+++ b/arch/blackfin/lib/string.c
@@ -29,7 +29,7 @@
 #include <config.h>
 #include <asm/blackfin.h>
 #include <asm/io.h>
-#include <asm/mach-common/bits/dma.h>
+#include <asm/dma.h>
 
 char *strcpy(char *dest, const char *src)
 {
@@ -117,81 +117,88 @@ int strncmp(const char *cs, const char *ct, size_t count)
        return __res1;
 }
 
-#ifdef bfin_write_MDMA1_D0_IRQ_STATUS
-# define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS
-# define bfin_write_MDMA_D0_START_ADDR bfin_write_MDMA1_D0_START_ADDR
-# define bfin_write_MDMA_D0_X_COUNT    bfin_write_MDMA1_D0_X_COUNT
-# define bfin_write_MDMA_D0_X_MODIFY   bfin_write_MDMA1_D0_X_MODIFY
-# define bfin_write_MDMA_D0_CONFIG     bfin_write_MDMA1_D0_CONFIG
-# define bfin_write_MDMA_S0_START_ADDR bfin_write_MDMA1_S0_START_ADDR
-# define bfin_write_MDMA_S0_X_COUNT    bfin_write_MDMA1_S0_X_COUNT
-# define bfin_write_MDMA_S0_X_MODIFY   bfin_write_MDMA1_S0_X_MODIFY
-# define bfin_write_MDMA_S0_CONFIG     bfin_write_MDMA1_S0_CONFIG
-# define bfin_write_MDMA_D0_IRQ_STATUS bfin_write_MDMA1_D0_IRQ_STATUS
-# define bfin_read_MDMA_D0_IRQ_STATUS  bfin_read_MDMA1_D0_IRQ_STATUS
+#ifdef MDMA1_D0_NEXT_DESC_PTR
+# define MDMA_D0_NEXT_DESC_PTR MDMA1_D0_NEXT_DESC_PTR
+# define MDMA_S0_NEXT_DESC_PTR MDMA1_S0_NEXT_DESC_PTR
 #endif
+
+static void dma_calc_size(unsigned long ldst, unsigned long lsrc, size_t count,
+                       unsigned long *dshift, unsigned long *bpos)
+{
+       unsigned long limit;
+
+#ifdef MSIZE
+       limit = 6;
+       *dshift = MSIZE_P;
+#else
+       limit = 3;
+       *dshift = WDSIZE_P;
+#endif
+
+       *bpos = min(limit, ffs(ldst | lsrc | count)) - 1;
+}
+
 /* This version misbehaves for count values of 0 and 2^16+.
  * Perhaps we should detect that ?  Nowhere do we actually
  * use dma memcpy for those types of lengths though ...
  */
 void dma_memcpy_nocache(void *dst, const void *src, size_t count)
 {
-       uint16_t wdsize, mod;
+       struct dma_register *mdma_d0 = (void *)MDMA_D0_NEXT_DESC_PTR;
+       struct dma_register *mdma_s0 = (void *)MDMA_S0_NEXT_DESC_PTR;
+       unsigned long ldst = (unsigned long)dst;
+       unsigned long lsrc = (unsigned long)src;
+       unsigned long dshift, bpos;
+       uint32_t dsize, mod;
 
        /* Disable DMA in case it's still running (older u-boot's did not
         * always turn them off).  Do it before the if statement below so
         * we can be cheap and not do a SSYNC() due to the forced abort.
         */
-       bfin_write_MDMA_D0_CONFIG(0);
-       bfin_write_MDMA_S0_CONFIG(0);
-       bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
+       bfin_write(&mdma_d0->config, 0);
+       bfin_write(&mdma_s0->config, 0);
+       bfin_write(&mdma_d0->status, DMA_RUN | DMA_DONE | DMA_ERR);
 
        /* Scratchpad cannot be a DMA source or destination */
-       if (((unsigned long)src >= L1_SRAM_SCRATCH &&
-            (unsigned long)src < L1_SRAM_SCRATCH_END) ||
-           ((unsigned long)dst >= L1_SRAM_SCRATCH &&
-            (unsigned long)dst < L1_SRAM_SCRATCH_END))
+       if ((lsrc >= L1_SRAM_SCRATCH && lsrc < L1_SRAM_SCRATCH_END) ||
+           (ldst >= L1_SRAM_SCRATCH && ldst < L1_SRAM_SCRATCH_END))
                hang();
 
-       if (((unsigned long)dst | (unsigned long)src | count) & 0x1) {
-               wdsize = WDSIZE_8;
-               mod = 1;
-       } else if (((unsigned long)dst | (unsigned long)src | count) & 0x2) {
-               wdsize = WDSIZE_16;
-               count >>= 1;
-               mod = 2;
-       } else {
-               wdsize = WDSIZE_32;
-               count >>= 2;
-               mod = 4;
-       }
+       dma_calc_size(ldst, lsrc, count, &dshift, &bpos);
+       dsize = bpos << dshift;
+       count >>= bpos;
+       mod = 1 << bpos;
+
+#ifdef PSIZE
+       dsize |= min(3, bpos) << PSIZE_P;
+#endif
 
        /* Copy sram functions from sdram to sram */
        /* Setup destination start address */
-       bfin_write_MDMA_D0_START_ADDR(dst);
+       bfin_write(&mdma_d0->start_addr, ldst);
        /* Setup destination xcount */
-       bfin_write_MDMA_D0_X_COUNT(count);
+       bfin_write(&mdma_d0->x_count, count);
        /* Setup destination xmodify */
-       bfin_write_MDMA_D0_X_MODIFY(mod);
+       bfin_write(&mdma_d0->x_modify, mod);
 
        /* Setup Source start address */
-       bfin_write_MDMA_S0_START_ADDR(src);
+       bfin_write(&mdma_s0->start_addr, lsrc);
        /* Setup Source xcount */
-       bfin_write_MDMA_S0_X_COUNT(count);
+       bfin_write(&mdma_s0->x_count, count);
        /* Setup Source xmodify */
-       bfin_write_MDMA_S0_X_MODIFY(mod);
+       bfin_write(&mdma_s0->x_modify, mod);
 
        /* Enable source DMA */
-       bfin_write_MDMA_S0_CONFIG(wdsize | DMAEN);
-       bfin_write_MDMA_D0_CONFIG(wdsize | DMAEN | WNR | DI_EN);
+       bfin_write(&mdma_s0->config, dsize | DMAEN);
+       bfin_write(&mdma_d0->config, dsize | DMAEN | WNR | DI_EN);
        SSYNC();
 
-       while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
+       while (!(bfin_read(&mdma_d0->status) & DMA_DONE))
                continue;
 
-       bfin_write_MDMA_D0_IRQ_STATUS(DMA_RUN | DMA_DONE | DMA_ERR);
-       bfin_write_MDMA_D0_CONFIG(0);
-       bfin_write_MDMA_S0_CONFIG(0);
+       bfin_write(&mdma_d0->status, DMA_RUN | DMA_DONE | DMA_ERR);
+       bfin_write(&mdma_d0->config, 0);
+       bfin_write(&mdma_s0->config, 0);
 }
 /* We should do a dcache invalidate on the destination after the dma, but since
  * we lack such hardware capability, we'll flush/invalidate the destination
-- 
1.7.0.4


_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to