From nobody Sun Oct 5 00:17:44 2025 Received: from www522.your-server.de (www522.your-server.de [195.201.215.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D62918C322; Mon, 11 Aug 2025 19:46:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.201.215.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754941578; cv=none; b=BmyKpLY6M+fDpgjKFiDHNya4oq6GZ2A4M4Uyu/X5uWfY3TbkysUv1x51X9G8EZA6YeDDF5jiYpQa4dauPd8zcbrkb4D0GgJkLFerARTY1CD32uZnmpmgPc+9txwD6b2Lc7QZnrcTQ/xbyQf8Uc2Kr9+7fAIn2LOI3RtEx2I8NCM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754941578; c=relaxed/simple; bh=N6GHB/ahgUbmi+yED3AjLdK6t8K0zonzpYaVdq1u1H4=; h=Message-Id:Cc:To:From:Date:Subject; b=g74sBUOC4lUy5+KD389ZoUSMMjKaKy3gWybjd822qDnUBEojWFy3ac66jb+slEAjmgyr8QVV5TJ9eEK0CuEKGBFdYGoyp2v0vK5pAH5HzNSWBVwUBfBR/dbiy5QNYMHtFDnCEnDB6/lFNkLrylqBCbaNwTP+F8kP7cH9ITARgs8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=folker-schwesinger.de; spf=pass smtp.mailfrom=folker-schwesinger.de; dkim=pass (2048-bit key) header.d=folker-schwesinger.de header.i=@folker-schwesinger.de header.b=D2WzmqmK; arc=none smtp.client-ip=195.201.215.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=folker-schwesinger.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=folker-schwesinger.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=folker-schwesinger.de header.i=@folker-schwesinger.de header.b="D2WzmqmK" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=folker-schwesinger.de; s=default2212; h=Subject:Date:From:To:Cc:Message-Id: Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References; bh=ThKptu1Z4PVKyQbUsbmM9Z1W7xxTizz6/uivJLE43rQ=; b=D2WzmqmKTI59POEc8bYlFQos60 0Y1SZvAOvo3oDkaKyewhotd4fD5ZW4ODfce0MkSOJFb190cvACk1DV0KWychKrhyBboVbV/cwthPc ISAgRCtzwcgXUJL8AOTdiE256ENnuyqhh30sFRlB1vckf4aOzWCwazLnXNGrGXZnRok2dtMtwVPSD 3mER2cUpWdKAELjrCs/JGCJbjxKpwwS8vFmvFiokwLYfvqM9AHZ8IHYIgTjPd9KGfR/svSeF3fwB+ iX/7bv6hfMuSi/GcnGoMVF+AjvLpb1+ZqvTiQs9/3wXsHdtxnpYzTNiSkETiwAlD9lSLcm72Qk3VV owPCpY3w==; Received: from sslproxy08.your-server.de ([78.47.166.52]) by www522.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96.2) (envelope-from ) id 1ulYDV-0004c3-2R; Mon, 11 Aug 2025 21:29:57 +0200 Received: from localhost ([127.0.0.1]) by sslproxy08.your-server.de with esmtpsa (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1ulYDV-0003zH-2q; Mon, 11 Aug 2025 21:29:57 +0200 Message-Id: Cc: "Vinod Koul" , "Michal Simek" , "Jernej Skrabec" , "Krzysztof Kozlowski" , =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= , "Marek Vasut" , "Radhey Shyam Pandey" To: , , From: "Folker Schwesinger" Date: Mon, 11 Aug 2025 21:22:59 +0200 Subject: [PATCH v3] dmaengine: xilinx_dma: Support descriptor setup from dma_vecs X-Virus-Scanned: Clear (ClamAV 1.0.7/27729/Mon Aug 11 10:33:11 2025) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The DMAEngine provides an interface for obtaining DMA transaction descriptors from an array of scatter gather buffers represented by struct dma_vec. This interface is used in the DMABUF API of the IIO framework [1]. To enable DMABUF support through the IIO framework for the Xilinx DMA, implement callback .device_prep_peripheral_dma_vec() of struct dma_device in the driver. [1]: https://elixir.bootlin.com/linux/v6.16-rc1/source/drivers/iio/buffer/i= ndustrialio-buffer-dmaengine.c#L104 Signed-off-by: Folker Schwesinger Reviewed-by: Suraj Gupta --- Changes in v3: - Collect R-b tags from v2. - Rebase onto v6.17-rc1. - Link to v2: https://lore.kernel.org/dmaengine/DAQB7EU7UXR3.Z07Q6JQ1V67Y@f= olker-schwesinger.de/ Changes in v2: - Improve commit message to include reasoning behind the change. - Rebase onto v6.16-rc1. - Link to v1: https://lore.kernel.org/dmaengine/D8TV2MP99NTE.1842MMA04VB9N@= folker-schwesinger.de/ --- drivers/dma/xilinx/xilinx_dma.c | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dm= a.c index a34d8f0ceed8..fabff602065f 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -2172,6 +2172,99 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_= addr_t dma_dst, return NULL; } =20 +/** + * xilinx_dma_prep_peripheral_dma_vec - prepare descriptors for a DMA_SLAVE + * transaction from DMA vectors + * @dchan: DMA channel + * @vecs: Array of DMA vectors that should be transferred + * @nb: number of entries in @vecs + * @direction: DMA direction + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor *xilinx_dma_prep_peripheral_dma_vec( + struct dma_chan *dchan, const struct dma_vec *vecs, size_t nb, + enum dma_transfer_direction direction, unsigned long flags) +{ + struct xilinx_dma_chan *chan =3D to_xilinx_chan(dchan); + struct xilinx_dma_tx_descriptor *desc; + struct xilinx_axidma_tx_segment *segment, *head, *prev =3D NULL; + size_t copy; + size_t sg_used; + unsigned int i; + + if (!is_slave_direction(direction) || direction !=3D chan->direction) + return NULL; + + desc =3D xilinx_dma_alloc_tx_descriptor(chan); + if (!desc) + return NULL; + + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit =3D xilinx_dma_tx_submit; + + /* Build transactions using information from DMA vectors */ + for (i =3D 0; i < nb; i++) { + sg_used =3D 0; + + /* Loop until the entire dma_vec entry is used */ + while (sg_used < vecs[i].len) { + struct xilinx_axidma_desc_hw *hw; + + /* Get a free segment */ + segment =3D xilinx_axidma_alloc_tx_segment(chan); + if (!segment) + goto error; + + /* + * Calculate the maximum number of bytes to transfer, + * making sure it is less than the hw limit + */ + copy =3D xilinx_dma_calc_copysize(chan, vecs[i].len, + sg_used); + hw =3D &segment->hw; + + /* Fill in the descriptor */ + xilinx_axidma_buf(chan, hw, vecs[i].addr, sg_used, 0); + hw->control =3D copy; + + if (prev) + prev->hw.next_desc =3D segment->phys; + + prev =3D segment; + sg_used +=3D copy; + + /* + * Insert the segment into the descriptor segments + * list. + */ + list_add_tail(&segment->node, &desc->segments); + } + } + + head =3D list_first_entry(&desc->segments, struct xilinx_axidma_tx_segmen= t, node); + desc->async_tx.phys =3D head->phys; + + /* For the last DMA_MEM_TO_DEV transfer, set EOP */ + if (chan->direction =3D=3D DMA_MEM_TO_DEV) { + segment->hw.control |=3D XILINX_DMA_BD_SOP; + segment =3D list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + segment->hw.control |=3D XILINX_DMA_BD_EOP; + } + + if (chan->xdev->has_axistream_connected) + desc->async_tx.metadata_ops =3D &xilinx_dma_metadata_ops; + + return &desc->async_tx; + +error: + xilinx_dma_free_tx_descriptor(chan, desc); + return NULL; +} + /** * xilinx_dma_prep_slave_sg - prepare descriptors for a DMA_SLAVE transact= ion * @dchan: DMA channel @@ -3180,6 +3273,7 @@ static int xilinx_dma_probe(struct platform_device *p= dev) xdev->common.device_config =3D xilinx_dma_device_config; if (xdev->dma_config->dmatype =3D=3D XDMA_TYPE_AXIDMA) { dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); + xdev->common.device_prep_peripheral_dma_vec =3D xilinx_dma_prep_peripher= al_dma_vec; xdev->common.device_prep_slave_sg =3D xilinx_dma_prep_slave_sg; xdev->common.device_prep_dma_cyclic =3D xilinx_dma_prep_dma_cyclic; base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585 --=20 2.50.1