aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/dma.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2014-04-14 10:44:42 -0400
committerIngo Molnar <mingo@kernel.org>2014-04-14 10:44:42 -0400
commit740c699a8d316c8bf8593f19e2ca47795e690622 (patch)
treea78886955770a477945c5d84e06b2e7678733b54 /arch/arm/mach-omap2/dma.c
parente69af4657e7764d03ad555f0b583d9c4217bcefa (diff)
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
Merge tag 'v3.15-rc1' into perf/urgent
Pick up the latest fixes. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/arm/mach-omap2/dma.c')
-rw-r--r--arch/arm/mach-omap2/dma.c183
1 files changed, 78 insertions, 105 deletions
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index 49fd0d501c9b..5689c88d986d 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -35,97 +35,80 @@
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 38static enum omap_reg_offsets dma_common_ch_end;
39 39
40static u32 errata; 40static const struct omap_dma_reg reg_map[] = {
41static u8 dma_stride; 41 [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
42 42 [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT },
43static struct omap_dma_dev_attr *d; 43 [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT },
44 44 [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT },
45static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; 45 [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT },
46 46 [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT },
47static u16 reg_map[] = { 47 [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT },
48 [REVISION] = 0x00, 48 [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT },
49 [GCR] = 0x78, 49 [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT },
50 [IRQSTATUS_L0] = 0x08, 50 [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT },
51 [IRQSTATUS_L1] = 0x0c, 51 [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT },
52 [IRQSTATUS_L2] = 0x10, 52 [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT },
53 [IRQSTATUS_L3] = 0x14, 53 [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT },
54 [IRQENABLE_L0] = 0x18, 54 [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT },
55 [IRQENABLE_L1] = 0x1c, 55 [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT },
56 [IRQENABLE_L2] = 0x20, 56 [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT },
57 [IRQENABLE_L3] = 0x24,
58 [SYSSTATUS] = 0x28,
59 [OCP_SYSCONFIG] = 0x2c,
60 [CAPS_0] = 0x64,
61 [CAPS_2] = 0x6c,
62 [CAPS_3] = 0x70,
63 [CAPS_4] = 0x74,
64 57
65 /* Common register offsets */ 58 /* Common register offsets */
66 [CCR] = 0x80, 59 [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT },
67 [CLNK_CTRL] = 0x84, 60 [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT },
68 [CICR] = 0x88, 61 [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT },
69 [CSR] = 0x8c, 62 [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT },
70 [CSDP] = 0x90, 63 [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT },
71 [CEN] = 0x94, 64 [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT },
72 [CFN] = 0x98, 65 [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT },
73 [CSEI] = 0xa4, 66 [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT },
74 [CSFI] = 0xa8, 67 [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT },
75 [CDEI] = 0xac, 68 [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT },
76 [CDFI] = 0xb0, 69 [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT },
77 [CSAC] = 0xb4, 70 [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT },
78 [CDAC] = 0xb8, 71 [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT },
79 72
80 /* Channel specific register offsets */ 73 /* Channel specific register offsets */
81 [CSSA] = 0x9c, 74 [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT },
82 [CDSA] = 0xa0, 75 [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT },
83 [CCEN] = 0xbc, 76 [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT },
84 [CCFN] = 0xc0, 77 [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT },
85 [COLOR] = 0xc4, 78 [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT },
86 79
87 /* OMAP4 specific registers */ 80 /* OMAP4 specific registers */
88 [CDP] = 0xd0, 81 [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT },
89 [CNDP] = 0xd4, 82 [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT },
90 [CCDN] = 0xd8, 83 [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
91}; 84};
92 85
93static void __iomem *dma_base; 86static void __iomem *dma_base;
94static inline void dma_write(u32 val, int reg, int lch) 87static inline void dma_write(u32 val, int reg, int lch)
95{ 88{
96 u8 stride; 89 void __iomem *addr = dma_base;
97 u32 offset;
98 90
99 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 91 addr += reg_map[reg].offset;
100 offset = reg_map[reg] + (stride * lch); 92 addr += reg_map[reg].stride * lch;
101 __raw_writel(val, dma_base + offset); 93
94 __raw_writel(val, addr);
102} 95}
103 96
104static inline u32 dma_read(int reg, int lch) 97static inline u32 dma_read(int reg, int lch)
105{ 98{
106 u8 stride; 99 void __iomem *addr = dma_base;
107 u32 offset, val;
108
109 stride = (reg >= dma_common_ch_start) ? dma_stride : 0;
110 offset = reg_map[reg] + (stride * lch);
111 val = __raw_readl(dma_base + offset);
112 return val;
113}
114 100
115static inline void omap2_disable_irq_lch(int lch) 101 addr += reg_map[reg].offset;
116{ 102 addr += reg_map[reg].stride * lch;
117 u32 val;
118 103
119 val = dma_read(IRQENABLE_L0, lch); 104 return __raw_readl(addr);
120 val &= ~(1 << lch);
121 dma_write(val, IRQENABLE_L0, lch);
122} 105}
123 106
124static void omap2_clear_dma(int lch) 107static void omap2_clear_dma(int lch)
125{ 108{
126 int i = dma_common_ch_start; 109 int i;
127 110
128 for (; i <= dma_common_ch_end; i += 1) 111 for (i = CSDP; i <= dma_common_ch_end; i += 1)
129 dma_write(0, i, lch); 112 dma_write(0, i, lch);
130} 113}
131 114
@@ -137,8 +120,9 @@ static void omap2_show_dma_caps(void)
137 return; 120 return;
138} 121}
139 122
140static u32 configure_dma_errata(void) 123static unsigned configure_dma_errata(void)
141{ 124{
125 unsigned errata = 0;
142 126
143 /* 127 /*
144 * Errata applicable for OMAP2430ES1.0 and all omap2420 128 * Errata applicable for OMAP2430ES1.0 and all omap2420
@@ -220,48 +204,50 @@ static u32 configure_dma_errata(void)
220 return errata; 204 return errata;
221} 205}
222 206
207static struct omap_system_dma_plat_info dma_plat_info __initdata = {
208 .reg_map = reg_map,
209 .channel_stride = 0x60,
210 .show_dma_caps = omap2_show_dma_caps,
211 .clear_dma = omap2_clear_dma,
212 .dma_write = dma_write,
213 .dma_read = dma_read,
214};
215
216static struct platform_device_info omap_dma_dev_info = {
217 .name = "omap-dma-engine",
218 .id = -1,
219 .dma_mask = DMA_BIT_MASK(32),
220};
221
223/* One time initializations */ 222/* One time initializations */
224static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) 223static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
225{ 224{
226 struct platform_device *pdev; 225 struct platform_device *pdev;
227 struct omap_system_dma_plat_info *p; 226 struct omap_system_dma_plat_info p;
227 struct omap_dma_dev_attr *d;
228 struct resource *mem; 228 struct resource *mem;
229 char *name = "omap_dma_system"; 229 char *name = "omap_dma_system";
230 230
231 dma_stride = OMAP2_DMA_STRIDE; 231 p = dma_plat_info;
232 dma_common_ch_start = CSDP; 232 p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
233 233 p.errata = configure_dma_errata();
234 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
235 if (!p) {
236 pr_err("%s: Unable to allocate pdata for %s:%s\n",
237 __func__, name, oh->name);
238 return -ENOMEM;
239 }
240
241 p->dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
242 p->disable_irq_lch = omap2_disable_irq_lch;
243 p->show_dma_caps = omap2_show_dma_caps;
244 p->clear_dma = omap2_clear_dma;
245 p->dma_write = dma_write;
246 p->dma_read = dma_read;
247
248 p->clear_lch_regs = NULL;
249
250 p->errata = configure_dma_errata();
251 234
252 pdev = omap_device_build(name, 0, oh, p, sizeof(*p)); 235 pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
253 kfree(p);
254 if (IS_ERR(pdev)) { 236 if (IS_ERR(pdev)) {
255 pr_err("%s: Can't build omap_device for %s:%s.\n", 237 pr_err("%s: Can't build omap_device for %s:%s.\n",
256 __func__, name, oh->name); 238 __func__, name, oh->name);
257 return PTR_ERR(pdev); 239 return PTR_ERR(pdev);
258 } 240 }
259 241
242 omap_dma_dev_info.res = pdev->resource;
243 omap_dma_dev_info.num_res = pdev->num_resources;
244
260 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 245 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
261 if (!mem) { 246 if (!mem) {
262 dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 247 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
263 return -EINVAL; 248 return -EINVAL;
264 } 249 }
250
265 dma_base = ioremap(mem->start, resource_size(mem)); 251 dma_base = ioremap(mem->start, resource_size(mem));
266 if (!dma_base) { 252 if (!dma_base) {
267 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 253 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
@@ -269,13 +255,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
269 } 255 }
270 256
271 d = oh->dev_attr; 257 d = oh->dev_attr;
272 d->chan = kzalloc(sizeof(struct omap_dma_lch) *
273 (d->lch_count), GFP_KERNEL);
274
275 if (!d->chan) {
276 dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
277 return -ENOMEM;
278 }
279 258
280 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 259 if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
281 d->dev_caps |= HS_CHANNELS_RESERVED; 260 d->dev_caps |= HS_CHANNELS_RESERVED;
@@ -289,12 +268,6 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
289 return 0; 268 return 0;
290} 269}
291 270
292static const struct platform_device_info omap_dma_dev_info = {
293 .name = "omap-dma-engine",
294 .id = -1,
295 .dma_mask = DMA_BIT_MASK(32),
296};
297
298static int __init omap2_system_dma_init(void) 271static int __init omap2_system_dma_init(void)
299{ 272{
300 struct platform_device *pdev; 273 struct platform_device *pdev;