diff options
Diffstat (limited to 'drivers/dma/ep93xx_dma.c')
-rw-r--r-- | drivers/dma/ep93xx_dma.c | 117 |
1 files changed, 93 insertions, 24 deletions
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index f6e9b572b998..c64917ec313d 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c | |||
@@ -71,6 +71,7 @@ | |||
71 | #define M2M_CONTROL_TM_SHIFT 13 | 71 | #define M2M_CONTROL_TM_SHIFT 13 |
72 | #define M2M_CONTROL_TM_TX (1 << M2M_CONTROL_TM_SHIFT) | 72 | #define M2M_CONTROL_TM_TX (1 << M2M_CONTROL_TM_SHIFT) |
73 | #define M2M_CONTROL_TM_RX (2 << M2M_CONTROL_TM_SHIFT) | 73 | #define M2M_CONTROL_TM_RX (2 << M2M_CONTROL_TM_SHIFT) |
74 | #define M2M_CONTROL_NFBINT BIT(21) | ||
74 | #define M2M_CONTROL_RSS_SHIFT 22 | 75 | #define M2M_CONTROL_RSS_SHIFT 22 |
75 | #define M2M_CONTROL_RSS_SSPRX (1 << M2M_CONTROL_RSS_SHIFT) | 76 | #define M2M_CONTROL_RSS_SSPRX (1 << M2M_CONTROL_RSS_SHIFT) |
76 | #define M2M_CONTROL_RSS_SSPTX (2 << M2M_CONTROL_RSS_SHIFT) | 77 | #define M2M_CONTROL_RSS_SSPTX (2 << M2M_CONTROL_RSS_SHIFT) |
@@ -79,7 +80,22 @@ | |||
79 | #define M2M_CONTROL_PWSC_SHIFT 25 | 80 | #define M2M_CONTROL_PWSC_SHIFT 25 |
80 | 81 | ||
81 | #define M2M_INTERRUPT 0x0004 | 82 | #define M2M_INTERRUPT 0x0004 |
82 | #define M2M_INTERRUPT_DONEINT BIT(1) | 83 | #define M2M_INTERRUPT_MASK 6 |
84 | |||
85 | #define M2M_STATUS 0x000c | ||
86 | #define M2M_STATUS_CTL_SHIFT 1 | ||
87 | #define M2M_STATUS_CTL_IDLE (0 << M2M_STATUS_CTL_SHIFT) | ||
88 | #define M2M_STATUS_CTL_STALL (1 << M2M_STATUS_CTL_SHIFT) | ||
89 | #define M2M_STATUS_CTL_MEMRD (2 << M2M_STATUS_CTL_SHIFT) | ||
90 | #define M2M_STATUS_CTL_MEMWR (3 << M2M_STATUS_CTL_SHIFT) | ||
91 | #define M2M_STATUS_CTL_BWCWAIT (4 << M2M_STATUS_CTL_SHIFT) | ||
92 | #define M2M_STATUS_CTL_MASK (7 << M2M_STATUS_CTL_SHIFT) | ||
93 | #define M2M_STATUS_BUF_SHIFT 4 | ||
94 | #define M2M_STATUS_BUF_NO (0 << M2M_STATUS_BUF_SHIFT) | ||
95 | #define M2M_STATUS_BUF_ON (1 << M2M_STATUS_BUF_SHIFT) | ||
96 | #define M2M_STATUS_BUF_NEXT (2 << M2M_STATUS_BUF_SHIFT) | ||
97 | #define M2M_STATUS_BUF_MASK (3 << M2M_STATUS_BUF_SHIFT) | ||
98 | #define M2M_STATUS_DONE BIT(6) | ||
83 | 99 | ||
84 | #define M2M_BCR0 0x0010 | 100 | #define M2M_BCR0 0x0010 |
85 | #define M2M_BCR1 0x0014 | 101 | #define M2M_BCR1 0x0014 |
@@ -426,15 +442,6 @@ static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac) | |||
426 | 442 | ||
427 | /* | 443 | /* |
428 | * M2M DMA implementation | 444 | * M2M DMA implementation |
429 | * | ||
430 | * For the M2M transfers we don't use NFB at all. This is because it simply | ||
431 | * doesn't work well with memcpy transfers. When you submit both buffers it is | ||
432 | * extremely unlikely that you get an NFB interrupt, but it instead reports | ||
433 | * DONE interrupt and both buffers are already transferred which means that we | ||
434 | * weren't able to update the next buffer. | ||
435 | * | ||
436 | * So for now we "simulate" NFB by just submitting buffer after buffer | ||
437 | * without double buffering. | ||
438 | */ | 445 | */ |
439 | 446 | ||
440 | static int m2m_hw_setup(struct ep93xx_dma_chan *edmac) | 447 | static int m2m_hw_setup(struct ep93xx_dma_chan *edmac) |
@@ -543,6 +550,11 @@ static void m2m_hw_submit(struct ep93xx_dma_chan *edmac) | |||
543 | m2m_fill_desc(edmac); | 550 | m2m_fill_desc(edmac); |
544 | control |= M2M_CONTROL_DONEINT; | 551 | control |= M2M_CONTROL_DONEINT; |
545 | 552 | ||
553 | if (ep93xx_dma_advance_active(edmac)) { | ||
554 | m2m_fill_desc(edmac); | ||
555 | control |= M2M_CONTROL_NFBINT; | ||
556 | } | ||
557 | |||
546 | /* | 558 | /* |
547 | * Now we can finally enable the channel. For M2M channel this must be | 559 | * Now we can finally enable the channel. For M2M channel this must be |
548 | * done _after_ the BCRx registers are programmed. | 560 | * done _after_ the BCRx registers are programmed. |
@@ -560,32 +572,89 @@ static void m2m_hw_submit(struct ep93xx_dma_chan *edmac) | |||
560 | } | 572 | } |
561 | } | 573 | } |
562 | 574 | ||
575 | /* | ||
576 | * According to EP93xx User's Guide, we should receive DONE interrupt when all | ||
577 | * M2M DMA controller transactions complete normally. This is not always the | ||
578 | * case - sometimes EP93xx M2M DMA asserts DONE interrupt when the DMA channel | ||
579 | * is still running (channel Buffer FSM in DMA_BUF_ON state, and channel | ||
580 | * Control FSM in DMA_MEM_RD state, observed at least in IDE-DMA operation). | ||
581 | * In effect, disabling the channel when only DONE bit is set could stop | ||
582 | * currently running DMA transfer. To avoid this, we use Buffer FSM and | ||
583 | * Control FSM to check current state of DMA channel. | ||
584 | */ | ||
563 | static int m2m_hw_interrupt(struct ep93xx_dma_chan *edmac) | 585 | static int m2m_hw_interrupt(struct ep93xx_dma_chan *edmac) |
564 | { | 586 | { |
587 | u32 status = readl(edmac->regs + M2M_STATUS); | ||
588 | u32 ctl_fsm = status & M2M_STATUS_CTL_MASK; | ||
589 | u32 buf_fsm = status & M2M_STATUS_BUF_MASK; | ||
590 | bool done = status & M2M_STATUS_DONE; | ||
591 | bool last_done; | ||
565 | u32 control; | 592 | u32 control; |
593 | struct ep93xx_dma_desc *desc; | ||
566 | 594 | ||
567 | if (!(readl(edmac->regs + M2M_INTERRUPT) & M2M_INTERRUPT_DONEINT)) | 595 | /* Accept only DONE and NFB interrupts */ |
596 | if (!(readl(edmac->regs + M2M_INTERRUPT) & M2M_INTERRUPT_MASK)) | ||
568 | return INTERRUPT_UNKNOWN; | 597 | return INTERRUPT_UNKNOWN; |
569 | 598 | ||
570 | /* Clear the DONE bit */ | 599 | if (done) { |
571 | writel(0, edmac->regs + M2M_INTERRUPT); | 600 | /* Clear the DONE bit */ |
601 | writel(0, edmac->regs + M2M_INTERRUPT); | ||
602 | } | ||
572 | 603 | ||
573 | /* Disable interrupts and the channel */ | 604 | /* |
574 | control = readl(edmac->regs + M2M_CONTROL); | 605 | * Check whether we are done with descriptors or not. This, together |
575 | control &= ~(M2M_CONTROL_DONEINT | M2M_CONTROL_ENABLE); | 606 | * with DMA channel state, determines action to take in interrupt. |
576 | writel(control, edmac->regs + M2M_CONTROL); | 607 | */ |
608 | desc = ep93xx_dma_get_active(edmac); | ||
609 | last_done = !desc || desc->txd.cookie; | ||
577 | 610 | ||
578 | /* | 611 | /* |
579 | * Since we only get DONE interrupt we have to find out ourselves | 612 | * Use M2M DMA Buffer FSM and Control FSM to check current state of |
580 | * whether there still is something to process. So we try to advance | 613 | * DMA channel. Using DONE and NFB bits from channel status register |
581 | * the chain an see whether it succeeds. | 614 | * or bits from channel interrupt register is not reliable. |
582 | */ | 615 | */ |
583 | if (ep93xx_dma_advance_active(edmac)) { | 616 | if (!last_done && |
584 | edmac->edma->hw_submit(edmac); | 617 | (buf_fsm == M2M_STATUS_BUF_NO || |
585 | return INTERRUPT_NEXT_BUFFER; | 618 | buf_fsm == M2M_STATUS_BUF_ON)) { |
619 | /* | ||
620 | * Two buffers are ready for update when Buffer FSM is in | ||
621 | * DMA_NO_BUF state. Only one buffer can be prepared without | ||
622 | * disabling the channel or polling the DONE bit. | ||
623 | * To simplify things, always prepare only one buffer. | ||
624 | */ | ||
625 | if (ep93xx_dma_advance_active(edmac)) { | ||
626 | m2m_fill_desc(edmac); | ||
627 | if (done && !edmac->chan.private) { | ||
628 | /* Software trigger for memcpy channel */ | ||
629 | control = readl(edmac->regs + M2M_CONTROL); | ||
630 | control |= M2M_CONTROL_START; | ||
631 | writel(control, edmac->regs + M2M_CONTROL); | ||
632 | } | ||
633 | return INTERRUPT_NEXT_BUFFER; | ||
634 | } else { | ||
635 | last_done = true; | ||
636 | } | ||
637 | } | ||
638 | |||
639 | /* | ||
640 | * Disable the channel only when Buffer FSM is in DMA_NO_BUF state | ||
641 | * and Control FSM is in DMA_STALL state. | ||
642 | */ | ||
643 | if (last_done && | ||
644 | buf_fsm == M2M_STATUS_BUF_NO && | ||
645 | ctl_fsm == M2M_STATUS_CTL_STALL) { | ||
646 | /* Disable interrupts and the channel */ | ||
647 | control = readl(edmac->regs + M2M_CONTROL); | ||
648 | control &= ~(M2M_CONTROL_DONEINT | M2M_CONTROL_NFBINT | ||
649 | | M2M_CONTROL_ENABLE); | ||
650 | writel(control, edmac->regs + M2M_CONTROL); | ||
651 | return INTERRUPT_DONE; | ||
586 | } | 652 | } |
587 | 653 | ||
588 | return INTERRUPT_DONE; | 654 | /* |
655 | * Nothing to do this time. | ||
656 | */ | ||
657 | return INTERRUPT_NEXT_BUFFER; | ||
589 | } | 658 | } |
590 | 659 | ||
591 | /* | 660 | /* |