aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap1/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap1/dma.c')
-rw-r--r--arch/arm/mach-omap1/dma.c191
1 files changed, 79 insertions, 112 deletions
diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c
index 5bb8ce86d54b..4be601b638d7 100644
--- a/arch/arm/mach-omap1/dma.c
+++ b/arch/arm/mach-omap1/dma.c
@@ -32,55 +32,51 @@
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;
38static u32 enable_1510_mode; 36static u32 enable_1510_mode;
39static u8 dma_stride; 37
40static enum omap_reg_offsets dma_common_ch_start, dma_common_ch_end; 38static const struct omap_dma_reg reg_map[] = {
41 39 [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT },
42static u16 reg_map[] = { 40 [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT },
43 [GCR] = 0x400, 41 [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT },
44 [GSCR] = 0x404, 42 [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT },
45 [GRST1] = 0x408, 43 [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT },
46 [HW_ID] = 0x442, 44 [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT },
47 [PCH2_ID] = 0x444, 45 [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT },
48 [PCH0_ID] = 0x446, 46 [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT },
49 [PCH1_ID] = 0x448, 47 [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT },
50 [PCHG_ID] = 0x44a, 48 [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT },
51 [PCHD_ID] = 0x44c, 49 [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT },
52 [CAPS_0] = 0x44e, 50 [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT },
53 [CAPS_1] = 0x452, 51 [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT },
54 [CAPS_2] = 0x456, 52 [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT },
55 [CAPS_3] = 0x458, 53 [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT },
56 [CAPS_4] = 0x45a, 54 [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT },
57 [PCH2_SR] = 0x460, 55 [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT },
58 [PCH0_SR] = 0x480, 56 [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT },
59 [PCH1_SR] = 0x482,
60 [PCHD_SR] = 0x4c0,
61 57
62 /* Common Registers */ 58 /* Common Registers */
63 [CSDP] = 0x00, 59 [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT },
64 [CCR] = 0x02, 60 [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT },
65 [CICR] = 0x04, 61 [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT },
66 [CSR] = 0x06, 62 [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT },
67 [CEN] = 0x10, 63 [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT },
68 [CFN] = 0x12, 64 [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT },
69 [CSFI] = 0x14, 65 [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT },
70 [CSEI] = 0x16, 66 [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT },
71 [CPC] = 0x18, /* 15xx only */ 67 [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */
72 [CSAC] = 0x18, 68 [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT },
73 [CDAC] = 0x1a, 69 [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT },
74 [CDEI] = 0x1c, 70 [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT },
75 [CDFI] = 0x1e, 71 [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT },
76 [CLNK_CTRL] = 0x28, 72 [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT },
77 73
78 /* Channel specific register offsets */ 74 /* Channel specific register offsets */
79 [CSSA] = 0x08, 75 [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT },
80 [CDSA] = 0x0c, 76 [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT },
81 [COLOR] = 0x20, 77 [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT },
82 [CCR2] = 0x24, 78 [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT },
83 [LCH_CTRL] = 0x2a, 79 [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT },
84}; 80};
85 81
86static struct resource res[] __initdata = { 82static struct resource res[] __initdata = {
@@ -181,44 +177,36 @@ static struct resource res[] __initdata = {
181static void __iomem *dma_base; 177static void __iomem *dma_base;
182static inline void dma_write(u32 val, int reg, int lch) 178static inline void dma_write(u32 val, int reg, int lch)
183{ 179{
184 u8 stride; 180 void __iomem *addr = dma_base;
185 u32 offset;
186 181
187 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 182 addr += reg_map[reg].offset;
188 offset = reg_map[reg] + (stride * lch); 183 addr += reg_map[reg].stride * lch;
189 184
190 __raw_writew(val, dma_base + offset); 185 __raw_writew(val, addr);
191 if ((reg > CLNK_CTRL && reg < CCEN) || 186 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
192 (reg > PCHD_ID && reg < CAPS_2)) { 187 __raw_writew(val >> 16, addr + 2);
193 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
194 __raw_writew(val >> 16, dma_base + offset2);
195 }
196} 188}
197 189
198static inline u32 dma_read(int reg, int lch) 190static inline u32 dma_read(int reg, int lch)
199{ 191{
200 u8 stride; 192 void __iomem *addr = dma_base;
201 u32 offset, val; 193 uint32_t val;
202 194
203 stride = (reg >= dma_common_ch_start) ? dma_stride : 0; 195 addr += reg_map[reg].offset;
204 offset = reg_map[reg] + (stride * lch); 196 addr += reg_map[reg].stride * lch;
205 197
206 val = __raw_readw(dma_base + offset); 198 val = __raw_readw(addr);
207 if ((reg > CLNK_CTRL && reg < CCEN) || 199 if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT)
208 (reg > PCHD_ID && reg < CAPS_2)) { 200 val |= __raw_readw(addr + 2) << 16;
209 u16 upper; 201
210 u32 offset2 = reg_map[reg] + 2 + (stride * lch);
211 upper = __raw_readw(dma_base + offset2);
212 val |= (upper << 16);
213 }
214 return val; 202 return val;
215} 203}
216 204
217static void omap1_clear_lch_regs(int lch) 205static void omap1_clear_lch_regs(int lch)
218{ 206{
219 int i = dma_common_ch_start; 207 int i;
220 208
221 for (; i <= dma_common_ch_end; i += 1) 209 for (i = CPC; i <= COLOR; i += 1)
222 dma_write(0, i, lch); 210 dma_write(0, i, lch);
223} 211}
224 212
@@ -255,8 +243,9 @@ static void omap1_show_dma_caps(void)
255 return; 243 return;
256} 244}
257 245
258static u32 configure_dma_errata(void) 246static unsigned configure_dma_errata(void)
259{ 247{
248 unsigned errata = 0;
260 249
261 /* 250 /*
262 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 251 * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is
@@ -272,11 +261,23 @@ static const struct platform_device_info omap_dma_dev_info = {
272 .name = "omap-dma-engine", 261 .name = "omap-dma-engine",
273 .id = -1, 262 .id = -1,
274 .dma_mask = DMA_BIT_MASK(32), 263 .dma_mask = DMA_BIT_MASK(32),
264 .res = res,
265 .num_res = 1,
266};
267
268static struct omap_system_dma_plat_info dma_plat_info __initdata = {
269 .reg_map = reg_map,
270 .channel_stride = 0x40,
271 .show_dma_caps = omap1_show_dma_caps,
272 .clear_lch_regs = omap1_clear_lch_regs,
273 .clear_dma = omap1_clear_dma,
274 .dma_write = dma_write,
275 .dma_read = dma_read,
275}; 276};
276 277
277static int __init omap1_system_dma_init(void) 278static int __init omap1_system_dma_init(void)
278{ 279{
279 struct omap_system_dma_plat_info *p; 280 struct omap_system_dma_plat_info p;
280 struct omap_dma_dev_attr *d; 281 struct omap_dma_dev_attr *d;
281 struct platform_device *pdev, *dma_pdev; 282 struct platform_device *pdev, *dma_pdev;
282 int ret; 283 int ret;
@@ -302,20 +303,12 @@ static int __init omap1_system_dma_init(void)
302 goto exit_iounmap; 303 goto exit_iounmap;
303 } 304 }
304 305
305 p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
306 if (!p) {
307 dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
308 __func__, pdev->name);
309 ret = -ENOMEM;
310 goto exit_iounmap;
311 }
312
313 d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL); 306 d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
314 if (!d) { 307 if (!d) {
315 dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n", 308 dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
316 __func__, pdev->name); 309 __func__, pdev->name);
317 ret = -ENOMEM; 310 ret = -ENOMEM;
318 goto exit_release_p; 311 goto exit_iounmap;
319 } 312 }
320 313
321 d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT; 314 d->lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
@@ -336,17 +329,6 @@ static int __init omap1_system_dma_init(void)
336 d->dev_caps |= CLEAR_CSR_ON_READ; 329 d->dev_caps |= CLEAR_CSR_ON_READ;
337 d->dev_caps |= IS_WORD_16; 330 d->dev_caps |= IS_WORD_16;
338 331
339
340 d->chan = kzalloc(sizeof(struct omap_dma_lch) *
341 (d->lch_count), GFP_KERNEL);
342 if (!d->chan) {
343 dev_err(&pdev->dev,
344 "%s: Memory allocation failed for d->chan!\n",
345 __func__);
346 ret = -ENOMEM;
347 goto exit_release_d;
348 }
349
350 if (cpu_is_omap15xx()) 332 if (cpu_is_omap15xx())
351 d->chan_count = 9; 333 d->chan_count = 9;
352 else if (cpu_is_omap16xx() || cpu_is_omap7xx()) { 334 else if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
@@ -356,35 +338,24 @@ static int __init omap1_system_dma_init(void)
356 d->chan_count = 9; 338 d->chan_count = 9;
357 } 339 }
358 340
359 p->dma_attr = d; 341 p = dma_plat_info;
360 342 p.dma_attr = d;
361 p->show_dma_caps = omap1_show_dma_caps; 343 p.errata = configure_dma_errata();
362 p->clear_lch_regs = omap1_clear_lch_regs;
363 p->clear_dma = omap1_clear_dma;
364 p->dma_write = dma_write;
365 p->dma_read = dma_read;
366 p->disable_irq_lch = NULL;
367
368 p->errata = configure_dma_errata();
369 344
370 ret = platform_device_add_data(pdev, p, sizeof(*p)); 345 ret = platform_device_add_data(pdev, &p, sizeof(p));
371 if (ret) { 346 if (ret) {
372 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 347 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
373 __func__, pdev->name, pdev->id); 348 __func__, pdev->name, pdev->id);
374 goto exit_release_chan; 349 goto exit_release_d;
375 } 350 }
376 351
377 ret = platform_device_add(pdev); 352 ret = platform_device_add(pdev);
378 if (ret) { 353 if (ret) {
379 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 354 dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
380 __func__, pdev->name, pdev->id); 355 __func__, pdev->name, pdev->id);
381 goto exit_release_chan; 356 goto exit_release_d;
382 } 357 }
383 358
384 dma_stride = OMAP1_DMA_STRIDE;
385 dma_common_ch_start = CPC;
386 dma_common_ch_end = COLOR;
387
388 dma_pdev = platform_device_register_full(&omap_dma_dev_info); 359 dma_pdev = platform_device_register_full(&omap_dma_dev_info);
389 if (IS_ERR(dma_pdev)) { 360 if (IS_ERR(dma_pdev)) {
390 ret = PTR_ERR(dma_pdev); 361 ret = PTR_ERR(dma_pdev);
@@ -395,12 +366,8 @@ static int __init omap1_system_dma_init(void)
395 366
396exit_release_pdev: 367exit_release_pdev:
397 platform_device_del(pdev); 368 platform_device_del(pdev);
398exit_release_chan:
399 kfree(d->chan);
400exit_release_d: 369exit_release_d:
401 kfree(d); 370 kfree(d);
402exit_release_p:
403 kfree(p);
404exit_iounmap: 371exit_iounmap:
405 iounmap(dma_base); 372 iounmap(dma_base);
406exit_device_put: 373exit_device_put: