aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-02-03 09:44:12 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-07 19:40:24 -0500
commit623b4ac4bf9e767991c66e29b47dd4b19458fb42 (patch)
tree9cf9c5ef8ac1ab714a35db1baf627fb701a98287
parentfc4618575f79eea062cdc51715040e40cd35b71c (diff)
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: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/drivers/dma/dma-sh.c5
-rw-r--r--arch/sh/include/asm/dma-sh.h2
-rw-r--r--arch/sh/include/cpu-sh3/cpu/dma.h20
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma-sh4a.h97
-rw-r--r--arch/sh/include/cpu-sh4/cpu/dma.h35
-rw-r--r--drivers/dma/shdma.c6
6 files changed, 114 insertions, 51 deletions
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 37fb5b8bbc3f..31830cb0af89 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -52,11 +52,14 @@ static inline unsigned int get_dmte_irq(unsigned int chan)
52 * 52 *
53 * iterations to complete the transfer. 53 * iterations to complete the transfer.
54 */ 54 */
55static unsigned int ts_shift[] = TS_SHIFT;
55static inline unsigned int calc_xmit_shift(struct dma_channel *chan) 56static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
56{ 57{
57 u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR); 58 u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
59 int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
60 ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
58 61
59 return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT]; 62 return ts_shift[cnt];
60} 63}
61 64
62/* 65/*
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
index 78eed3e0bdf5..01d2fc72551b 100644
--- a/arch/sh/include/asm/dma-sh.h
+++ b/arch/sh/include/asm/dma-sh.h
@@ -83,7 +83,7 @@ static int dmte_irq_map[] __maybe_unused = {
83 * Define the default configuration for dual address memory-memory transfer. 83 * Define the default configuration for dual address memory-memory transfer.
84 * The 0x400 value represents auto-request, external->external. 84 * The 0x400 value represents auto-request, external->external.
85 */ 85 */
86#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_32) 86#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
87 87
88/* DMA base address */ 88/* DMA base address */
89static u32 dma_base_addr[] __maybe_unused = { 89static u32 dma_base_addr[] __maybe_unused = {
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 0ea15f3f2363..207811a7a650 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -20,8 +20,10 @@
20#define TS_32 0x00000010 20#define TS_32 0x00000010
21#define TS_128 0x00000018 21#define TS_128 0x00000018
22 22
23#define CHCR_TS_MASK 0x18 23#define CHCR_TS_LOW_MASK 0x18
24#define CHCR_TS_SHIFT 3 24#define CHCR_TS_LOW_SHIFT 3
25#define CHCR_TS_HIGH_MASK 0
26#define CHCR_TS_HIGH_SHIFT 0
25 27
26#define DMAOR_INIT DMAOR_DME 28#define DMAOR_INIT DMAOR_DME
27 29
@@ -36,11 +38,13 @@ enum {
36 XMIT_SZ_128BIT, 38 XMIT_SZ_128BIT,
37}; 39};
38 40
39static unsigned int ts_shift[] __maybe_unused = { 41#define TS_SHIFT { \
40 [XMIT_SZ_8BIT] = 0, 42 [XMIT_SZ_8BIT] = 0, \
41 [XMIT_SZ_16BIT] = 1, 43 [XMIT_SZ_16BIT] = 1, \
42 [XMIT_SZ_32BIT] = 2, 44 [XMIT_SZ_32BIT] = 2, \
43 [XMIT_SZ_128BIT] = 4, 45 [XMIT_SZ_128BIT] = 4, \
44}; 46}
47
48#define TS_INDEX2VAL(i) (((i) & 3) << CHCR_TS_LOW_SHIFT)
45 49
46#endif /* __ASM_CPU_SH3_DMA_H */ 50#endif /* __ASM_CPU_SH3_DMA_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
index c4ed660c14cf..cc1cf3e8f163 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -2,13 +2,26 @@
2#define __ASM_SH_CPU_SH4_DMA_SH7780_H 2#define __ASM_SH_CPU_SH4_DMA_SH7780_H
3 3
4#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \ 4#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
5 defined(CONFIG_CPU_SUBTYPE_SH7722) || \
6 defined(CONFIG_CPU_SUBTYPE_SH7730) 5 defined(CONFIG_CPU_SUBTYPE_SH7730)
7#define DMTE0_IRQ 48 6#define DMTE0_IRQ 48
8#define DMTE4_IRQ 76 7#define DMTE4_IRQ 76
9#define DMAE0_IRQ 78 /* DMA Error IRQ*/ 8#define DMAE0_IRQ 78 /* DMA Error IRQ*/
10#define SH_DMAC_BASE0 0xFE008020 9#define SH_DMAC_BASE0 0xFE008020
11#define SH_DMARS_BASE 0xFE009000 10#define SH_DMARS_BASE 0xFE009000
11#define CHCR_TS_LOW_MASK 0x00000018
12#define CHCR_TS_LOW_SHIFT 3
13#define CHCR_TS_HIGH_MASK 0
14#define CHCR_TS_HIGH_SHIFT 0
15#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
16#define DMTE0_IRQ 48
17#define DMTE4_IRQ 76
18#define DMAE0_IRQ 78 /* DMA Error IRQ*/
19#define SH_DMAC_BASE0 0xFE008020
20#define SH_DMARS_BASE 0xFE009000
21#define CHCR_TS_LOW_MASK 0x00000018
22#define CHCR_TS_LOW_SHIFT 3
23#define CHCR_TS_HIGH_MASK 0x00300000
24#define CHCR_TS_HIGH_SHIFT 20
12#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \ 25#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
13 defined(CONFIG_CPU_SUBTYPE_SH7764) 26 defined(CONFIG_CPU_SUBTYPE_SH7764)
14#define DMTE0_IRQ 34 27#define DMTE0_IRQ 34
@@ -16,8 +29,11 @@
16#define DMAE0_IRQ 38 29#define DMAE0_IRQ 38
17#define SH_DMAC_BASE0 0xFF608020 30#define SH_DMAC_BASE0 0xFF608020
18#define SH_DMARS_BASE 0xFF609000 31#define SH_DMARS_BASE 0xFF609000
19#elif defined(CONFIG_CPU_SUBTYPE_SH7723) || \ 32#define CHCR_TS_LOW_MASK 0x00000018
20 defined(CONFIG_CPU_SUBTYPE_SH7724) 33#define CHCR_TS_LOW_SHIFT 3
34#define CHCR_TS_HIGH_MASK 0
35#define CHCR_TS_HIGH_SHIFT 0
36#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
21#define DMTE0_IRQ 48 /* DMAC0A*/ 37#define DMTE0_IRQ 48 /* DMAC0A*/
22#define DMTE4_IRQ 76 /* DMAC0B */ 38#define DMTE4_IRQ 76 /* DMAC0B */
23#define DMTE6_IRQ 40 39#define DMTE6_IRQ 40
@@ -30,6 +46,27 @@
30#define SH_DMAC_BASE0 0xFE008020 46#define SH_DMAC_BASE0 0xFE008020
31#define SH_DMAC_BASE1 0xFDC08020 47#define SH_DMAC_BASE1 0xFDC08020
32#define SH_DMARS_BASE 0xFDC09000 48#define SH_DMARS_BASE 0xFDC09000
49#define CHCR_TS_LOW_MASK 0x00000018
50#define CHCR_TS_LOW_SHIFT 3
51#define CHCR_TS_HIGH_MASK 0
52#define CHCR_TS_HIGH_SHIFT 0
53#elif defined(CONFIG_CPU_SUBTYPE_SH7724)
54#define DMTE0_IRQ 48 /* DMAC0A*/
55#define DMTE4_IRQ 76 /* DMAC0B */
56#define DMTE6_IRQ 40
57#define DMTE8_IRQ 42 /* DMAC1A */
58#define DMTE9_IRQ 43
59#define DMTE10_IRQ 72 /* DMAC1B */
60#define DMTE11_IRQ 73
61#define DMAE0_IRQ 78 /* DMA Error IRQ*/
62#define DMAE1_IRQ 74 /* DMA Error IRQ*/
63#define SH_DMAC_BASE0 0xFE008020
64#define SH_DMAC_BASE1 0xFDC08020
65#define SH_DMARS_BASE 0xFDC09000
66#define CHCR_TS_LOW_MASK 0x00000018
67#define CHCR_TS_LOW_SHIFT 3
68#define CHCR_TS_HIGH_MASK 0x00600000
69#define CHCR_TS_HIGH_SHIFT 21
33#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 70#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
34#define DMTE0_IRQ 34 71#define DMTE0_IRQ 34
35#define DMTE4_IRQ 44 72#define DMTE4_IRQ 44
@@ -42,6 +79,10 @@
42#define SH_DMAC_BASE0 0xFC808020 79#define SH_DMAC_BASE0 0xFC808020
43#define SH_DMAC_BASE1 0xFC818020 80#define SH_DMAC_BASE1 0xFC818020
44#define SH_DMARS_BASE 0xFC809000 81#define SH_DMARS_BASE 0xFC809000
82#define CHCR_TS_LOW_MASK 0x00000018
83#define CHCR_TS_LOW_SHIFT 3
84#define CHCR_TS_HIGH_MASK 0
85#define CHCR_TS_HIGH_SHIFT 0
45#else /* SH7785 */ 86#else /* SH7785 */
46#define DMTE0_IRQ 33 87#define DMTE0_IRQ 33
47#define DMTE4_IRQ 37 88#define DMTE4_IRQ 37
@@ -55,17 +96,16 @@
55#define SH_DMAC_BASE0 0xFC808020 96#define SH_DMAC_BASE0 0xFC808020
56#define SH_DMAC_BASE1 0xFCC08020 97#define SH_DMAC_BASE1 0xFCC08020
57#define SH_DMARS_BASE 0xFC809000 98#define SH_DMARS_BASE 0xFC809000
99#define CHCR_TS_LOW_MASK 0x00000018
100#define CHCR_TS_LOW_SHIFT 3
101#define CHCR_TS_HIGH_MASK 0
102#define CHCR_TS_HIGH_SHIFT 0
58#endif 103#endif
59 104
60#define REQ_HE 0x000000C0 105#define REQ_HE 0x000000C0
61#define REQ_H 0x00000080 106#define REQ_H 0x00000080
62#define REQ_LE 0x00000040 107#define REQ_LE 0x00000040
63#define TM_BURST 0x0000020 108#define TM_BURST 0x00000020
64#define TS_8 0x00000000
65#define TS_16 0x00000008
66#define TS_32 0x00000010
67#define TS_16BLK 0x00000018
68#define TS_32BLK 0x00100000
69 109
70/* 110/*
71 * The SuperH DMAC supports a number of transmit sizes, we list them here, 111 * The SuperH DMAC supports a number of transmit sizes, we list them here,
@@ -74,22 +114,31 @@
74 * Defaults to a 64-bit transfer size. 114 * Defaults to a 64-bit transfer size.
75 */ 115 */
76enum { 116enum {
77 XMIT_SZ_8BIT, 117 XMIT_SZ_8BIT = 0,
78 XMIT_SZ_16BIT, 118 XMIT_SZ_16BIT = 1,
79 XMIT_SZ_32BIT, 119 XMIT_SZ_32BIT = 2,
80 XMIT_SZ_128BIT, 120 XMIT_SZ_64BIT = 7,
81 XMIT_SZ_256BIT, 121 XMIT_SZ_128BIT = 3,
122 XMIT_SZ_256BIT = 4,
123 XMIT_SZ_128BIT_BLK = 0xb,
124 XMIT_SZ_256BIT_BLK = 0xc,
82}; 125};
83 126
84/* 127/*
85 * The DMA count is defined as the number of bytes to transfer. 128 * The DMA count is defined as the number of bytes to transfer.
86 */ 129 */
87static unsigned int ts_shift[] __maybe_unused = { 130#define TS_SHIFT { \
88 [XMIT_SZ_8BIT] = 0, 131 [XMIT_SZ_8BIT] = 0, \
89 [XMIT_SZ_16BIT] = 1, 132 [XMIT_SZ_16BIT] = 1, \
90 [XMIT_SZ_32BIT] = 2, 133 [XMIT_SZ_32BIT] = 2, \
91 [XMIT_SZ_128BIT] = 4, 134 [XMIT_SZ_64BIT] = 3, \
92 [XMIT_SZ_256BIT] = 5, 135 [XMIT_SZ_128BIT] = 4, \
93}; 136 [XMIT_SZ_256BIT] = 5, \
137 [XMIT_SZ_128BIT_BLK] = 4, \
138 [XMIT_SZ_256BIT_BLK] = 5, \
139}
140
141#define TS_INDEX2VAL(i) ((((i) & 3) << CHCR_TS_LOW_SHIFT) | \
142 ((((i) >> 2) & 3) << CHCR_TS_HIGH_SHIFT))
94 143
95#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */ 144#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index bcb30246e85c..114a369705bc 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -6,8 +6,6 @@
6#ifdef CONFIG_CPU_SH4A 6#ifdef CONFIG_CPU_SH4A
7 7
8#define DMAOR_INIT (DMAOR_DME) 8#define DMAOR_INIT (DMAOR_DME)
9#define CHCR_TS_MASK 0x18
10#define CHCR_TS_SHIFT 3
11 9
12#include <cpu/dma-sh4a.h> 10#include <cpu/dma-sh4a.h>
13#else /* CONFIG_CPU_SH4A */ 11#else /* CONFIG_CPU_SH4A */
@@ -29,8 +27,10 @@
29#define TS_32 0x00000030 27#define TS_32 0x00000030
30#define TS_64 0x00000000 28#define TS_64 0x00000000
31 29
32#define CHCR_TS_MASK 0x70 30#define CHCR_TS_LOW_MASK 0x70
33#define CHCR_TS_SHIFT 4 31#define CHCR_TS_LOW_SHIFT 4
32#define CHCR_TS_HIGH_MASK 0
33#define CHCR_TS_HIGH_SHIFT 0
34 34
35#define DMAOR_COD 0x00000008 35#define DMAOR_COD 0x00000008
36 36
@@ -41,23 +41,26 @@
41 * Defaults to a 64-bit transfer size. 41 * Defaults to a 64-bit transfer size.
42 */ 42 */
43enum { 43enum {
44 XMIT_SZ_64BIT, 44 XMIT_SZ_8BIT = 1,
45 XMIT_SZ_8BIT, 45 XMIT_SZ_16BIT = 2,
46 XMIT_SZ_16BIT, 46 XMIT_SZ_32BIT = 3,
47 XMIT_SZ_32BIT, 47 XMIT_SZ_64BIT = 0,
48 XMIT_SZ_256BIT, 48 XMIT_SZ_256BIT = 4,
49}; 49};
50 50
51/* 51/*
52 * The DMA count is defined as the number of bytes to transfer. 52 * The DMA count is defined as the number of bytes to transfer.
53 */ 53 */
54static unsigned int ts_shift[] __maybe_unused = { 54#define TS_SHIFT { \
55 [XMIT_SZ_64BIT] = 3, 55 [XMIT_SZ_8BIT] = 0, \
56 [XMIT_SZ_8BIT] = 0, 56 [XMIT_SZ_16BIT] = 1, \
57 [XMIT_SZ_16BIT] = 1, 57 [XMIT_SZ_32BIT] = 2, \
58 [XMIT_SZ_32BIT] = 2, 58 [XMIT_SZ_64BIT] = 3, \
59 [XMIT_SZ_256BIT] = 5, 59 [XMIT_SZ_256BIT] = 5, \
60}; 60}
61
62#define TS_INDEX2VAL(i) (((i) & 7) << CHCR_TS_LOW_SHIFT)
63
61#endif 64#endif
62 65
63#endif /* __ASM_CPU_SH4_DMA_H */ 66#endif /* __ASM_CPU_SH4_DMA_H */
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 427c3effc432..3e1037c5ebd1 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -105,10 +105,14 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
105 return false; /* waiting */ 105 return false; /* waiting */
106} 106}
107 107
108static unsigned int ts_shift[] = TS_SHIFT;
108static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan) 109static inline unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan)
109{ 110{
110 u32 chcr = sh_dmae_readl(sh_chan, CHCR); 111 u32 chcr = sh_dmae_readl(sh_chan, CHCR);
111 return ts_shift[(chcr & CHCR_TS_MASK) >> CHCR_TS_SHIFT]; 112 int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |
113 ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT);
114
115 return ts_shift[cnt];
112} 116}
113 117
114static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) 118static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)