aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-11-08 13:04:06 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-04-03 19:31:44 -0400
commit64a2dc3d3de4235eb73921d870a674a23d9888f0 (patch)
tree02be605c9a07a76952dc8678d7e7a4e0c2bac2f3
parentad0c381a8b3a15b8edfca0996729ea45692470ca (diff)
ARM: omap: clean up DMA register accesses
We can do much better with this by using a structure to describe each register, rather than code. Acked-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-omap1/dma.c117
-rw-r--r--arch/arm/mach-omap2/dma.c99
-rw-r--r--include/linux/omap-dma.h13
3 files changed, 115 insertions, 114 deletions
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 11f0b0ee67a3..b680db7a35d4 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -32,53 +32,52 @@
32 32
33#define OMAP1_DMA_BASE (0xfffed800) 33#define OMAP1_DMA_BASE (0xfffed800)
34#define OMAP1_LOGICAL_DMA_CH_COUNT 17 34#define OMAP1_LOGICAL_DMA_CH_COUNT 17
35#define OMAP1_DMA_STRIDE 0x40
36 35
37static u32 errata; 36static u32 errata;
38static u32 enable_1510_mode; 37static u32 enable_1510_mode;
39 38
40static u16 reg_map[] = { 39static const struct omap_dma_reg reg_map[] = {
41 [GCR] = 0x400, 40 [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
42 [GSCR] = 0x404, 41 [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
43 [GRST1] = 0x408, 42 [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
44 [HW_ID] = 0x442, 43 [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
45 [PCH2_ID] = 0x444, 44 [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
46 [PCH0_ID] = 0x446, 45 [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
47 [PCH1_ID] = 0x448, 46 [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
48 [PCHG_ID] = 0x44a, 47 [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
49 [PCHD_ID] = 0x44c, 48 [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
50 [CAPS_0] = 0x44e, 49 [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
51 [CAPS_1] = 0x452, 50 [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
52 [CAPS_2] = 0x456, 51 [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
53 [CAPS_3] = 0x458, 52 [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
54 [CAPS_4] = 0x45a, 53 [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
55 [PCH2_SR] = 0x460, 54 [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
56 [PCH0_SR] = 0x480, 55 [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
57 [PCH1_SR] = 0x482, 56 [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
58 [PCHD_SR] = 0x4c0, 57 [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
59 58
60 /* Common Registers */ 59 /* Common Registers */
61 [CSDP] = 0x00, 60 [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
62 [CCR] = 0x02, 61 [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
63 [CICR] = 0x04, 62 [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
64 [CSR] = 0x06, 63 [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
65 [CEN] = 0x10, 64 [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
66 [CFN] = 0x12, 65 [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
67 [CSFI] = 0x14, 66 [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
68 [CSEI] = 0x16, 67 [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
69 [CPC] = 0x18, /* 15xx only */ 68 [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
70 [CSAC] = 0x18, 69 [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
71 [CDAC] = 0x1a, 70 [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
72 [CDEI] = 0x1c, 71 [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
73 [CDFI] = 0x1e, 72 [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
74 [CLNK_CTRL] = 0x28, 73 [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
75 74
76 /* Channel specific register offsets */ 75 /* Channel specific register offsets */
77 [CSSA] = 0x08, 76 [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
78 [CDSA] = 0x0c, 77 [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
79 [COLOR] = 0x20, 78 [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
80 [CCR2] = 0x24, 79 [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
81 [LCH_CTRL] = 0x2a, 80 [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
82}; 81};
83 82
84static struct resource res[] __initdata = { 83static struct resource res[] __initdata = {
@@ -179,36 +178,28 @@ static struct resource res[] __initdata = {
179static void __iomem *dma_base; 178static void __iomem *dma_base;
180static inline void dma_write(u32 val, int reg, int lch) 179static inline void dma_write(u32 val, int reg, int lch)
181{ 180{
182 u8 stride; 181 void __iomem *addr = dma_base;
183 u32 offset;
184 182
185 stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0; 183 addr += reg_map[reg].offset;
186 offset = reg_map[reg] + (stride * lch); 184 addr += reg_map[reg].stride * lch;
187 185
188 __raw_writew(val, dma_base + offset); 186 __raw_writew(val, addr);
189 if ((reg > CLNK_CTRL && reg < CCEN) || 187 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
190 (reg > PCHD_ID && reg < CAPS_2)) { 188 __raw_writew(val >> 16, addr + 2);
191 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
192 __raw_writew(val >> 16, dma_base + offset2);
193 }
194} 189}
195 190
196static inline u32 dma_read(int reg, int lch) 191static inline u32 dma_read(int reg, int lch)
197{ 192{
198 u8 stride; 193 void __iomem *addr = dma_base;
199 u32 offset, val; 194 uint32_t val;
200 195
201 stride = (reg >= CPC) ? OMAP1_DMA_STRIDE : 0; 196 addr += reg_map[reg].offset;
202 offset = reg_map[reg] + (stride * lch); 197 addr += reg_map[reg].stride * lch;
203 198
204 val = __raw_readw(dma_base + offset); 199 val = __raw_readw(addr);
205 if ((reg > CLNK_CTRL && reg < CCEN) || 200 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
206 (reg > PCHD_ID && reg < CAPS_2)) { 201 val |= __raw_readw(addr + 2) << 16;
207 u16 upper; 202
208 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
209 upper = __raw_readw(dma_base + offset2);
210 val |= (upper << 16);
211 }
212 return val; 203 return val;
213} 204}
214 205
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e4ac7ac9a228..e633b48a3fcb 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,80 +35,77 @@
35#include "omap_hwmod.h" 35#include "omap_hwmod.h"
36#include "omap_device.h" 36#include "omap_device.h"
37 37
38#define OMAP2_DMA_STRIDE 0x60
39
40static u32 errata; 38static u32 errata;
41 39
42static struct omap_dma_dev_attr *d; 40static struct omap_dma_dev_attr *d;
43 41
44static enum omap_reg_offsets dma_common_ch_end; 42static enum omap_reg_offsets dma_common_ch_end;
45 43
46static u16 reg_map[] = { 44static const struct omap_dma_reg reg_map[] = {
47 [REVISION] = 0x00, 45 [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
48 [GCR] = 0x78, 46 [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
49 [IRQSTATUS_L0] = 0x08, 47 [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
50 [IRQSTATUS_L1] = 0x0c, 48 [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
51 [IRQSTATUS_L2] = 0x10, 49 [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
52 [IRQSTATUS_L3] = 0x14, 50 [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
53 [IRQENABLE_L0] = 0x18, 51 [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
54 [IRQENABLE_L1] = 0x1c, 52 [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
55 [IRQENABLE_L2] = 0x20, 53 [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
56 [IRQENABLE_L3] = 0x24, 54 [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
57 [SYSSTATUS] = 0x28, 55 [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
58 [OCP_SYSCONFIG] = 0x2c, 56 [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
59 [CAPS_0] = 0x64, 57 [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
60 [CAPS_2] = 0x6c, 58 [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
61 [CAPS_3] = 0x70, 59 [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
62 [CAPS_4] = 0x74, 60 [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
63 61
64 /* Common register offsets */ 62 /* Common register offsets */
65 [CCR] = 0x80, 63 [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
66 [CLNK_CTRL] = 0x84, 64 [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
67 [CICR] = 0x88, 65 [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
68 [CSR] = 0x8c, 66 [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
69 [CSDP] = 0x90, 67 [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
70 [CEN] = 0x94, 68 [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
71 [CFN] = 0x98, 69 [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
72 [CSEI] = 0xa4, 70 [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
73 [CSFI] = 0xa8, 71 [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
74 [CDEI] = 0xac, 72 [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
75 [CDFI] = 0xb0, 73 [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
76 [CSAC] = 0xb4, 74 [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
77 [CDAC] = 0xb8, 75 [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
78 76
79 /* Channel specific register offsets */ 77 /* Channel specific register offsets */
80 [CSSA] = 0x9c, 78 [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
81 [CDSA] = 0xa0, 79 [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
82 [CCEN] = 0xbc, 80 [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
83 [CCFN] = 0xc0, 81 [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
84 [COLOR] = 0xc4, 82 [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
85 83
86 /* OMAP4 specific registers */ 84 /* OMAP4 specific registers */
87 [CDP] = 0xd0, 85 [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
88 [CNDP] = 0xd4, 86 [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
89 [CCDN] = 0xd8, 87 [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
90}; 88};
91 89
92static void __iomem *dma_base; 90static void __iomem *dma_base;
93static inline void dma_write(u32 val, int reg, int lch) 91static inline void dma_write(u32 val, int reg, int lch)
94{ 92{
95 u8 stride; 93 void __iomem *addr = dma_base;
96 u32 offset; 94
95 addr += reg_map[reg].offset;
96 addr += reg_map[reg].stride * lch;
97 97
98 stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0; 98 __raw_writel(val, addr);
99 offset = reg_map[reg] + (stride * lch);
100 __raw_writel(val, dma_base + offset);
101} 99}
102 100
103static inline u32 dma_read(int reg, int lch) 101static inline u32 dma_read(int reg, int lch)
104{ 102{
105 u8 stride; 103 void __iomem *addr = dma_base;
106 u32 offset, val; 104
105 addr += reg_map[reg].offset;
106 addr += reg_map[reg].stride * lch;
107 107
108 stride = (reg >= CSDP) ? OMAP2_DMA_STRIDE : 0; 108 return __raw_readl(addr);
109 offset = reg_map[reg] + (stride * lch);
110 val = __raw_readl(dma_base + offset);
111 return val;
112} 109}
113 110
114static void omap2_clear_dma(int lch) 111static void omap2_clear_dma(int lch)
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 0bb7de77d478..41328725721a 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -271,6 +271,19 @@ struct omap_dma_dev_attr {
271 struct omap_dma_lch *chan; 271 struct omap_dma_lch *chan;
272}; 272};
273 273
274enum {
275 OMAP_DMA_REG_NONE,
276 OMAP_DMA_REG_16BIT,
277 OMAP_DMA_REG_2X16BIT,
278 OMAP_DMA_REG_32BIT,
279};
280
281struct omap_dma_reg {
282 u16 offset;
283 u8 stride;
284 u8 type;
285};
286
274/* System DMA platform data structure */ 287/* System DMA platform data structure */
275struct omap_system_dma_plat_info { 288struct omap_system_dma_plat_info {
276 struct omap_dma_dev_attr *dma_attr; 289 struct omap_dma_dev_attr *dma_attr;