aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/dma.c')
-rw-r--r--arch/arm/plat-omap/dma.c84
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
287void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) 294void 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
349void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode) 373void 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
369static inline void omap_enable_channel_irq(int lch) 409static 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 */