mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority
@ 2026-09-01  6:16 Jia Wang
  2026-09-01  6:16 ` [PATCH v2 1/4] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Jia Wang @ 2026-09-01  6:16 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang, Frank Li

This series fixes AXI burst length encoding, an out-of-bounds access in
the error-path LLI dump, and the CH_CFG2 channel priority field position.

It also converts register field definitions and programming to GENMASK()
and FIELD_PREP().

The series was tested with dmatest on all eight channels using
snps,axi-max-burst-len = <256>. All channels completed without errors. It
was also build-tested on RISC-V with CONFIG_DW_AXI_DMAC as both a module
and built-in.

Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
Changes in v2:
- Use a loop-local unsigned iterator in the LLI dump helper.
- Add a patch to fix the CH_CFG2 channel priority field position.
- Add a cleanup patch to use GENMASK() and FIELD_PREP() for register fields.
- Link to v1: https://patch.msgid.link/20260828-dma-fix-v1-0-a6947f487e07@ultrarisc.com

To: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
To: Vinod Koul <vkoul@kernel.org>
To: Frank Li <Frank.Li@kernel.org>
To: Pandith N <pandith.n@intel.com>
To: Sia Jee Heng <jee.heng.sia@intel.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: dmaengine@vger.kernel.org
Cc: linux-kernel@vger.kernel.org

---
Jia Wang (4):
      dmaengine: dw-axi-dmac: Fix AXI burst length encoding
      dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
      dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position
      dmaengine: dw-axi-dmac: Use bitfield helpers for registers

 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 78 +++++++++++++-------------
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h          | 44 +++++++--------
 2 files changed, 60 insertions(+), 62 deletions(-)
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260827-dma-fix-c2b27795ce12

Best regards,
--  
Jia Wang <wangjia@ultrarisc.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/4] dmaengine: dw-axi-dmac: Fix AXI burst length encoding
  2026-09-01  6:16 [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority Jia Wang
@ 2026-09-01  6:16 ` Jia Wang
  2026-09-01  6:16 ` [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Jia Wang @ 2026-09-01  6:16 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang, Frank Li

The snps,axi-max-burst-len property describes the number of beats in an
AXI burst, while the ARLEN and AWLEN fields encode that value minus one.

The driver keeps axi_rw_burst_len as the actual burst length so that
dma_device.max_burst reports the correct value. However, it also programs
that unencoded value directly into the hardware fields. A value of 256
therefore overflows the 8-bit fields and can cause AXI decode errors.

Subtract one only when constructing hardware descriptors, while keeping
the actual value for dma_device.max_burst.

Fixes: c454d16a7d5a ("dmaengine: dw-axi-dmac: Burst length settings")
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index eebed2474210..742e08cfab43 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -706,7 +706,7 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
 	ctlhi = CH_CTL_H_LLI_VALID;
 
 	if (chan->chip->dw->hdata->restrict_axi_burst_len) {
-		burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
+		burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 		ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN |
 			 burst_len << CH_CTL_H_ARLEN_POS |
 			 burst_len << CH_CTL_H_AWLEN_POS;
@@ -975,7 +975,7 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
 
 		reg = CH_CTL_H_LLI_VALID;
 		if (chan->chip->dw->hdata->restrict_axi_burst_len) {
-			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len;
+			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 
 			reg |= (CH_CTL_H_ARLEN_EN |
 				burst_len << CH_CTL_H_ARLEN_POS |

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-09-01  6:16 [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority Jia Wang
  2026-09-01  6:16 ` [PATCH v2 1/4] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
@ 2026-09-01  6:16 ` Jia Wang
  2026-09-01 18:53   ` Frank Li
  2026-09-01  6:16 ` [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position Jia Wang
  2026-09-01  6:16 ` [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers Jia Wang
  3 siblings, 1 reply; 9+ messages in thread
From: Jia Wang @ 2026-09-01  6:16 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang

axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
walk the hw_desc[] array of a single transaction. If multiple
transactions have allocated LLIs, the channel count can exceed the
transaction-local nr_hw_descs and make the DMA error path read past the
end of hw_desc[].

Use the descriptor-local nr_hw_descs count when dumping LLIs.

Fixes: ef6fb2d6f1ab ("dmaengine: dw-axi-dmac: simplify descriptor management")
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 742e08cfab43..61230d2b1c56 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -1052,10 +1052,7 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan,
 static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
 				   struct axi_dma_desc *desc_head)
 {
-	int count = atomic_read(&chan->descs_allocated);
-	int i;
-
-	for (i = 0; i < count; i++)
+	for (unsigned int i = 0; i < desc_head->nr_hw_descs; i++)
 		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
 }
 

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position
  2026-09-01  6:16 [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority Jia Wang
  2026-09-01  6:16 ` [PATCH v2 1/4] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
  2026-09-01  6:16 ` [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
@ 2026-09-01  6:16 ` Jia Wang
  2026-09-01 18:55   ` Frank Li
  2026-09-01  6:16 ` [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers Jia Wang
  3 siblings, 1 reply; 9+ messages in thread
From: Jia Wang @ 2026-09-01  6:16 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang

The CH_CFG2 channel priority field occupies bits 51:47 of the 64-bit
channel configuration register, corresponding to bits 19:15 of CH_CFG2_H.

The driver currently shifts the priority value by 20, programming the
wrong bits. Use bit 15 as the field position.

Fixes: 824351668a41 ("dmaengine: dw-axi-dmac: support DMAX_NUM_CHANNELS > 8")
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index 67cc199e24d1..97451bb8b16a 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -327,7 +327,7 @@ enum {
 #define CH_CFG2_H_TT_FC_POS		0
 #define CH_CFG2_H_HS_SEL_SRC_POS	3
 #define CH_CFG2_H_HS_SEL_DST_POS	4
-#define CH_CFG2_H_PRIORITY_POS		20
+#define CH_CFG2_H_PRIORITY_POS		15
 
 /**
  * DW AXI DMA channel interrupts

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers
  2026-09-01  6:16 [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority Jia Wang
                   ` (2 preceding siblings ...)
  2026-09-01  6:16 ` [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position Jia Wang
@ 2026-09-01  6:16 ` Jia Wang
  2026-09-01  7:02   ` Andy Shevchenko
  3 siblings, 1 reply; 9+ messages in thread
From: Jia Wang @ 2026-09-01  6:16 UTC (permalink / raw)
  To: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng
  Cc: dmaengine, linux-kernel, Jia Wang, Frank Li

The driver open-codes several channel configuration and descriptor
control bitfield writes with left shifts. Define masks for those fields
and use FIELD_PREP() when programming the registers.

Valid field values keep the same encoding. FIELD_PREP() confines values
to their respective fields, but does not validate handshake numbers
supplied through DMA specifiers.

Suggested-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
---
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 69 +++++++++++++-------------
 drivers/dma/dw-axi-dmac/dw-axi-dmac.h          | 44 ++++++++--------
 2 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
index 61230d2b1c56..f8ab8d072222 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -7,6 +7,7 @@
  * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
  */
 
+#include <linux/bitfield.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -101,23 +102,23 @@ static inline void axi_chan_config_write(struct axi_dma_chan *chan,
 {
 	u32 cfg_lo, cfg_hi;
 
-	cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
-		  config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
+	cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
+		 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type);
 	if (chan->chip->dw->hdata->reg_map_8_channels &&
 	    !chan->chip->dw->hdata->use_cfg2) {
-		cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
-			 config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
-			 config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
-			 config->src_per << CH_CFG_H_SRC_PER_POS |
-			 config->dst_per << CH_CFG_H_DST_PER_POS |
-			 config->prior << CH_CFG_H_PRIORITY_POS;
+		cfg_hi = FIELD_PREP(CH_CFG_H_TT_FC, config->tt_fc) |
+			 FIELD_PREP(CH_CFG_H_HS_SEL_SRC, config->hs_sel_src) |
+			 FIELD_PREP(CH_CFG_H_HS_SEL_DST, config->hs_sel_dst) |
+			 FIELD_PREP(CH_CFG_H_SRC_PER, config->src_per) |
+			 FIELD_PREP(CH_CFG_H_DST_PER, config->dst_per) |
+			 FIELD_PREP(CH_CFG_H_PRIORITY, config->prior);
 	} else {
-		cfg_lo |= config->src_per << CH_CFG2_L_SRC_PER_POS |
-			  config->dst_per << CH_CFG2_L_DST_PER_POS;
-		cfg_hi = config->tt_fc << CH_CFG2_H_TT_FC_POS |
-			 config->hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS |
-			 config->hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS |
-			 config->prior << CH_CFG2_H_PRIORITY_POS;
+		cfg_lo |= FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) |
+			  FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per);
+		cfg_hi = FIELD_PREP(CH_CFG2_H_TT_FC, config->tt_fc) |
+			 FIELD_PREP(CH_CFG2_H_HS_SEL_SRC, config->hs_sel_src) |
+			 FIELD_PREP(CH_CFG2_H_HS_SEL_DST, config->hs_sel_dst) |
+			 FIELD_PREP(CH_CFG2_H_PRIORITY, config->prior);
 	}
 	axi_chan_iowrite32(chan, CH_CFG_L, cfg_lo);
 	axi_chan_iowrite32(chan, CH_CFG_H, cfg_hi);
@@ -677,19 +678,19 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
 	case DMA_MEM_TO_DEV:
 		reg_width = __ffs(chan->config.dst_addr_width);
 		device_addr = chan->config.dst_addr;
-		ctllo = reg_width << CH_CTL_L_DST_WIDTH_POS |
-			mem_width << CH_CTL_L_SRC_WIDTH_POS |
-			DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_DST_INC_POS |
-			DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS;
+		ctllo = FIELD_PREP(CH_CTL_L_DST_WIDTH, reg_width) |
+			FIELD_PREP(CH_CTL_L_SRC_WIDTH, mem_width) |
+			FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_NOINC) |
+			FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC);
 		block_ts = len >> mem_width;
 		break;
 	case DMA_DEV_TO_MEM:
 		reg_width = __ffs(chan->config.src_addr_width);
 		device_addr = chan->config.src_addr;
-		ctllo = reg_width << CH_CTL_L_SRC_WIDTH_POS |
-			mem_width << CH_CTL_L_DST_WIDTH_POS |
-			DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
-			DWAXIDMAC_CH_CTL_L_NOINC << CH_CTL_L_SRC_INC_POS;
+		ctllo = FIELD_PREP(CH_CTL_L_SRC_WIDTH, reg_width) |
+			FIELD_PREP(CH_CTL_L_DST_WIDTH, mem_width) |
+			FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) |
+			FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_NOINC);
 		block_ts = len >> reg_width;
 		break;
 	default:
@@ -708,8 +709,8 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
 	if (chan->chip->dw->hdata->restrict_axi_burst_len) {
 		burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 		ctlhi |= CH_CTL_H_ARLEN_EN | CH_CTL_H_AWLEN_EN |
-			 burst_len << CH_CTL_H_ARLEN_POS |
-			 burst_len << CH_CTL_H_AWLEN_POS;
+			 FIELD_PREP(CH_CTL_H_ARLEN, burst_len) |
+			 FIELD_PREP(CH_CTL_H_AWLEN, burst_len);
 	}
 
 	hw_desc->lli->ctl_hi = cpu_to_le32(ctlhi);
@@ -724,8 +725,8 @@ static int dw_axi_dma_set_hw_desc(struct axi_dma_chan *chan,
 
 	hw_desc->lli->block_ts_lo = cpu_to_le32(block_ts - 1);
 
-	ctllo |= DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
-		 DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS;
+	ctllo |= FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
+		 FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4);
 	hw_desc->lli->ctl_lo = cpu_to_le32(ctllo);
 
 	set_desc_src_master(hw_desc);
@@ -978,18 +979,18 @@ dma_chan_prep_dma_memcpy(struct dma_chan *dchan, dma_addr_t dst_adr,
 			u32 burst_len = chan->chip->dw->hdata->axi_rw_burst_len - 1;
 
 			reg |= (CH_CTL_H_ARLEN_EN |
-				burst_len << CH_CTL_H_ARLEN_POS |
+				FIELD_PREP(CH_CTL_H_ARLEN, burst_len) |
 				CH_CTL_H_AWLEN_EN |
-				burst_len << CH_CTL_H_AWLEN_POS);
+				FIELD_PREP(CH_CTL_H_AWLEN, burst_len));
 		}
 		hw_desc->lli->ctl_hi = cpu_to_le32(reg);
 
-		reg = (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
-		       DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
-		       xfer_width << CH_CTL_L_DST_WIDTH_POS |
-		       xfer_width << CH_CTL_L_SRC_WIDTH_POS |
-		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
-		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS);
+		reg = (FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
+		       FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
+		       FIELD_PREP(CH_CTL_L_DST_WIDTH, xfer_width) |
+		       FIELD_PREP(CH_CTL_L_SRC_WIDTH, xfer_width) |
+		       FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) |
+		       FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC));
 		hw_desc->lli->ctl_lo = cpu_to_le32(reg);
 
 		set_desc_src_master(hw_desc);
diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
index 97451bb8b16a..b4ed241e87e2 100644
--- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -234,9 +234,9 @@ static inline struct axi_dma_chan *dchan_to_axi_dma_chan(struct dma_chan *dchan)
 
 /* CH_CTL_H */
 #define CH_CTL_H_ARLEN_EN		BIT(6)
-#define CH_CTL_H_ARLEN_POS		7
+#define CH_CTL_H_ARLEN			GENMASK(14, 7)
 #define CH_CTL_H_AWLEN_EN		BIT(15)
-#define CH_CTL_H_AWLEN_POS		16
+#define CH_CTL_H_AWLEN			GENMASK(23, 16)
 
 enum {
 	DWAXIDMAC_ARWLEN_1		= 0,
@@ -258,8 +258,8 @@ enum {
 /* CH_CTL_L */
 #define CH_CTL_L_LAST_WRITE_EN		BIT(30)
 
-#define CH_CTL_L_DST_MSIZE_POS		18
-#define CH_CTL_L_SRC_MSIZE_POS		14
+#define CH_CTL_L_DST_MSIZE		GENMASK(21, 18)
+#define CH_CTL_L_SRC_MSIZE		GENMASK(17, 14)
 
 enum {
 	DWAXIDMAC_BURST_TRANS_LEN_1	= 0,
@@ -274,11 +274,11 @@ enum {
 	DWAXIDMAC_BURST_TRANS_LEN_1024
 };
 
-#define CH_CTL_L_DST_WIDTH_POS		11
-#define CH_CTL_L_SRC_WIDTH_POS		8
+#define CH_CTL_L_DST_WIDTH		GENMASK(13, 11)
+#define CH_CTL_L_SRC_WIDTH		GENMASK(10, 8)
 
-#define CH_CTL_L_DST_INC_POS		6
-#define CH_CTL_L_SRC_INC_POS		4
+#define CH_CTL_L_DST_INC		BIT(6)
+#define CH_CTL_L_SRC_INC		BIT(4)
 enum {
 	DWAXIDMAC_CH_CTL_L_INC		= 0,
 	DWAXIDMAC_CH_CTL_L_NOINC
@@ -288,17 +288,17 @@ enum {
 #define CH_CTL_L_SRC_MAST		BIT(0)
 
 /* CH_CFG_H */
-#define CH_CFG_H_PRIORITY_POS		17
-#define CH_CFG_H_DST_PER_POS		12
-#define CH_CFG_H_SRC_PER_POS		7
-#define CH_CFG_H_HS_SEL_DST_POS		4
-#define CH_CFG_H_HS_SEL_SRC_POS		3
+#define CH_CFG_H_PRIORITY		GENMASK(19, 17)
+#define CH_CFG_H_DST_PER		GENMASK(15, 12)
+#define CH_CFG_H_SRC_PER		GENMASK(10, 7)
+#define CH_CFG_H_HS_SEL_DST		BIT(4)
+#define CH_CFG_H_HS_SEL_SRC		BIT(3)
 enum {
 	DWAXIDMAC_HS_SEL_HW		= 0,
 	DWAXIDMAC_HS_SEL_SW
 };
 
-#define CH_CFG_H_TT_FC_POS		0
+#define CH_CFG_H_TT_FC			GENMASK(2, 0)
 enum {
 	DWAXIDMAC_TT_FC_MEM_TO_MEM_DMAC	= 0,
 	DWAXIDMAC_TT_FC_MEM_TO_PER_DMAC,
@@ -311,8 +311,8 @@ enum {
 };
 
 /* CH_CFG_L */
-#define CH_CFG_L_DST_MULTBLK_TYPE_POS	2
-#define CH_CFG_L_SRC_MULTBLK_TYPE_POS	0
+#define CH_CFG_L_DST_MULTBLK_TYPE	GENMASK(3, 2)
+#define CH_CFG_L_SRC_MULTBLK_TYPE	GENMASK(1, 0)
 enum {
 	DWAXIDMAC_MBLK_TYPE_CONTIGUOUS	= 0,
 	DWAXIDMAC_MBLK_TYPE_RELOAD,
@@ -321,13 +321,13 @@ enum {
 };
 
 /* CH_CFG2 */
-#define CH_CFG2_L_SRC_PER_POS		4
-#define CH_CFG2_L_DST_PER_POS		11
+#define CH_CFG2_L_SRC_PER		GENMASK(9, 4)
+#define CH_CFG2_L_DST_PER		GENMASK(16, 11)
 
-#define CH_CFG2_H_TT_FC_POS		0
-#define CH_CFG2_H_HS_SEL_SRC_POS	3
-#define CH_CFG2_H_HS_SEL_DST_POS	4
-#define CH_CFG2_H_PRIORITY_POS		15
+#define CH_CFG2_H_TT_FC			GENMASK(2, 0)
+#define CH_CFG2_H_HS_SEL_SRC		BIT(3)
+#define CH_CFG2_H_HS_SEL_DST		BIT(4)
+#define CH_CFG2_H_PRIORITY		GENMASK(19, 15)
 
 /**
  * DW AXI DMA channel interrupts

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers
  2026-09-01  6:16 ` [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers Jia Wang
@ 2026-09-01  7:02   ` Andy Shevchenko
  2026-09-01  8:49     ` Jia Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Andy Shevchenko @ 2026-09-01  7:02 UTC (permalink / raw)
  To: Jia Wang
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N, Sia Jee Heng,
	dmaengine, linux-kernel, Frank Li

On Tue, Sep 01, 2026 at 02:16:07PM +0800, Jia Wang wrote:
> The driver open-codes several channel configuration and descriptor
> control bitfield writes with left shifts. Define masks for those fields
> and use FIELD_PREP() when programming the registers.
> 
> Valid field values keep the same encoding. FIELD_PREP() confines values
> to their respective fields, but does not validate handshake numbers
> supplied through DMA specifiers.

...

>  {
>  	u32 cfg_lo, cfg_hi;
>  
> -	cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
> -		  config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
> +	cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
> +		 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type);

Personally I would duplicate this to make each branch self-contained.

>  	if (chan->chip->dw->hdata->reg_map_8_channels &&
>  	    !chan->chip->dw->hdata->use_cfg2) {
> -		cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
> -			 config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
> -			 config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
> -			 config->src_per << CH_CFG_H_SRC_PER_POS |
> -			 config->dst_per << CH_CFG_H_DST_PER_POS |
> -			 config->prior << CH_CFG_H_PRIORITY_POS;

		cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
			 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type);

> +		cfg_hi = FIELD_PREP(CH_CFG_H_TT_FC, config->tt_fc) |
> +			 FIELD_PREP(CH_CFG_H_HS_SEL_SRC, config->hs_sel_src) |
> +			 FIELD_PREP(CH_CFG_H_HS_SEL_DST, config->hs_sel_dst) |
> +			 FIELD_PREP(CH_CFG_H_SRC_PER, config->src_per) |
> +			 FIELD_PREP(CH_CFG_H_DST_PER, config->dst_per) |
> +			 FIELD_PREP(CH_CFG_H_PRIORITY, config->prior);
>  	} else {
> -		cfg_lo |= config->src_per << CH_CFG2_L_SRC_PER_POS |
> -			  config->dst_per << CH_CFG2_L_DST_PER_POS;
> -		cfg_hi = config->tt_fc << CH_CFG2_H_TT_FC_POS |
> -			 config->hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS |
> -			 config->hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS |
> -			 config->prior << CH_CFG2_H_PRIORITY_POS;
> +		cfg_lo |= FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) |
> +			  FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per);

		cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
			 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type) |
			 FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) |
			 FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per);

> +		cfg_hi = FIELD_PREP(CH_CFG2_H_TT_FC, config->tt_fc) |
> +			 FIELD_PREP(CH_CFG2_H_HS_SEL_SRC, config->hs_sel_src) |
> +			 FIELD_PREP(CH_CFG2_H_HS_SEL_DST, config->hs_sel_dst) |
> +			 FIELD_PREP(CH_CFG2_H_PRIORITY, config->prior);
>  	}

...

> -		reg = (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
> -		       DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
> -		       xfer_width << CH_CTL_L_DST_WIDTH_POS |
> -		       xfer_width << CH_CTL_L_SRC_WIDTH_POS |
> -		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
> -		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS);
> +		reg = (FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
> +		       FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
> +		       FIELD_PREP(CH_CTL_L_DST_WIDTH, xfer_width) |
> +		       FIELD_PREP(CH_CTL_L_SRC_WIDTH, xfer_width) |
> +		       FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) |
> +		       FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC));

Unneeded parentheses.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers
  2026-09-01  7:02   ` Andy Shevchenko
@ 2026-09-01  8:49     ` Jia Wang
  0 siblings, 0 replies; 9+ messages in thread
From: Jia Wang @ 2026-09-01  8:49 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Jia Wang, Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Sia Jee Heng, dmaengine, linux-kernel, Frank Li

On 2026-09-01 10:02 +0300, Andy Shevchenko wrote:
> On Tue, Sep 01, 2026 at 02:16:07PM +0800, Jia Wang wrote:
> > The driver open-codes several channel configuration and descriptor
> > control bitfield writes with left shifts. Define masks for those fields
> > and use FIELD_PREP() when programming the registers.
> > 
> > Valid field values keep the same encoding. FIELD_PREP() confines values
> > to their respective fields, but does not validate handshake numbers
> > supplied through DMA specifiers.
> 
> ...
> 
> >  {
> >  	u32 cfg_lo, cfg_hi;
> >  
> > -	cfg_lo = (config->dst_multblk_type << CH_CFG_L_DST_MULTBLK_TYPE_POS |
> > -		  config->src_multblk_type << CH_CFG_L_SRC_MULTBLK_TYPE_POS);
> > +	cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
> > +		 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type);
> 
> Personally I would duplicate this to make each branch self-contained.
> 

Agreed. I will initialize cfg_lo separately in each branch in the next
version.

> >  	if (chan->chip->dw->hdata->reg_map_8_channels &&
> >  	    !chan->chip->dw->hdata->use_cfg2) {
> > -		cfg_hi = config->tt_fc << CH_CFG_H_TT_FC_POS |
> > -			 config->hs_sel_src << CH_CFG_H_HS_SEL_SRC_POS |
> > -			 config->hs_sel_dst << CH_CFG_H_HS_SEL_DST_POS |
> > -			 config->src_per << CH_CFG_H_SRC_PER_POS |
> > -			 config->dst_per << CH_CFG_H_DST_PER_POS |
> > -			 config->prior << CH_CFG_H_PRIORITY_POS;
> 
> 		cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
> 			 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type);
> 
> > +		cfg_hi = FIELD_PREP(CH_CFG_H_TT_FC, config->tt_fc) |
> > +			 FIELD_PREP(CH_CFG_H_HS_SEL_SRC, config->hs_sel_src) |
> > +			 FIELD_PREP(CH_CFG_H_HS_SEL_DST, config->hs_sel_dst) |
> > +			 FIELD_PREP(CH_CFG_H_SRC_PER, config->src_per) |
> > +			 FIELD_PREP(CH_CFG_H_DST_PER, config->dst_per) |
> > +			 FIELD_PREP(CH_CFG_H_PRIORITY, config->prior);
> >  	} else {
> > -		cfg_lo |= config->src_per << CH_CFG2_L_SRC_PER_POS |
> > -			  config->dst_per << CH_CFG2_L_DST_PER_POS;
> > -		cfg_hi = config->tt_fc << CH_CFG2_H_TT_FC_POS |
> > -			 config->hs_sel_src << CH_CFG2_H_HS_SEL_SRC_POS |
> > -			 config->hs_sel_dst << CH_CFG2_H_HS_SEL_DST_POS |
> > -			 config->prior << CH_CFG2_H_PRIORITY_POS;
> > +		cfg_lo |= FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) |
> > +			  FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per);
> 
> 		cfg_lo = FIELD_PREP(CH_CFG_L_DST_MULTBLK_TYPE, config->dst_multblk_type) |
> 			 FIELD_PREP(CH_CFG_L_SRC_MULTBLK_TYPE, config->src_multblk_type) |
> 			 FIELD_PREP(CH_CFG2_L_SRC_PER, config->src_per) |
> 			 FIELD_PREP(CH_CFG2_L_DST_PER, config->dst_per);
> 
> > +		cfg_hi = FIELD_PREP(CH_CFG2_H_TT_FC, config->tt_fc) |
> > +			 FIELD_PREP(CH_CFG2_H_HS_SEL_SRC, config->hs_sel_src) |
> > +			 FIELD_PREP(CH_CFG2_H_HS_SEL_DST, config->hs_sel_dst) |
> > +			 FIELD_PREP(CH_CFG2_H_PRIORITY, config->prior);
> >  	}
> 
> ...
> 
> > -		reg = (DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_DST_MSIZE_POS |
> > -		       DWAXIDMAC_BURST_TRANS_LEN_4 << CH_CTL_L_SRC_MSIZE_POS |
> > -		       xfer_width << CH_CTL_L_DST_WIDTH_POS |
> > -		       xfer_width << CH_CTL_L_SRC_WIDTH_POS |
> > -		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_DST_INC_POS |
> > -		       DWAXIDMAC_CH_CTL_L_INC << CH_CTL_L_SRC_INC_POS);
> > +		reg = (FIELD_PREP(CH_CTL_L_DST_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
> > +		       FIELD_PREP(CH_CTL_L_SRC_MSIZE, DWAXIDMAC_BURST_TRANS_LEN_4) |
> > +		       FIELD_PREP(CH_CTL_L_DST_WIDTH, xfer_width) |
> > +		       FIELD_PREP(CH_CTL_L_SRC_WIDTH, xfer_width) |
> > +		       FIELD_PREP(CH_CTL_L_DST_INC, DWAXIDMAC_CH_CTL_L_INC) |
> > +		       FIELD_PREP(CH_CTL_L_SRC_INC, DWAXIDMAC_CH_CTL_L_INC));
> 
> Unneeded parentheses.
> 

I will drop the outer parentheses in the next version.

> -- 
> With Best Regards,
> Andy Shevchenko
> 
> 
> 

Best regards,
Jia Wang



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access
  2026-09-01  6:16 ` [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
@ 2026-09-01 18:53   ` Frank Li
  0 siblings, 0 replies; 9+ messages in thread
From: Frank Li @ 2026-09-01 18:53 UTC (permalink / raw)
  To: Jia Wang
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng, dmaengine, linux-kernel

On Tue, Sep 01, 2026 at 02:16:05PM +0800, Jia Wang wrote:
> axi_chan_list_dump_lli() uses the channel-wide descs_allocated count to
> walk the hw_desc[] array of a single transaction. If multiple
> transactions have allocated LLIs, the channel count can exceed the
> transaction-local nr_hw_descs and make the DMA error path read past the
> end of hw_desc[].
>
> Use the descriptor-local nr_hw_descs count when dumping LLIs.
>
> Fixes: ef6fb2d6f1ab ("dmaengine: dw-axi-dmac: simplify descriptor management")
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> index 742e08cfab43..61230d2b1c56 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
> @@ -1052,10 +1052,7 @@ static void axi_chan_dump_lli(struct axi_dma_chan *chan,
>  static void axi_chan_list_dump_lli(struct axi_dma_chan *chan,
>  				   struct axi_dma_desc *desc_head)
>  {
> -	int count = atomic_read(&chan->descs_allocated);
> -	int i;
> -
> -	for (i = 0; i < count; i++)
> +	for (unsigned int i = 0; i < desc_head->nr_hw_descs; i++)
>  		axi_chan_dump_lli(chan, &desc_head->hw_desc[i]);
>  }
>
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position
  2026-09-01  6:16 ` [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position Jia Wang
@ 2026-09-01 18:55   ` Frank Li
  0 siblings, 0 replies; 9+ messages in thread
From: Frank Li @ 2026-09-01 18:55 UTC (permalink / raw)
  To: Jia Wang
  Cc: Eugeniy Paltsev, Vinod Koul, Frank Li, Pandith N,
	Andy Shevchenko, Sia Jee Heng, dmaengine, linux-kernel

On Tue, Sep 01, 2026 at 02:16:06PM +0800, Jia Wang wrote:
> The CH_CFG2 channel priority field occupies bits 51:47 of the 64-bit
> channel configuration register, corresponding to bits 19:15 of CH_CFG2_H.
>
> The driver currently shifts the priority value by 20, programming the
> wrong bits. Use bit 15 as the field position.
>
> Fixes: 824351668a41 ("dmaengine: dw-axi-dmac: support DMAX_NUM_CHANNELS > 8")
> Signed-off-by: Jia Wang <wangjia@ultrarisc.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/dma/dw-axi-dmac/dw-axi-dmac.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> index 67cc199e24d1..97451bb8b16a 100644
> --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
> @@ -327,7 +327,7 @@ enum {
>  #define CH_CFG2_H_TT_FC_POS		0
>  #define CH_CFG2_H_HS_SEL_SRC_POS	3
>  #define CH_CFG2_H_HS_SEL_DST_POS	4
> -#define CH_CFG2_H_PRIORITY_POS		20
> +#define CH_CFG2_H_PRIORITY_POS		15
>
>  /**
>   * DW AXI DMA channel interrupts
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-09-01 18:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-01  6:16 [PATCH v2 0/4] dmaengine: dw-axi-dmac: Fix burst encoding, LLI dump and priority Jia Wang
2026-09-01  6:16 ` [PATCH v2 1/4] dmaengine: dw-axi-dmac: Fix AXI burst length encoding Jia Wang
2026-09-01  6:16 ` [PATCH v2 2/4] dmaengine: dw-axi-dmac: Fix LLI dump out-of-bounds access Jia Wang
2026-09-01 18:53   ` Frank Li
2026-09-01  6:16 ` [PATCH v2 3/4] dmaengine: dw-axi-dmac: Fix CH_CFG2 channel priority position Jia Wang
2026-09-01 18:55   ` Frank Li
2026-09-01  6:16 ` [PATCH v2 4/4] dmaengine: dw-axi-dmac: Use bitfield helpers for registers Jia Wang
2026-09-01  7:02   ` Andy Shevchenko
2026-09-01  8:49     ` Jia Wang

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®