Patchwork [U-Boot,04/11] Blackfin: bf60x: add dma support

login
register
mail settings
Submitter Sonic Zhang
Date Feb. 7, 2013, 7:47 a.m.
Message ID <1360223258-6945-5-git-send-email-sonic.adi@gmail.com>
Download mbox | patch
Permalink /patch/218853/
State Superseded
Delegated to: Tom Rini
Headers show

Comments

Sonic Zhang - Feb. 7, 2013, 7:47 a.m.
From: Bob Liu <lliubbo@gmail.com>

Add dma support for bf60x.

Signed-off-by: Bob Liu <lliubbo@gmail.com>
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
---
 arch/blackfin/include/asm/dma.h                  |  113 ++++++++++++----------
 arch/blackfin/include/asm/mach-common/bits/dma.h |   48 +++++++++-
 arch/blackfin/lib/string.c                       |   97 ++++++++++---------
 3 files changed, 159 insertions(+), 99 deletions(-)
Wolfgang Denk - Feb. 7, 2013, 10:11 a.m.
Dear Sonic Zhang,

In message <1360223258-6945-5-git-send-email-sonic.adi@gmail.com> you wrote:
> From: Bob Liu <lliubbo@gmail.com>
> 
> Add dma support for bf60x.
> 
> Signed-off-by: Bob Liu <lliubbo@gmail.com>
> Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
> ---
>  arch/blackfin/include/asm/dma.h                  |  113 ++++++++++++----------
>  arch/blackfin/include/asm/mach-common/bits/dma.h |   48 +++++++++-
>  arch/blackfin/lib/string.c                       |   97 ++++++++++---------
>  3 files changed, 159 insertions(+), 99 deletions(-)

There are checkpatch errors and warnings.  Please fix these!!


>  struct dmasg_large {
>  	void *next_desc_addr;
> -	unsigned long start_addr;
> -	unsigned short cfg;
> -	unsigned short x_count;
> -	short x_modify;
> -	unsigned short y_count;
> -	short y_modify;
> +	u32 start_addr;
> +	u16 cfg;
> +	u16 x_count;
> +	s16 x_modify;
> +	u16 y_count;
> +	s16 y_modify;
>  } __attribute__((packed));
>  
>  struct dmasg {
> -	unsigned long start_addr;
> -	unsigned short cfg;
> -	unsigned short x_count;
> -	short x_modify;
> -	unsigned short y_count;
> -	short y_modify;
> +	u32 start_addr;
> +	u16 cfg;
> +	u16 x_count;
> +	s16 x_modify;
> +	u16 y_count;
> +	s16 y_modify;
>  } __attribute__((packed));

These appear totally unrelated changes.  These should be split out
into separate patches.

> +/*
> + * All Blackfin system MMRs are padded to 32bits even if the register
> + * itself is only 16bits.  So use a helper macro to streamline this.
> + */
> +#define __BFP(m) m; u16 __pad_##m
>  struct dma_register {
> -	void *next_desc_ptr;	/* DMA Next Descriptor Pointer register */
> -	unsigned long start_addr;	/* DMA Start address  register */
> -
> -	unsigned short cfg;	/* DMA Configuration register */
> -	unsigned short dummy1;	/* DMA Configuration register */
> -
> -	unsigned long reserved;
> -
> -	unsigned short x_count;	/* DMA x_count register */
> -	unsigned short dummy2;
> -
> -	short x_modify;	/* DMA x_modify register */
> -	unsigned short dummy3;
> -
> -	unsigned short y_count;	/* DMA y_count register */
> -	unsigned short dummy4;
> -
> -	short y_modify;	/* DMA y_modify register */
> -	unsigned short 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;
> -
> -	unsigned short peripheral_map;	/* DMA peripheral map register */
> -	unsigned short dummy7;
> -
> -	unsigned short curr_x_count;	/* DMA Current x-count register */
> -	unsigned short dummy8;
> -
> -	unsigned long reserved2;
> -
> -	unsigned short curr_y_count;	/* DMA Current y-count register */
> -	unsigned short dummy9;
> -
> -	unsigned long reserved3;
> -
> +#ifdef __ADSPBF60x__
> +	void *next_desc_ptr;
> +	u32 start_addr;
> +	u32 config;

You drop all the comments; please don't do that.

Also, "cfg" used to be a short, now it gets replaced by "config" which
is a u32.  Is this correct?

> +	void *next_desc_ptr;
> +	u32 start_addr;
> +	u16 __BFP(config);
> +	u32 __pad0;
> +	u16 __BFP(x_count);
> +	s16 __BFP(x_modify);
> +	u16 __BFP(y_count);
> +	s16 __BFP(y_modify);
> +	void *curr_desc_ptr;
> +	u32 curr_addr_ptr;
> +	u16 __BFP(status);
> +	u16 __BFP(peripheral_map);
> +	u16 __BFP(curr_x_count);
> +	u32 __pad1;
> +	u16 __BFP(curr_y_count);
> +	u32 __pad2;

Sorry, but this is unreadable.  NAK.


Best regards,

Wolfgang Denk
Sonic Zhang - Feb. 8, 2013, 4:17 a.m.
On Thu, Feb 7, 2013 at 6:11 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Sonic Zhang,
>
> In message <1360223258-6945-5-git-send-email-sonic.adi@gmail.com> you wrote:
>> From: Bob Liu <lliubbo@gmail.com>
>>
>> Add dma support for bf60x.
>>
>> Signed-off-by: Bob Liu <lliubbo@gmail.com>
>> Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
>> ---
>>  arch/blackfin/include/asm/dma.h                  |  113 ++++++++++++----------
>>  arch/blackfin/include/asm/mach-common/bits/dma.h |   48 +++++++++-
>>  arch/blackfin/lib/string.c                       |   97 ++++++++++---------
>>  3 files changed, 159 insertions(+), 99 deletions(-)
>
> There are checkpatch errors and warnings.  Please fix these!!
>

No problem.

>
>>  struct dmasg_large {
>>       void *next_desc_addr;
>> -     unsigned long start_addr;
>> -     unsigned short cfg;
>> -     unsigned short x_count;
>> -     short x_modify;
>> -     unsigned short y_count;
>> -     short y_modify;
>> +     u32 start_addr;
>> +     u16 cfg;
>> +     u16 x_count;
>> +     s16 x_modify;
>> +     u16 y_count;
>> +     s16 y_modify;
>>  } __attribute__((packed));
>>
>>  struct dmasg {
>> -     unsigned long start_addr;
>> -     unsigned short cfg;
>> -     unsigned short x_count;
>> -     short x_modify;
>> -     unsigned short y_count;
>> -     short y_modify;
>> +     u32 start_addr;
>> +     u16 cfg;
>> +     u16 x_count;
>> +     s16 x_modify;
>> +     u16 y_count;
>> +     s16 y_modify;
>>  } __attribute__((packed));
>
> These appear totally unrelated changes.  These should be split out
> into separate patches.
>

OK, I will move these changes out as a new patch.

>> +/*
>> + * All Blackfin system MMRs are padded to 32bits even if the register
>> + * itself is only 16bits.  So use a helper macro to streamline this.
>> + */
>> +#define __BFP(m) m; u16 __pad_##m
>>  struct dma_register {
>> -     void *next_desc_ptr;    /* DMA Next Descriptor Pointer register */
>> -     unsigned long start_addr;       /* DMA Start address  register */
>> -
>> -     unsigned short cfg;     /* DMA Configuration register */
>> -     unsigned short dummy1;  /* DMA Configuration register */
>> -
>> -     unsigned long reserved;
>> -
>> -     unsigned short x_count; /* DMA x_count register */
>> -     unsigned short dummy2;
>> -
>> -     short x_modify; /* DMA x_modify register */
>> -     unsigned short dummy3;
>> -
>> -     unsigned short y_count; /* DMA y_count register */
>> -     unsigned short dummy4;
>> -
>> -     short y_modify; /* DMA y_modify register */
>> -     unsigned short 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;
>> -
>> -     unsigned short peripheral_map;  /* DMA peripheral map register */
>> -     unsigned short dummy7;
>> -
>> -     unsigned short curr_x_count;    /* DMA Current x-count register */
>> -     unsigned short dummy8;
>> -
>> -     unsigned long reserved2;
>> -
>> -     unsigned short curr_y_count;    /* DMA Current y-count register */
>> -     unsigned short dummy9;
>> -
>> -     unsigned long reserved3;
>> -
>> +#ifdef __ADSPBF60x__
>> +     void *next_desc_ptr;
>> +     u32 start_addr;
>> +     u32 config;
>
> You drop all the comments; please don't do that.
>
> Also, "cfg" used to be a short, now it gets replaced by "config" which
> is a u32.  Is this correct?

Yes, this is correct for BF60x. The DMA config MMR on BF60x is 32 bits
while it is 16 bits on BF5xx.

>
>> +     void *next_desc_ptr;
>> +     u32 start_addr;
>> +     u16 __BFP(config);
>> +     u32 __pad0;
>> +     u16 __BFP(x_count);
>> +     s16 __BFP(x_modify);
>> +     u16 __BFP(y_count);
>> +     s16 __BFP(y_modify);
>> +     void *curr_desc_ptr;
>> +     u32 curr_addr_ptr;
>> +     u16 __BFP(status);
>> +     u16 __BFP(peripheral_map);
>> +     u16 __BFP(curr_x_count);
>> +     u32 __pad1;
>> +     u16 __BFP(curr_y_count);
>> +     u32 __pad2;
>
> Sorry, but this is unreadable.  NAK.
>

OK, I will change back to the former definition style.


Sonic Zhang

Patch

diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
index 21ff1cf..211719a 100644
--- a/arch/blackfin/include/asm/dma.h
+++ b/arch/blackfin/include/asm/dma.h
@@ -8,68 +8,77 @@ 
 #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;
-	unsigned long start_addr;
-	unsigned short cfg;
-	unsigned short x_count;
-	short x_modify;
-	unsigned short y_count;
-	short y_modify;
+	u32 start_addr;
+	u16 cfg;
+	u16 x_count;
+	s16 x_modify;
+	u16 y_count;
+	s16 y_modify;
 } __attribute__((packed));
 
 struct dmasg {
-	unsigned long start_addr;
-	unsigned short cfg;
-	unsigned short x_count;
-	short x_modify;
-	unsigned short y_count;
-	short y_modify;
+	u32 start_addr;
+	u16 cfg;
+	u16 x_count;
+	s16 x_modify;
+	u16 y_count;
+	s16 y_modify;
 } __attribute__((packed));
 
+/*
+ * All Blackfin system MMRs are padded to 32bits even if the register
+ * itself is only 16bits.  So use a helper macro to streamline this.
+ */
+#define __BFP(m) m; u16 __pad_##m
 struct dma_register {
-	void *next_desc_ptr;	/* DMA Next Descriptor Pointer register */
-	unsigned long start_addr;	/* DMA Start address  register */
-
-	unsigned short cfg;	/* DMA Configuration register */
-	unsigned short dummy1;	/* DMA Configuration register */
-
-	unsigned long reserved;
-
-	unsigned short x_count;	/* DMA x_count register */
-	unsigned short dummy2;
-
-	short x_modify;	/* DMA x_modify register */
-	unsigned short dummy3;
-
-	unsigned short y_count;	/* DMA y_count register */
-	unsigned short dummy4;
-
-	short y_modify;	/* DMA y_modify register */
-	unsigned short 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;
-
-	unsigned short peripheral_map;	/* DMA peripheral map register */
-	unsigned short dummy7;
-
-	unsigned short curr_x_count;	/* DMA Current x-count register */
-	unsigned short dummy8;
-
-	unsigned long reserved2;
-
-	unsigned short curr_y_count;	/* DMA Current y-count register */
-	unsigned short dummy9;
-
-	unsigned long reserved3;
-
+#ifdef __ADSPBF60x__
+	void *next_desc_ptr;
+	u32 start_addr;
+	u32 config;
+	u32 x_count;
+	s32 x_modify;
+	u32 y_count;
+	s32 y_modify;
+	u32 __pad0[2];
+	void *curr_desc_ptr;
+	void *prev_desc_ptr;
+	void *curr_addr;
+	u32 status;
+	u32 curr_x_count;
+	u32 curr_y_count;
+	u32 __pad1[2];
+	u32 bw_limit;
+	u32 curr_bw_limit;
+	u32 bw_monitor;
+	u32 curr_bw_monitor;
+#else
+	void *next_desc_ptr;
+	u32 start_addr;
+	u16 __BFP(config);
+	u32 __pad0;
+	u16 __BFP(x_count);
+	s16 __BFP(x_modify);
+	u16 __BFP(y_count);
+	s16 __BFP(y_modify);
+	void *curr_desc_ptr;
+	u32 curr_addr_ptr;
+	u16 __BFP(status);
+	u16 __BFP(peripheral_map);
+	u16 __BFP(curr_x_count);
+	u32 __pad1;
+	u16 __BFP(curr_y_count);
+	u32 __pad2;
+#endif
 };
+#undef __BFP
 
 #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..1126c44 100644
--- a/arch/blackfin/include/asm/mach-common/bits/dma.h
+++ b/arch/blackfin/include/asm/mach-common/bits/dma.h
@@ -9,8 +9,48 @@ 
 #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 Interrupt Enable in X count */
+#define DI_EN_Y			0x00200000	/* Data Interrupt Enable in Y count */
+#define DI_EN_P			0x00300000	/* Data Interrupt Enable in Peripheral */
+#define DI_EN			DI_EN_X		/* Data Interrupt Enable */
+#define NDSIZE_0		0x00000000	/* Next Descriptor Size = 0 (Stop/Autobuffer) */
+#define NDSIZE_1		0x00010000	/* Next Descriptor Size = 1 */
+#define NDSIZE_2		0x00020000	/* Next Descriptor Size = 2 */
+#define NDSIZE_3		0x00030000	/* Next Descriptor Size = 3 */
+#define NDSIZE_4		0x00040000	/* Next Descriptor Size = 4 */
+#define NDSIZE_5		0x00050000	/* Next Descriptor Size = 5 */
+#define NDSIZE_6		0x00060000	/* Next Descriptor Size = 6 */
+#define NDSIZE			0x00070000	/* Next Descriptor Size */
+#define NDSIZE_OFFSET		16		/* Next Descriptor Size Offset */
+#define DMAFLOW_LIST		0x00004000	/* Descriptor List Mode */
+#define DMAFLOW_ARRAY		0x00005000	/* Descriptor Array Mode */
+#define DMAFLOW_LIST_DEMAND	0x00006000	/* Descriptor Demand List Mode */
+#define DMAFLOW_ARRAY_DEMAND	0x00007000	/* Descriptor Demand Array Mode */
+#define DMA_RUN_DFETCH		0x00000100	/* DMA Channel Running Indicator (DFETCH) */
+#define DMA_RUN			0x00000200	/* DMA Channel Running Indicator */
+#define DMA_RUN_WAIT_TRIG	0x00000300	/* DMA Channel Running Indicator (WAIT TRIG) */
+#define DMA_RUN_WAIT_ACK	0x00000400	/* DMA Channel Running Indicator (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 */
@@ -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,6 +84,11 @@ 
 #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 */
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