Commit 623b4ac4 authored by Guennadi Liakhovetski's avatar Guennadi Liakhovetski Committed by Paul Mundt

sh: fix Transfer Size calculation in both DMA drivers

Both the original arch/sh/drivers/dma/dma-sh.c and the new SH dmaengine drivers
do not take into account bits 3:2 of the Transfer Size field in the CHCR
register, besides, bit-field defines set bit 2, but the mask only passes bits
1:0 through. TS_16BLK and TS_32BLK macros are bogus too. This patch fixes all
these issues for sh7722 and sh7724, other CPUs stay unchanged and might need to
be fixed too.
Signed-off-by: default avatarGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent fc461857
...@@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan) ...@@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan)
* *
* iterations to complete the transfer. * iterations to complete the transfer.
*/ */
static unsigned int ts_shift[] = TS_SHIFT;
static inline unsigned int calc_xmit_shift(struct dma_channel *chan) static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
{ {
u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; return ts_shift[cnt];
} }
/* /*
......
...@@ -83,7 +83,7 @@ static int dmte_irq_map[] __maybe_unused = { ...@@ -83,7 +83,7 @@ static int dmte_irq_map[] __maybe_unused = {
* Define the default configuration for dual address memory-memory transfer. * Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external. * The 0x400 value represents auto-request, external->external.
*/ */
#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) #define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
/* DMA base address */ /* DMA base address */
static u32 dma_base_addr[] __maybe_unused = { static u32 dma_base_addr[] __maybe_unused = {
......
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
#define TS_32 0x00000010 #define TS_32 0x00000010
#define TS_128 0x00000018 #define TS_128 0x00000018
#define CHCR_TS_MASK 0x18 #define CHCR_TS_LOW_MASK 0x18
#define CHCR_TS_SHIFT 3 #define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#define DMAOR_INIT DMAOR_DME #define DMAOR_INIT DMAOR_DME
...@@ -36,11 +38,13 @@ enum { ...@@ -36,11 +38,13 @@ enum {
XMIT_SZ_128BIT, XMIT_SZ_128BIT,
}; };
static unsigned int ts_shift[] __maybe_unused = { #define TS_SHIFT { \
[XMIT_SZ_8BIT] = 0, [XMIT_SZ_8BIT] = 0, \
[XMIT_SZ_16BIT] = 1, [XMIT_SZ_16BIT] = 1, \
[XMIT_SZ_32BIT] = 2, [XMIT_SZ_32BIT] = 2, \
[XMIT_SZ_128BIT] = 4, [XMIT_SZ_128BIT] = 4, \
}; }
#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
#endif /* __ASM_CPU_SH3_DMA_H */ #endif /* __ASM_CPU_SH3_DMA_H */
...@@ -2,13 +2,26 @@ ...@@ -2,13 +2,26 @@
#define __ASM_SH_CPU_SH4_DMA_SH7780_H #define __ASM_SH_CPU_SH4_DMA_SH7780_H
#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \ #if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
defined(CONFIG_CPU_SUBTYPE_SH7722) || \
defined(CONFIG_CPU_SUBTYPE_SH7730) defined(CONFIG_CPU_SUBTYPE_SH7730)
#define DMTE0_IRQ 48 #define DMTE0_IRQ 48
#define DMTE4_IRQ 76 #define DMTE4_IRQ 76
#define DMAE0_IRQ 78 /* DMA Error IRQ*/ #define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE0 0xFE008020
#define SH_DMARS_BASE 0xFE009000 #define SH_DMARS_BASE 0xFE009000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
#define DMTE0_IRQ 48
#define DMTE4_IRQ 76
#define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMARS_BASE 0xFE009000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0x00300000
#define CHCR_TS_HIGH_SHIFT 20
#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ #elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
defined(CONFIG_CPU_SUBTYPE_SH7764) defined(CONFIG_CPU_SUBTYPE_SH7764)
#define DMTE0_IRQ 34 #define DMTE0_IRQ 34
...@@ -16,8 +29,11 @@ ...@@ -16,8 +29,11 @@
#define DMAE0_IRQ 38 #define DMAE0_IRQ 38
#define SH_DMAC_BASE0 0xFF608020 #define SH_DMAC_BASE0 0xFF608020
#define SH_DMARS_BASE 0xFF609000 #define SH_DMARS_BASE 0xFF609000
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \ #define CHCR_TS_LOW_MASK 0x00000018
defined(CONFIG_CPU_SUBTYPE_SH7724) #define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
#define DMTE0_IRQ 48 /* DMAC0A*/ #define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 76 /* DMAC0B */ #define DMTE4_IRQ 76 /* DMAC0B */
#define DMTE6_IRQ 40 #define DMTE6_IRQ 40
...@@ -30,6 +46,27 @@ ...@@ -30,6 +46,27 @@
#define SH_DMAC_BASE0 0xFE008020 #define SH_DMAC_BASE0 0xFE008020
#define SH_DMAC_BASE1 0xFDC08020 #define SH_DMAC_BASE1 0xFDC08020
#define SH_DMARS_BASE 0xFDC09000 #define SH_DMARS_BASE 0xFDC09000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
#define DMTE0_IRQ 48 /* DMAC0A*/
#define DMTE4_IRQ 76 /* DMAC0B */
#define DMTE6_IRQ 40
#define DMTE8_IRQ 42 /* DMAC1A */
#define DMTE9_IRQ 43
#define DMTE10_IRQ 72 /* DMAC1B */
#define DMTE11_IRQ 73
#define DMAE0_IRQ 78 /* DMA Error IRQ*/
#define DMAE1_IRQ 74 /* DMA Error IRQ*/
#define SH_DMAC_BASE0 0xFE008020
#define SH_DMAC_BASE1 0xFDC08020
#define SH_DMARS_BASE 0xFDC09000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0x00600000
#define CHCR_TS_HIGH_SHIFT 21
#elif defined(CONFIG_CPU_SUBTYPE_SH7780) #elif defined(CONFIG_CPU_SUBTYPE_SH7780)
#define DMTE0_IRQ 34 #define DMTE0_IRQ 34
#define DMTE4_IRQ 44 #define DMTE4_IRQ 44
...@@ -42,6 +79,10 @@ ...@@ -42,6 +79,10 @@
#define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFC818020 #define SH_DMAC_BASE1 0xFC818020
#define SH_DMARS_BASE 0xFC809000 #define SH_DMARS_BASE 0xFC809000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#else /* SH7785 */ #else /* SH7785 */
#define DMTE0_IRQ 33 #define DMTE0_IRQ 33
#define DMTE4_IRQ 37 #define DMTE4_IRQ 37
...@@ -55,17 +96,16 @@ ...@@ -55,17 +96,16 @@
#define SH_DMAC_BASE0 0xFC808020 #define SH_DMAC_BASE0 0xFC808020
#define SH_DMAC_BASE1 0xFCC08020 #define SH_DMAC_BASE1 0xFCC08020
#define SH_DMARS_BASE 0xFC809000 #define SH_DMARS_BASE 0xFC809000
#define CHCR_TS_LOW_MASK 0x00000018
#define CHCR_TS_LOW_SHIFT 3
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#endif #endif
#define REQ_HE 0x000000C0 #define REQ_HE 0x000000C0
#define REQ_H 0x00000080 #define REQ_H 0x00000080
#define REQ_LE 0x00000040 #define REQ_LE 0x00000040
#define TM_BURST 0x0000020 #define TM_BURST 0x00000020
#define TS_8 0x00000000
#define TS_16 0x00000008
#define TS_32 0x00000010
#define TS_16BLK 0x00000018
#define TS_32BLK 0x00100000
/* /*
* The SuperH DMAC supports a number of transmit sizes, we list them here, * The SuperH DMAC supports a number of transmit sizes, we list them here,
...@@ -74,22 +114,31 @@ ...@@ -74,22 +114,31 @@
* Defaults to a 64-bit transfer size. * Defaults to a 64-bit transfer size.
*/ */
enum { enum {
XMIT_SZ_8BIT, XMIT_SZ_8BIT = 0,
XMIT_SZ_16BIT, XMIT_SZ_16BIT = 1,
XMIT_SZ_32BIT, XMIT_SZ_32BIT = 2,
XMIT_SZ_128BIT, XMIT_SZ_64BIT = 7,
XMIT_SZ_256BIT, XMIT_SZ_128BIT = 3,
XMIT_SZ_256BIT = 4,
XMIT_SZ_128BIT_BLK = 0xb,
XMIT_SZ_256BIT_BLK = 0xc,
}; };
/* /*
* The DMA count is defined as the number of bytes to transfer. * The DMA count is defined as the number of bytes to transfer.
*/ */
static unsigned int ts_shift[] __maybe_unused = { #define TS_SHIFT { \
[XMIT_SZ_8BIT] = 0, [XMIT_SZ_8BIT] = 0, \
[XMIT_SZ_16BIT] = 1, [XMIT_SZ_16BIT] = 1, \
[XMIT_SZ_32BIT] = 2, [XMIT_SZ_32BIT] = 2, \
[XMIT_SZ_128BIT] = 4, [XMIT_SZ_64BIT] = 3, \
[XMIT_SZ_256BIT] = 5, [XMIT_SZ_128BIT] = 4, \
}; [XMIT_SZ_256BIT] = 5, \
[XMIT_SZ_128BIT_BLK] = 4, \
[XMIT_SZ_256BIT_BLK] = 5, \
}
#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */ #endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
#ifdef CONFIG_CPU_SH4A #ifdef CONFIG_CPU_SH4A
#define DMAOR_INIT (DMAOR_DME) #define DMAOR_INIT (DMAOR_DME)
#define CHCR_TS_MASK 0x18
#define CHCR_TS_SHIFT 3
#include <cpu/dma-sh4a.h> #include <cpu/dma-sh4a.h>
#else /* CONFIG_CPU_SH4A */ #else /* CONFIG_CPU_SH4A */
...@@ -29,8 +27,10 @@ ...@@ -29,8 +27,10 @@
#define TS_32 0x00000030 #define TS_32 0x00000030
#define TS_64 0x00000000 #define TS_64 0x00000000
#define CHCR_TS_MASK 0x70 #define CHCR_TS_LOW_MASK 0x70
#define CHCR_TS_SHIFT 4 #define CHCR_TS_LOW_SHIFT 4
#define CHCR_TS_HIGH_MASK 0
#define CHCR_TS_HIGH_SHIFT 0
#define DMAOR_COD 0x00000008 #define DMAOR_COD 0x00000008
...@@ -41,23 +41,26 @@ ...@@ -41,23 +41,26 @@
* Defaults to a 64-bit transfer size. * Defaults to a 64-bit transfer size.
*/ */
enum { enum {
XMIT_SZ_64BIT, XMIT_SZ_8BIT = 1,
XMIT_SZ_8BIT, XMIT_SZ_16BIT = 2,
XMIT_SZ_16BIT, XMIT_SZ_32BIT = 3,
XMIT_SZ_32BIT, XMIT_SZ_64BIT = 0,
XMIT_SZ_256BIT, XMIT_SZ_256BIT = 4,
}; };
/* /*
* The DMA count is defined as the number of bytes to transfer. * The DMA count is defined as the number of bytes to transfer.
*/ */
static unsigned int ts_shift[] __maybe_unused = { #define TS_SHIFT { \
[XMIT_SZ_64BIT] = 3, [XMIT_SZ_8BIT] = 0, \
[XMIT_SZ_8BIT] = 0, [XMIT_SZ_16BIT] = 1, \
[XMIT_SZ_16BIT] = 1, [XMIT_SZ_32BIT] = 2, \
[XMIT_SZ_32BIT] = 2, [XMIT_SZ_64BIT] = 3, \
[XMIT_SZ_256BIT] = 5, [XMIT_SZ_256BIT] = 5, \
}; }
#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
#endif #endif
#endif /* __ASM_CPU_SH4_DMA_H */ #endif /* __ASM_CPU_SH4_DMA_H */
...@@ -105,10 +105,14 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) ...@@ -105,10 +105,14 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
return false; /* waiting */ return false; /* waiting */
} }
static unsigned int ts_shift[] = TS_SHIFT;
static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan)
{ {
u32 chcr = sh_dmae_readl(sh_chan, CHCR); u32 chcr = sh_dmae_readl(sh_chan, CHCR);
return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
return ts_shift[cnt];
} }
static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment