Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

dmaengine: sh: rz-dmac: Add device_tx_status() callback

The RZ/G2L SCIFA driver uses dmaengine_prep_slave_sg() to enqueue DMA
transfers and implements a timeout mechanism on RX to handle cases where
a DMA transfer does not complete. The timeout is implemented using an
hrtimer.

In the hrtimer callback, dmaengine_tx_status() is called (along with
dmaengine_pause()) to retrieve the transfer residue and handle incomplete
DMA transfers.

Add support for the device_tx_status() callback.

Co-developed-by: Long Luu <long.luu.ur@renesas.com>
Signed-off-by: Long Luu <long.luu.ur@renesas.com>
Signed-off-by: Biju Das <biju.das.jz@bp.renesas.com>
Co-developed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260316133252.240348-8-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Biju Das and committed by
Vinod Koul
21323b11 bfaa60be

+143 -1
+143 -1
drivers/dma/sh/rz-dmac.c
··· 124 124 * Registers 125 125 */ 126 126 127 + #define CRTB 0x0020 127 128 #define CHSTAT 0x0024 128 129 #define CHCTRL 0x0028 129 130 #define CHCFG 0x002c 130 131 #define NXLA 0x0038 132 + #define CRLA 0x003c 131 133 132 134 #define DCTRL 0x0000 133 135 ··· 678 676 rz_dmac_set_dma_req_no(dmac, channel->index, dmac->info->default_dma_req_no); 679 677 } 680 678 679 + static struct rz_lmdesc * 680 + rz_dmac_get_next_lmdesc(struct rz_lmdesc *base, struct rz_lmdesc *lmdesc) 681 + { 682 + struct rz_lmdesc *next = ++lmdesc; 683 + 684 + if (next >= base + DMAC_NR_LMDESC) 685 + next = base; 686 + 687 + return next; 688 + } 689 + 690 + static u32 rz_dmac_calculate_residue_bytes_in_vd(struct rz_dmac_chan *channel, u32 crla) 691 + { 692 + struct rz_lmdesc *lmdesc = channel->lmdesc.head; 693 + struct dma_chan *chan = &channel->vc.chan; 694 + struct rz_dmac *dmac = to_rz_dmac(chan->device); 695 + u32 residue = 0, i = 0; 696 + 697 + while (lmdesc->nxla != crla) { 698 + lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc); 699 + if (++i >= DMAC_NR_LMDESC) 700 + return 0; 701 + } 702 + 703 + /* Calculate residue from next lmdesc to end of virtual desc */ 704 + while (lmdesc->chcfg & CHCFG_DEM) { 705 + residue += lmdesc->tb; 706 + lmdesc = rz_dmac_get_next_lmdesc(channel->lmdesc.base, lmdesc); 707 + } 708 + 709 + dev_dbg(dmac->dev, "%s: VD residue is %u\n", __func__, residue); 710 + 711 + return residue; 712 + } 713 + 714 + static u32 rz_dmac_chan_get_residue(struct rz_dmac_chan *channel, 715 + dma_cookie_t cookie) 716 + { 717 + struct rz_dmac_desc *current_desc, *desc; 718 + enum dma_status status; 719 + u32 crla, crtb, i; 720 + 721 + /* Get current processing virtual descriptor */ 722 + current_desc = list_first_entry(&channel->ld_active, 723 + struct rz_dmac_desc, node); 724 + if (!current_desc) 725 + return 0; 726 + 727 + /* 728 + * If the cookie corresponds to a descriptor that has been completed 729 + * there is no residue. The same check has already been performed by the 730 + * caller but without holding the channel lock, so the descriptor could 731 + * now be complete. 732 + */ 733 + status = dma_cookie_status(&channel->vc.chan, cookie, NULL); 734 + if (status == DMA_COMPLETE) 735 + return 0; 736 + 737 + /* 738 + * If the cookie doesn't correspond to the currently processing virtual 739 + * descriptor then the descriptor hasn't been processed yet, and the 740 + * residue is equal to the full descriptor size. Also, a client driver 741 + * is possible to call this function before rz_dmac_irq_handler_thread() 742 + * runs. In this case, the running descriptor will be the next 743 + * descriptor, and will appear in the done list. So, if the argument 744 + * cookie matches the done list's cookie, we can assume the residue is 745 + * zero. 746 + */ 747 + if (cookie != current_desc->vd.tx.cookie) { 748 + list_for_each_entry(desc, &channel->ld_free, node) { 749 + if (cookie == desc->vd.tx.cookie) 750 + return 0; 751 + } 752 + 753 + list_for_each_entry(desc, &channel->ld_queue, node) { 754 + if (cookie == desc->vd.tx.cookie) 755 + return desc->len; 756 + } 757 + 758 + list_for_each_entry(desc, &channel->ld_active, node) { 759 + if (cookie == desc->vd.tx.cookie) 760 + return desc->len; 761 + } 762 + 763 + /* 764 + * No descriptor found for the cookie, there's thus no residue. 765 + * This shouldn't happen if the calling driver passes a correct 766 + * cookie value. 767 + */ 768 + WARN(1, "No descriptor for cookie!"); 769 + return 0; 770 + } 771 + 772 + /* 773 + * We need to read two registers. Make sure the hardware does not move 774 + * to next lmdesc while reading the current lmdesc. Trying it 3 times 775 + * should be enough: initial read, retry, retry for the paranoid. 776 + */ 777 + for (i = 0; i < 3; i++) { 778 + crla = rz_dmac_ch_readl(channel, CRLA, 1); 779 + crtb = rz_dmac_ch_readl(channel, CRTB, 1); 780 + /* Still the same? */ 781 + if (crla == rz_dmac_ch_readl(channel, CRLA, 1)) 782 + break; 783 + } 784 + 785 + WARN_ONCE(i >= 3, "residue might not be continuous!"); 786 + 787 + /* 788 + * Calculate number of bytes transferred in processing virtual descriptor. 789 + * One virtual descriptor can have many lmdesc. 790 + */ 791 + return crtb + rz_dmac_calculate_residue_bytes_in_vd(channel, crla); 792 + } 793 + 794 + static enum dma_status rz_dmac_tx_status(struct dma_chan *chan, 795 + dma_cookie_t cookie, 796 + struct dma_tx_state *txstate) 797 + { 798 + struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); 799 + enum dma_status status; 800 + u32 residue; 801 + 802 + status = dma_cookie_status(chan, cookie, txstate); 803 + if (status == DMA_COMPLETE || !txstate) 804 + return status; 805 + 806 + scoped_guard(spinlock_irqsave, &channel->vc.lock) 807 + residue = rz_dmac_chan_get_residue(channel, cookie); 808 + 809 + /* if there's no residue, the cookie is complete */ 810 + if (!residue) 811 + return DMA_COMPLETE; 812 + 813 + dma_set_residue(txstate, residue); 814 + 815 + return status; 816 + } 817 + 681 818 /* 682 819 * ----------------------------------------------------------------------------- 683 820 * IRQ handling ··· 1138 997 engine = &dmac->engine; 1139 998 dma_cap_set(DMA_SLAVE, engine->cap_mask); 1140 999 dma_cap_set(DMA_MEMCPY, engine->cap_mask); 1000 + engine->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; 1141 1001 rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_0_7_COMMON_BASE + DCTRL); 1142 1002 rz_dmac_writel(dmac, DCTRL_DEFAULT, CHANNEL_8_15_COMMON_BASE + DCTRL); 1143 1003 ··· 1146 1004 1147 1005 engine->device_alloc_chan_resources = rz_dmac_alloc_chan_resources; 1148 1006 engine->device_free_chan_resources = rz_dmac_free_chan_resources; 1149 - engine->device_tx_status = dma_cookie_status; 1007 + engine->device_tx_status = rz_dmac_tx_status; 1150 1008 engine->device_prep_slave_sg = rz_dmac_prep_slave_sg; 1151 1009 engine->device_prep_dma_memcpy = rz_dmac_prep_dma_memcpy; 1152 1010 engine->device_config = rz_dmac_config;