From patchwork Fri Nov 24 15:09:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13467771 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="mn28l1hd" Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::222]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A1155199B for ; Fri, 24 Nov 2023 07:09:25 -0800 (PST) Received: by mail.gandi.net (Postfix) with ESMTPSA id F2C6D4000A; Fri, 24 Nov 2023 15:09:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1700838564; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oO52fbsCOZFdHIXi/jDGUrQo9botuIhFbs+S183F+ko=; b=mn28l1hdMReN3fjO9JtSoasc9agrAHGsPrpMfFLZ65tzY1kdA0yP89qma7QtK9bjpwV0GN I++5pBsrCjCkcnPuS/z8JaErzkmeI9amXHeCHOQIrqbGx2cxUTepXlPsuCbkrCM0Y0W4sC 1CZ0vpfBVzSdk9msGWbjBXjS4e3NV8QO2OhO0shjEyQk7AjP+WO9KtuIrgWpVe2Jk7VybS 9XG7oqd/ACYytvZEtWCd1b2/bY80DfQx6onEZu8IAMlYHrWnOeNl4ugY4EeGzXL/EBN6u+ ELdytyBByAySmDnGKSCDRvN8E3EHI3P2QQhg73lMR5bjLBg1hrUmNsto9a6WnQ== From: Miquel Raynal To: Vinod Koul , Lizhi Hou , Brian Xu , Raj Kumar Rampelli , dmaengine@vger.kernel.org Cc: Michal Simek , Thomas Petazzoni , Miquel Raynal Subject: [PATCH 1/3] dmaengine: xilinx: xdma: Fix the count of elapsed periods in cyclic mode Date: Fri, 24 Nov 2023 16:09:21 +0100 Message-Id: <20231124150923.257687-2-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231124150923.257687-1-miquel.raynal@bootlin.com> References: <20231124150923.257687-1-miquel.raynal@bootlin.com> Precedence: bulk X-Mailing-List: dmaengine@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: miquel.raynal@bootlin.com Xilinx DMA engine is capable of keeping track of the number of elapsed periods and this is an increasing 32-bit counter which is only reset when turning off the engine. No need to add this value to our local counter. Fixes: cd8c732ce1a5 ("dmaengine: xilinx: xdma: Support cyclic transfers") Signed-off-by: Miquel Raynal --- Hello, so far all my testing was performed by looping the playback output to the recording input and comparing the files using FFTs. Unfortunately, when the DMA engine suffers from the same issue on both sides, some issues may appear un-noticed, which is likely what happened here as the tooling did not report any issue while analyzing the output until I actually listened to real audio now that I have in my hands the relevant hardware/connectors to do so. --- drivers/dma/xilinx/xdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index 84a88029226f..75533e787414 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -754,7 +754,7 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) if (ret) goto out; - desc->completed_desc_num += complete_desc_num; + desc->completed_desc_num = complete_desc_num; if (desc->cyclic) { ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS, From patchwork Fri Nov 24 15:09:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13467768 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="PKlUHei4" Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [IPv6:2001:4b98:dc4:8::222]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F08019A2 for ; Fri, 24 Nov 2023 07:09:25 -0800 (PST) Received: by mail.gandi.net (Postfix) with ESMTPSA id 6E99D40016; Fri, 24 Nov 2023 15:09:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1700838564; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=kdneLdQtosT/1Jsu3ffIIlGLAwKem6GqvHil4BjQ5vY=; b=PKlUHei4HMuOdPC0gO0/8wbvWRsY09RLrQZDqljb2e113q5tDn9+FxmwmIQ5c/+VInBJMx I6aVp1jNK8rSgZ7wbL0CqcrH/EFq8Roj6YVyfYP9Kw2i0RaqhDMocLuRLS494BMDj7eAhe 3HyK+0xkERgz5BcC4zAgy/QiheRiV8J9F10RMIPO8Q5PdkjVjoLhBxkWRsUIUaTbZwKgit 2t7ddWpNADhDKvqNkcXhT6L+nVwZZFlUdfgpmsqm0KSq91rwP8cYAvMKbNuYPR1K2TVJAK odyu0trY1JD4etZ8MBRYqvI4M4zbbZuAXrMa9o9wtYUFR8v6KZ/RaZs0FaRITQ== From: Miquel Raynal To: Vinod Koul , Lizhi Hou , Brian Xu , Raj Kumar Rampelli , dmaengine@vger.kernel.org Cc: Michal Simek , Thomas Petazzoni , Miquel Raynal Subject: [PATCH 2/3] dmaengine: xilinx: xdma: Better handling of the busy variable Date: Fri, 24 Nov 2023 16:09:22 +0100 Message-Id: <20231124150923.257687-3-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231124150923.257687-1-miquel.raynal@bootlin.com> References: <20231124150923.257687-1-miquel.raynal@bootlin.com> Precedence: bulk X-Mailing-List: dmaengine@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: miquel.raynal@bootlin.com The driver internal scatter-gather logic is: - set busy to true - start transfer - set busy to false - trigger next transfer if any - set busy to true Setting busy to false in cyclic transfers does not make any sense and is conceptually wrong. In order to ease the integration of additional callbacks let's move this change to a scatter-gather-only path. Signed-off-by: Miquel Raynal --- --- drivers/dma/xilinx/xdma.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index 75533e787414..caddd741a79c 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -745,7 +745,6 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) if (!vd) goto out; - xchan->busy = false; desc = to_xdma_desc(vd); xdev = xchan->xdev_hdl; @@ -768,6 +767,8 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id) goto out; } + xchan->busy = false; + /* * if all data blocks are transferred, remove and complete the request */ From patchwork Fri Nov 24 15:09:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 13467769 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="ND2+0CbI" Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7A9FD93 for ; Fri, 24 Nov 2023 07:09:26 -0800 (PST) Received: by mail.gandi.net (Postfix) with ESMTPSA id DE00440004; Fri, 24 Nov 2023 15:09:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1700838565; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Cueb4lxVm2fT2ZPGf++TonvT2CunFkXPK1b8+bsLe60=; b=ND2+0CbIHOmA4en6Y5HeGz5xIvhpAErTSmBJf0meBJgpsUmMqLc92ZK/z8kpGUZvCvAd5o 7iyG+NK1WBu41vpCdwYSPPP41uMk9tagemusq25tzo0dUEvYc+XeEZlo6ob0IXicWiAtIY 4ec2FD8fO0gaCp2vUIG9hUrGqAF7luGp8+cs1DVqmnQqVp4SSyAtfIvWwq/84h0IEMNMTP CxBXw0MaBNghZxHw7jANB3BEiLU/S8kdVZOXFqTi5y03IDnck94PH3n0U5EfFt87ArYSD0 NnYas6/bi+6sL73UfFZlJLe9/KjII/sG4nuqV4p7kl8a+ftVlA8bFU45wy25hQ== From: Miquel Raynal To: Vinod Koul , Lizhi Hou , Brian Xu , Raj Kumar Rampelli , dmaengine@vger.kernel.org Cc: Michal Simek , Thomas Petazzoni , Miquel Raynal Subject: [PATCH 3/3] dmaengine: xilinx: xdma: Add terminate_all/synchronize callbacks Date: Fri, 24 Nov 2023 16:09:23 +0100 Message-Id: <20231124150923.257687-4-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231124150923.257687-1-miquel.raynal@bootlin.com> References: <20231124150923.257687-1-miquel.raynal@bootlin.com> Precedence: bulk X-Mailing-List: dmaengine@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-GND-Sasl: miquel.raynal@bootlin.com The driver is capable of starting scatter-gather transfers and needs to wait until their end. It is also capable of starting cyclic transfers and will only be "reset" next time the channel will be reused. In practice most of the time we hear no audio glitch because the sound card stops the flow on its side so the DMA transfers are just discarded. There are however some cases (when playing a bit with a number of frames and with a discontinuous sound file) when the sound card seems to be slightly too slow at stopping the flow, leading to a glitch that can be heard. In all cases, we need to earn better control of the DMA engine and adding proper ->device_terminate_all() and ->device_synchronize() callbacks feels totally relevant. With these two callbacks, no glitch can be heard anymore. Fixes: cd8c732ce1a5 ("dmaengine: xilinx: xdma: Support cyclic transfers") Signed-off-by: Miquel Raynal --- This was only tested with cyclic transfers. --- drivers/dma/xilinx/xdma.c | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index caddd741a79c..3dfa4a35eb15 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -371,6 +371,31 @@ static int xdma_xfer_start(struct xdma_chan *xchan) return ret; xchan->busy = true; + + return 0; +} + +/** + * xdma_xfer_stop - Stop DMA transfer + * @xchan: DMA channel pointer + */ +static int xdma_xfer_stop(struct xdma_chan *xchan) +{ + struct virt_dma_desc *vd = vchan_next_desc(&xchan->vchan); + struct xdma_device *xdev = xchan->xdev_hdl; + int ret; + + if (!vd || !xchan->busy) + return -EINVAL; + + /* clear run stop bit to prevent any further auto-triggering */ + ret = regmap_write(xdev->rmap, xchan->base + XDMA_CHAN_CONTROL_W1C, + CHAN_CTRL_RUN_STOP); + if (ret) + return ret; + + xchan->busy = false; + return 0; } @@ -475,6 +500,47 @@ static void xdma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags); } +/** + * xdma_terminate_all - Terminate all transactions + * @chan: DMA channel pointer + */ +static int xdma_terminate_all(struct dma_chan *chan) +{ + struct xdma_chan *xdma_chan = to_xdma_chan(chan); + struct xdma_desc *desc = NULL; + struct virt_dma_desc *vd; + unsigned long flags; + LIST_HEAD(head); + + spin_lock_irqsave(&xdma_chan->vchan.lock, flags); + xdma_xfer_stop(xdma_chan); + + vd = vchan_next_desc(&xdma_chan->vchan); + if (vd) + desc = to_xdma_desc(vd); + if (desc) { + dma_cookie_complete(&desc->vdesc.tx); + vchan_terminate_vdesc(&desc->vdesc); + } + + vchan_get_all_descriptors(&xdma_chan->vchan, &head); + spin_unlock_irqrestore(&xdma_chan->vchan.lock, flags); + vchan_dma_desc_free_list(&xdma_chan->vchan, &head); + + return 0; +} + +/** + * xdma_synchronize - Synchronize terminated transactions + * @chan: DMA channel pointer + */ +static void xdma_synchronize(struct dma_chan *chan) +{ + struct xdma_chan *xdma_chan = to_xdma_chan(chan); + + vchan_synchronize(&xdma_chan->vchan); +} + /** * xdma_prep_device_sg - prepare a descriptor for a DMA transaction * @chan: DMA channel pointer @@ -1090,6 +1156,8 @@ static int xdma_probe(struct platform_device *pdev) xdev->dma_dev.device_prep_slave_sg = xdma_prep_device_sg; xdev->dma_dev.device_config = xdma_device_config; xdev->dma_dev.device_issue_pending = xdma_issue_pending; + xdev->dma_dev.device_terminate_all = xdma_terminate_all; + xdev->dma_dev.device_synchronize = xdma_synchronize; xdev->dma_dev.filter.map = pdata->device_map; xdev->dma_dev.filter.mapcnt = pdata->device_map_cnt; xdev->dma_dev.filter.fn = xdma_filter_fn;