From: Suraj Gupta <suraj.gupta2@amd.com>
To: <andrew+netdev@lunn.ch>, <davem@davemloft.net>, <kuba@kernel.org>,
<pabeni@redhat.com>, <michal.simek@amd.com>, <vkoul@kernel.org>,
<radhey.shyam.pandey@amd.com>
Cc: <netdev@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, <dmaengine@vger.kernel.org>,
<harini.katakam@amd.com>
Subject: [PATCH V2 3/4] dmaengine: xilinx_dma: Add support to configure/report coalesce parameters from/to client using AXI DMA
Date: Thu, 10 Jul 2025 15:42:28 +0530 [thread overview]
Message-ID: <20250710101229.804183-4-suraj.gupta2@amd.com> (raw)
In-Reply-To: <20250710101229.804183-1-suraj.gupta2@amd.com>
AXI DMA supports interrupt coalescing. Client can fine-tune coalesce
parameters based on transaction load. Add support to configure/
report coalesce parameters.
Change delay setting to scale with SG clock rate rather than being a
fixed number of clock cycles (Referred from AXI ethernet driver).
Increase Buffer Descriptors ring size from 512 to 1024 to allow
sufficient space in BD ring during max coalesce count of 255.
Signed-off-by: Suraj Gupta <suraj.gupta2@amd.com>
---
drivers/dma/xilinx/xilinx_dma.c | 73 +++++++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 7 deletions(-)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 187749b7b8a6..26f328cd3e10 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -33,6 +33,7 @@
*
*/
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/dmapool.h>
#include <linux/dma/xilinx_dma.h>
@@ -159,6 +160,9 @@
XILINX_DMA_DMASR_SOF_EARLY_ERR | \
XILINX_DMA_DMASR_DMA_INT_ERR)
+/* Constant to convert delay counts to microseconds */
+#define XILINX_DMA_DELAY_SCALE (125ULL * USEC_PER_SEC)
+
/* Axi VDMA Flush on Fsync bits */
#define XILINX_DMA_FLUSH_S2MM 3
#define XILINX_DMA_FLUSH_MM2S 2
@@ -184,7 +188,7 @@
#define XILINX_DMA_BD_EOP BIT(26)
#define XILINX_DMA_BD_COMP_MASK BIT(31)
#define XILINX_DMA_COALESCE_MAX 255
-#define XILINX_DMA_NUM_DESCS 512
+#define XILINX_DMA_NUM_DESCS 1024
#define XILINX_DMA_NUM_APP_WORDS 5
/* AXI CDMA Specific Registers/Offsets */
@@ -403,6 +407,7 @@ struct xilinx_dma_tx_descriptor {
* @terminating: Check for channel being synchronized by user
* @tasklet: Cleanup work after irq
* @config: Device configuration info
+ * @slave_cfg: Device configuration info from Dmaengine
* @flush_on_fsync: Flush on Frame sync
* @desc_pendingcount: Descriptor pending count
* @ext_addr: Indicates 64 bit addressing is supported by dma channel
@@ -442,6 +447,7 @@ struct xilinx_dma_chan {
bool terminating;
struct tasklet_struct tasklet;
struct xilinx_vdma_config config;
+ struct dma_slave_config slave_cfg;
bool flush_on_fsync;
u32 desc_pendingcount;
bool ext_addr;
@@ -1540,7 +1546,9 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
{
struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
struct xilinx_axidma_tx_segment *tail_segment;
- u32 reg;
+ struct dma_slave_config *slave_cfg = &chan->slave_cfg;
+ u64 clk_rate;
+ u32 reg, usec, timer;
if (chan->err)
return;
@@ -1561,14 +1569,32 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
- if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
- reg &= ~XILINX_DMA_CR_COALESCE_MAX;
+ reg &= ~XILINX_DMA_CR_COALESCE_MAX;
+ reg &= ~XILINX_DMA_CR_DELAY_MAX;
+
+ /* Use dma_slave_config if it has valid values */
+ if (slave_cfg->coalesce_cnt &&
+ slave_cfg->coalesce_cnt <= XILINX_DMA_COALESCE_MAX)
+ reg |= slave_cfg->coalesce_cnt <<
+ XILINX_DMA_CR_COALESCE_SHIFT;
+ else if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX)
reg |= chan->desc_pendingcount <<
XILINX_DMA_CR_COALESCE_SHIFT;
- }
- reg &= ~XILINX_DMA_CR_DELAY_MAX;
- reg |= chan->irq_delay << XILINX_DMA_CR_DELAY_SHIFT;
+ if (slave_cfg->coalesce_usecs <= XILINX_DMA_DMACR_DELAY_MAX)
+ usec = slave_cfg->coalesce_usecs;
+ else
+ usec = chan->irq_delay;
+
+ /* Scale with SG clock rate rather than being a fixed number of
+ * clock cycles.
+ * 1 Timeout Interval = 125 * (clock period of SG clock)
+ */
+ clk_rate = clk_get_rate(chan->xdev->rx_clk);
+ timer = DIV64_U64_ROUND_CLOSEST((u64)usec * clk_rate,
+ XILINX_DMA_DELAY_SCALE);
+ timer = min(timer, FIELD_MAX(XILINX_DMA_DMACR_DELAY_MASK));
+ reg |= timer << XILINX_DMA_CR_DELAY_SHIFT;
dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg);
if (chan->idle)
@@ -1701,9 +1727,41 @@ static void xilinx_dma_issue_pending(struct dma_chan *dchan)
static int xilinx_dma_device_config(struct dma_chan *dchan,
struct dma_slave_config *config)
{
+ struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+
+ if (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA)
+ return 0;
+
+ if (!config->coalesce_cnt ||
+ config->coalesce_cnt > XILINX_DMA_DMACR_FRAME_COUNT_MAX ||
+ config->coalesce_usecs > XILINX_DMA_DMACR_DELAY_MAX)
+ return -EINVAL;
+
+ chan->slave_cfg.coalesce_cnt = config->coalesce_cnt;
+ chan->slave_cfg.coalesce_usecs = config->coalesce_usecs;
+
return 0;
}
+static void xilinx_dma_device_caps(struct dma_chan *dchan,
+ struct dma_slave_caps *caps)
+{
+ struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+ u64 clk_rate, timer;
+ u32 reg;
+
+ if (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA)
+ return;
+
+ reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
+ caps->coalesce_cnt = FIELD_GET(XILINX_DMA_CR_COALESCE_MAX, reg);
+
+ clk_rate = clk_get_rate(chan->xdev->rx_clk);
+ timer = FIELD_GET(XILINX_DMA_CR_DELAY_MAX, reg);
+ caps->coalesce_usecs = DIV64_U64_ROUND_CLOSEST(timer * XILINX_DMA_DELAY_SCALE,
+ clk_rate);
+}
+
/**
* xilinx_dma_complete_descriptor - Mark the active descriptor as complete
* @chan : xilinx DMA channel
@@ -3178,6 +3236,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
xdev->common.device_tx_status = xilinx_dma_tx_status;
xdev->common.device_issue_pending = xilinx_dma_issue_pending;
xdev->common.device_config = xilinx_dma_device_config;
+ xdev->common.device_caps = xilinx_dma_device_caps;
if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask);
xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg;
--
2.25.1
next prev parent reply other threads:[~2025-07-10 10:12 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-10 10:12 [PATCH V2 0/4] Add ethtool support to configure irq coalescing count and delay Suraj Gupta
2025-07-10 10:12 ` [PATCH V2 1/4] dmaengine: Add support to configure and read IRQ coalescing parameters Suraj Gupta
2025-07-23 7:30 ` Vinod Koul
2025-07-23 11:49 ` Gupta, Suraj
2025-08-25 6:17 ` Gupta, Suraj
2025-08-25 11:30 ` Vinod Koul
2025-07-10 10:12 ` [PATCH V2 2/4] dmaengine: xilinx_dma: Fix irq handler and start transfer path for AXI DMA Suraj Gupta
2025-07-10 11:26 ` Simon Horman
2025-07-11 5:32 ` Folker Schwesinger
2025-07-11 16:26 ` Subbaraya Sundeep
2025-07-11 20:13 ` Gupta, Suraj
2025-07-12 5:36 ` Subbaraya Sundeep
2025-07-15 11:05 ` Pandey, Radhey Shyam
2025-07-10 10:12 ` Suraj Gupta [this message]
2025-07-10 10:12 ` [PATCH V2 4/4] net: xilinx: axienet: Add ethtool support to configure/report irq coalescing parameters in DMAengine flow Suraj Gupta
2025-07-11 16:33 ` Subbaraya Sundeep
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250710101229.804183-4-suraj.gupta2@amd.com \
--to=suraj.gupta2@amd.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=dmaengine@vger.kernel.org \
--cc=harini.katakam@amd.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michal.simek@amd.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=radhey.shyam.pandey@amd.com \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®