diff options
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r-- | arch/arm/plat-omap/dma.c | 84 |
1 files changed, 65 insertions, 19 deletions
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index 5dac4230360d..c5d0214ef191 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | #define OMAP_DMA_ACTIVE 0x01 | 44 | #define OMAP_DMA_ACTIVE 0x01 |
45 | #define OMAP_DMA_CCR_EN (1 << 7) | 45 | #define OMAP_DMA_CCR_EN (1 << 7) |
46 | #define OMAP2_DMA_CSR_CLEAR_MASK 0xffe | ||
46 | 47 | ||
47 | #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) | 48 | #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) |
48 | 49 | ||
@@ -166,18 +167,24 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, | |||
166 | if (cpu_is_omap24xx() && dma_trigger) { | 167 | if (cpu_is_omap24xx() && dma_trigger) { |
167 | u32 val = OMAP_DMA_CCR_REG(lch); | 168 | u32 val = OMAP_DMA_CCR_REG(lch); |
168 | 169 | ||
170 | val &= ~(3 << 19); | ||
169 | if (dma_trigger > 63) | 171 | if (dma_trigger > 63) |
170 | val |= 1 << 20; | 172 | val |= 1 << 20; |
171 | if (dma_trigger > 31) | 173 | if (dma_trigger > 31) |
172 | val |= 1 << 19; | 174 | val |= 1 << 19; |
173 | 175 | ||
176 | val &= ~(0x1f); | ||
174 | val |= (dma_trigger & 0x1f); | 177 | val |= (dma_trigger & 0x1f); |
175 | 178 | ||
176 | if (sync_mode & OMAP_DMA_SYNC_FRAME) | 179 | if (sync_mode & OMAP_DMA_SYNC_FRAME) |
177 | val |= 1 << 5; | 180 | val |= 1 << 5; |
181 | else | ||
182 | val &= ~(1 << 5); | ||
178 | 183 | ||
179 | if (sync_mode & OMAP_DMA_SYNC_BLOCK) | 184 | if (sync_mode & OMAP_DMA_SYNC_BLOCK) |
180 | val |= 1 << 18; | 185 | val |= 1 << 18; |
186 | else | ||
187 | val &= ~(1 << 18); | ||
181 | 188 | ||
182 | if (src_or_dst_synch) | 189 | if (src_or_dst_synch) |
183 | val |= 1 << 24; /* source synch */ | 190 | val |= 1 << 24; /* source synch */ |
@@ -286,22 +293,39 @@ void omap_set_dma_src_data_pack(int lch, int enable) | |||
286 | 293 | ||
287 | void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) | 294 | void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) |
288 | { | 295 | { |
296 | unsigned int burst = 0; | ||
289 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); | 297 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7); |
290 | 298 | ||
291 | switch (burst_mode) { | 299 | switch (burst_mode) { |
292 | case OMAP_DMA_DATA_BURST_DIS: | 300 | case OMAP_DMA_DATA_BURST_DIS: |
293 | break; | 301 | break; |
294 | case OMAP_DMA_DATA_BURST_4: | 302 | case OMAP_DMA_DATA_BURST_4: |
295 | OMAP_DMA_CSDP_REG(lch) |= (0x02 << 7); | 303 | if (cpu_is_omap24xx()) |
304 | burst = 0x1; | ||
305 | else | ||
306 | burst = 0x2; | ||
296 | break; | 307 | break; |
297 | case OMAP_DMA_DATA_BURST_8: | 308 | case OMAP_DMA_DATA_BURST_8: |
298 | /* not supported by current hardware | 309 | if (cpu_is_omap24xx()) { |
310 | burst = 0x2; | ||
311 | break; | ||
312 | } | ||
313 | /* not supported by current hardware on OMAP1 | ||
299 | * w |= (0x03 << 7); | 314 | * w |= (0x03 << 7); |
300 | * fall through | 315 | * fall through |
301 | */ | 316 | */ |
317 | case OMAP_DMA_DATA_BURST_16: | ||
318 | if (cpu_is_omap24xx()) { | ||
319 | burst = 0x3; | ||
320 | break; | ||
321 | } | ||
322 | /* OMAP1 don't support burst 16 | ||
323 | * fall through | ||
324 | */ | ||
302 | default: | 325 | default: |
303 | BUG(); | 326 | BUG(); |
304 | } | 327 | } |
328 | OMAP_DMA_CSDP_REG(lch) |= (burst << 7); | ||
305 | } | 329 | } |
306 | 330 | ||
307 | /* Note that dest_port is only for OMAP1 */ | 331 | /* Note that dest_port is only for OMAP1 */ |
@@ -348,30 +372,49 @@ void omap_set_dma_dest_data_pack(int lch, int enable) | |||
348 | 372 | ||
349 | void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) | 373 | void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) |
350 | { | 374 | { |
375 | unsigned int burst = 0; | ||
351 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); | 376 | OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14); |
352 | 377 | ||
353 | switch (burst_mode) { | 378 | switch (burst_mode) { |
354 | case OMAP_DMA_DATA_BURST_DIS: | 379 | case OMAP_DMA_DATA_BURST_DIS: |
355 | break; | 380 | break; |
356 | case OMAP_DMA_DATA_BURST_4: | 381 | case OMAP_DMA_DATA_BURST_4: |
357 | OMAP_DMA_CSDP_REG(lch) |= (0x02 << 14); | 382 | if (cpu_is_omap24xx()) |
383 | burst = 0x1; | ||
384 | else | ||
385 | burst = 0x2; | ||
358 | break; | 386 | break; |
359 | case OMAP_DMA_DATA_BURST_8: | 387 | case OMAP_DMA_DATA_BURST_8: |
360 | OMAP_DMA_CSDP_REG(lch) |= (0x03 << 14); | 388 | if (cpu_is_omap24xx()) |
389 | burst = 0x2; | ||
390 | else | ||
391 | burst = 0x3; | ||
361 | break; | 392 | break; |
393 | case OMAP_DMA_DATA_BURST_16: | ||
394 | if (cpu_is_omap24xx()) { | ||
395 | burst = 0x3; | ||
396 | break; | ||
397 | } | ||
398 | /* OMAP1 don't support burst 16 | ||
399 | * fall through | ||
400 | */ | ||
362 | default: | 401 | default: |
363 | printk(KERN_ERR "Invalid DMA burst mode\n"); | 402 | printk(KERN_ERR "Invalid DMA burst mode\n"); |
364 | BUG(); | 403 | BUG(); |
365 | return; | 404 | return; |
366 | } | 405 | } |
406 | OMAP_DMA_CSDP_REG(lch) |= (burst << 14); | ||
367 | } | 407 | } |
368 | 408 | ||
369 | static inline void omap_enable_channel_irq(int lch) | 409 | static inline void omap_enable_channel_irq(int lch) |
370 | { | 410 | { |
371 | u32 status; | 411 | u32 status; |
372 | 412 | ||
373 | /* Read CSR to make sure it's cleared. */ | 413 | /* Clear CSR */ |
374 | status = OMAP_DMA_CSR_REG(lch); | 414 | if (cpu_class_is_omap1()) |
415 | status = OMAP_DMA_CSR_REG(lch); | ||
416 | else if (cpu_is_omap24xx()) | ||
417 | OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; | ||
375 | 418 | ||
376 | /* Enable some nice interrupts. */ | 419 | /* Enable some nice interrupts. */ |
377 | OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; | 420 | OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs; |
@@ -470,11 +513,13 @@ int omap_request_dma(int dev_id, const char *dev_name, | |||
470 | chan->dev_name = dev_name; | 513 | chan->dev_name = dev_name; |
471 | chan->callback = callback; | 514 | chan->callback = callback; |
472 | chan->data = data; | 515 | chan->data = data; |
473 | chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | | 516 | chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ; |
474 | OMAP_DMA_BLOCK_IRQ; | ||
475 | 517 | ||
476 | if (cpu_is_omap24xx()) | 518 | if (cpu_class_is_omap1()) |
477 | chan->enabled_irqs |= OMAP2_DMA_TRANS_ERR_IRQ; | 519 | chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ; |
520 | else if (cpu_is_omap24xx()) | ||
521 | chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ | | ||
522 | OMAP2_DMA_TRANS_ERR_IRQ; | ||
478 | 523 | ||
479 | if (cpu_is_omap16xx()) { | 524 | if (cpu_is_omap16xx()) { |
480 | /* If the sync device is set, configure it dynamically. */ | 525 | /* If the sync device is set, configure it dynamically. */ |
@@ -494,7 +539,7 @@ int omap_request_dma(int dev_id, const char *dev_name, | |||
494 | 539 | ||
495 | omap_enable_channel_irq(free_ch); | 540 | omap_enable_channel_irq(free_ch); |
496 | /* Clear the CSR register and IRQ status register */ | 541 | /* Clear the CSR register and IRQ status register */ |
497 | OMAP_DMA_CSR_REG(free_ch) = 0x0; | 542 | OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK; |
498 | omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0); | 543 | omap_writel(~0x0, OMAP_DMA4_IRQSTATUS_L0); |
499 | } | 544 | } |
500 | 545 | ||
@@ -534,7 +579,7 @@ void omap_free_dma(int lch) | |||
534 | omap_writel(val, OMAP_DMA4_IRQENABLE_L0); | 579 | omap_writel(val, OMAP_DMA4_IRQENABLE_L0); |
535 | 580 | ||
536 | /* Clear the CSR register and IRQ status register */ | 581 | /* Clear the CSR register and IRQ status register */ |
537 | OMAP_DMA_CSR_REG(lch) = 0x0; | 582 | OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK; |
538 | 583 | ||
539 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); | 584 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); |
540 | val |= 1 << lch; | 585 | val |= 1 << lch; |
@@ -798,7 +843,7 @@ static int omap1_dma_handle_ch(int ch) | |||
798 | "%d (CSR %04x)\n", ch, csr); | 843 | "%d (CSR %04x)\n", ch, csr); |
799 | return 0; | 844 | return 0; |
800 | } | 845 | } |
801 | if (unlikely(csr & OMAP_DMA_TOUT_IRQ)) | 846 | if (unlikely(csr & OMAP1_DMA_TOUT_IRQ)) |
802 | printk(KERN_WARNING "DMA timeout with device %d\n", | 847 | printk(KERN_WARNING "DMA timeout with device %d\n", |
803 | dma_chan[ch].dev_id); | 848 | dma_chan[ch].dev_id); |
804 | if (unlikely(csr & OMAP_DMA_DROP_IRQ)) | 849 | if (unlikely(csr & OMAP_DMA_DROP_IRQ)) |
@@ -846,20 +891,21 @@ static int omap2_dma_handle_ch(int ch) | |||
846 | return 0; | 891 | return 0; |
847 | if (unlikely(dma_chan[ch].dev_id == -1)) | 892 | if (unlikely(dma_chan[ch].dev_id == -1)) |
848 | return 0; | 893 | return 0; |
849 | /* REVISIT: According to 24xx TRM, there's no TOUT_IE */ | ||
850 | if (unlikely(status & OMAP_DMA_TOUT_IRQ)) | ||
851 | printk(KERN_INFO "DMA timeout with device %d\n", | ||
852 | dma_chan[ch].dev_id); | ||
853 | if (unlikely(status & OMAP_DMA_DROP_IRQ)) | 894 | if (unlikely(status & OMAP_DMA_DROP_IRQ)) |
854 | printk(KERN_INFO | 895 | printk(KERN_INFO |
855 | "DMA synchronization event drop occurred with device " | 896 | "DMA synchronization event drop occurred with device " |
856 | "%d\n", dma_chan[ch].dev_id); | 897 | "%d\n", dma_chan[ch].dev_id); |
857 | |||
858 | if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) | 898 | if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) |
859 | printk(KERN_INFO "DMA transaction error with device %d\n", | 899 | printk(KERN_INFO "DMA transaction error with device %d\n", |
860 | dma_chan[ch].dev_id); | 900 | dma_chan[ch].dev_id); |
901 | if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ)) | ||
902 | printk(KERN_INFO "DMA secure error with device %d\n", | ||
903 | dma_chan[ch].dev_id); | ||
904 | if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ)) | ||
905 | printk(KERN_INFO "DMA misaligned error with device %d\n", | ||
906 | dma_chan[ch].dev_id); | ||
861 | 907 | ||
862 | OMAP_DMA_CSR_REG(ch) = 0x20; | 908 | OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK; |
863 | 909 | ||
864 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); | 910 | val = omap_readl(OMAP_DMA4_IRQSTATUS_L0); |
865 | /* ch in this function is from 0-31 while in register it is 1-32 */ | 911 | /* ch in this function is from 0-31 while in register it is 1-32 */ |