All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frank Li <Frank.li@oss.nxp.com>
To: Devendra K Verma <devendra.verma@amd.com>
Cc: bhelgaas@google.com, mani@kernel.org, vkoul@kernel.org,
	Frank.Li@kernel.org, dmaengine@vger.kernel.org,
	linux-kernel@vger.kernel.org, michal.simek@amd.com
Subject: Re: [PATCH v5] dmaengine: dw-edma: Enable HDMA 64R/W Channels
Date: Fri, 26 Jun 2026 11:10:00 -0500	[thread overview]
Message-ID: <aj6kWCMbzyYC8Nh8@SMW015318> (raw)
In-Reply-To: <20260626132151.1875965-1-devendra.verma@amd.com>

On Fri, Jun 26, 2026 at 06:51:51PM +0530, Devendra K Verma wrote:
> As per 'Designware Cores PCI Express Controller Databook',
> Section 7.1 - Overview, HDMA supports 64 Read and 64 Write
> channels. Current controller driver supports up to 8 read and
> write channels only. In order to utilize all the channels the
> controller driver need to have the channel related structs
> and variables as per the number of channels supported by IP.
> Following changes are made to enable 64 Read / 64 Write
> channel support:
>
>  o Defined HDMA specific macros to reflect the channel count.
>  o The count of ll_regions and dt_regions in dw_edma_chip and
>    dw_edma_pcie_data shall be in accordance to number of read
>    and write channels.
>  o In dw_edma_probe() configure the channels as per the channels
>    of the IP used.
>  o Changed mask types to u64 for higher channel counts.
>
> Signed-off-by: Devendra K Verma <devendra.verma@amd.com>
> ---
> Changes in v4:
>   o Changed 'mask' variable to a bitmap type as per the
>     review comment.
>
> Changes in v3:
>   o Reverted the FIX for AI reported GET_CH_32() issue, as
>     per the recommendation of reviewers, need to create
>     separate patch for it.
>
> Changes in v2:
>   o Fixed the pre-existing bug related to GET_CH_32
>     interchanging the channel direction and id.
>     This bug was not caused by any version of this patch.
>   o Fixed the issue when using for_each_set_bit() for mask
>     of u64 type.
>
> Changes in v1:
>   o On review recommendation of sashiko bot, in the function
>     dw_hdma_v0_core_off(), the loop iterates over registers
>     as per the number of channels enabled and not on total
>     number of channels supported.
>   o Changed mask types to u64 for higher channel counts.
> ---
>  drivers/dma/dw-edma/dw-edma-core.c    | 19 +++++++++++-----
>  drivers/dma/dw-edma/dw-edma-core.h    |  4 ++--
>  drivers/dma/dw-edma/dw-edma-pcie.c    |  8 +++----
>  drivers/dma/dw-edma/dw-hdma-v0-core.c | 32 ++++++++++++++++++---------
>  drivers/dma/dw-edma/dw-hdma-v0-regs.h |  2 +-
>  include/linux/dma/edma.h              | 10 +++++----
>  6 files changed, 48 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c
> index c2feb3adc79f..adf1b3939f96 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.c
> +++ b/drivers/dma/dw-edma/dw-edma-core.c
> @@ -925,9 +925,9 @@ static int dw_edma_channel_setup(struct dw_edma *dw, u32 wr_alloc, u32 rd_alloc)
>  		irq = &dw->irq[pos];
>
>  		if (chan->dir == EDMA_DIR_WRITE)
> -			irq->wr_mask |= BIT(chan->id);
> +			irq->wr_mask |= BIT_ULL(chan->id);
>  		else
> -			irq->rd_mask |= BIT(chan->id);
> +			irq->rd_mask |= BIT_ULL(chan->id);
>
>  		irq->dw = dw;
>  		memcpy(&chan->msi, &irq->msi, sizeof(chan->msi));
> @@ -1079,6 +1079,8 @@ int dw_edma_probe(struct dw_edma_chip *chip)
>  	struct dw_edma *dw;
>  	u32 wr_alloc = 0;
>  	u32 rd_alloc = 0;
> +	u16 max_wr_cnt;
> +	u16 max_rd_cnt;
>  	int i, err;
>
>  	if (!chip)
> @@ -1094,20 +1096,25 @@ int dw_edma_probe(struct dw_edma_chip *chip)
>
>  	dw->chip = chip;
>
> -	if (dw->chip->mf == EDMA_MF_HDMA_NATIVE)
> +	if (dw->chip->mf == EDMA_MF_HDMA_NATIVE) {
>  		dw_hdma_v0_core_register(dw);
> -	else
> +		max_wr_cnt = HDMA_MAX_WR_CH;
> +		max_rd_cnt = HDMA_MAX_RD_CH;
> +	} else {
>  		dw_edma_v0_core_register(dw);
> +		max_wr_cnt = EDMA_MAX_WR_CH;
> +		max_rd_cnt = EDMA_MAX_RD_CH;
> +	}
>
>  	raw_spin_lock_init(&dw->lock);
>
>  	dw->wr_ch_cnt = min_t(u16, chip->ll_wr_cnt,
>  			      dw_edma_core_ch_count(dw, EDMA_DIR_WRITE));
> -	dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, EDMA_MAX_WR_CH);
> +	dw->wr_ch_cnt = min_t(u16, dw->wr_ch_cnt, max_wr_cnt);
>
>  	dw->rd_ch_cnt = min_t(u16, chip->ll_rd_cnt,
>  			      dw_edma_core_ch_count(dw, EDMA_DIR_READ));
> -	dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, EDMA_MAX_RD_CH);
> +	dw->rd_ch_cnt = min_t(u16, dw->rd_ch_cnt, max_rd_cnt);
>
>  	if (!dw->wr_ch_cnt && !dw->rd_ch_cnt)
>  		return -EINVAL;
> diff --git a/drivers/dma/dw-edma/dw-edma-core.h b/drivers/dma/dw-edma/dw-edma-core.h
> index 902574b1ba86..d12fefbf3952 100644
> --- a/drivers/dma/dw-edma/dw-edma-core.h
> +++ b/drivers/dma/dw-edma/dw-edma-core.h
> @@ -91,8 +91,8 @@ struct dw_edma_chan {
>
>  struct dw_edma_irq {
>  	struct msi_msg                  msi;
> -	u32				wr_mask;
> -	u32				rd_mask;
> +	u64				wr_mask;
> +	u64				rd_mask;

Can you direct use DECLARE_BITMAP(rd_mask, 64) here?

>  	struct dw_edma			*dw;
>  };
>
> diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c
> index 0b30ce138503..79f653da8e0f 100644
> --- a/drivers/dma/dw-edma/dw-edma-pcie.c
> +++ b/drivers/dma/dw-edma/dw-edma-pcie.c
...
>  	}
>  }
>
> @@ -118,19 +129,20 @@ dw_hdma_v0_core_handle_int(struct dw_edma_irq *dw_irq, enum dw_edma_dir dir,
>  	unsigned long total, pos, val;
>  	irqreturn_t ret = IRQ_NONE;
>  	struct dw_edma_chan *chan;
> -	unsigned long off, mask;

after change wr_mask to BITMAP

	mask -> *mask

So needn't change this code if support more channel in future.

Frank

> +	DECLARE_BITMAP(mask, 64);
> +	unsigned long off;
>
>  	if (dir == EDMA_DIR_WRITE) {
>  		total = dw->wr_ch_cnt;
>  		off = 0;
> -		mask = dw_irq->wr_mask;
> +		bitmap_from_u64(mask, dw_irq->wr_mask);
>  	} else {
>  		total = dw->rd_ch_cnt;
>  		off = dw->wr_ch_cnt;
> -		mask = dw_irq->rd_mask;
> +		bitmap_from_u64(mask, dw_irq->rd_mask);
>  	}
>
> -	for_each_set_bit(pos, &mask, total) {
> +	for_each_set_bit(pos, mask, total) {
>  		chan = &dw->chan[pos + off];
>
>  		val = dw_hdma_v0_core_status_int(chan);
> diff --git a/drivers/dma/dw-edma/dw-hdma-v0-regs.h b/drivers/dma/dw-edma/dw-hdma-v0-regs.h
> index 7759ba9b4850..48e40efceb2e 100644
> --- a/drivers/dma/dw-edma/dw-hdma-v0-regs.h
> +++ b/drivers/dma/dw-edma/dw-hdma-v0-regs.h
> @@ -11,7 +11,7 @@
>
>  #include <linux/dmaengine.h>
>
> -#define HDMA_V0_MAX_NR_CH			8
> +#define HDMA_V0_MAX_NR_CH			64
>  #define HDMA_V0_CH_EN				BIT(0)
>  #define HDMA_V0_LOCAL_ABORT_INT_EN		BIT(6)
>  #define HDMA_V0_REMOTE_ABORT_INT_EN		BIT(5)
> diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h
> index 1fafd5b0e315..da7a5cc93ad4 100644
> --- a/include/linux/dma/edma.h
> +++ b/include/linux/dma/edma.h
> @@ -14,6 +14,8 @@
>
>  #define EDMA_MAX_WR_CH                                  8
>  #define EDMA_MAX_RD_CH                                  8
> +#define HDMA_MAX_WR_CH                                  64
> +#define HDMA_MAX_RD_CH                                  64
>
>  struct dw_edma;
>
> @@ -89,12 +91,12 @@ struct dw_edma_chip {
>  	u16			ll_wr_cnt;
>  	u16			ll_rd_cnt;
>  	/* link list address */
> -	struct dw_edma_region	ll_region_wr[EDMA_MAX_WR_CH];
> -	struct dw_edma_region	ll_region_rd[EDMA_MAX_RD_CH];
> +	struct dw_edma_region	ll_region_wr[HDMA_MAX_WR_CH];
> +	struct dw_edma_region	ll_region_rd[HDMA_MAX_RD_CH];
>
>  	/* data region */
> -	struct dw_edma_region	dt_region_wr[EDMA_MAX_WR_CH];
> -	struct dw_edma_region	dt_region_rd[EDMA_MAX_RD_CH];
> +	struct dw_edma_region	dt_region_wr[HDMA_MAX_WR_CH];
> +	struct dw_edma_region	dt_region_rd[HDMA_MAX_RD_CH];
>
>  	/* interrupt emulation */
>  	int			db_irq;
> --
> 2.43.0
>

      parent reply	other threads:[~2026-06-26 16:10 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-26 13:21 [PATCH v5] dmaengine: dw-edma: Enable HDMA 64R/W Channels Devendra K Verma
2026-06-26 13:46 ` sashiko-bot
2026-06-26 15:26   ` Verma, Devendra
2026-06-26 16:00     ` Frank Li
2026-06-26 16:10 ` Frank Li [this message]

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=aj6kWCMbzyYC8Nh8@SMW015318 \
    --to=frank.li@oss.nxp.com \
    --cc=Frank.Li@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=devendra.verma@amd.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mani@kernel.org \
    --cc=michal.simek@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.