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 */ | 
