Re: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Dec 21, 2023 at 07:47:19AM +0000, Joy Zou wrote:
> Hi frank,
> > -----Original Message-----
> > From: Frank Li <frank.li@xxxxxxx>
> > Sent: 2023年11月28日 6:56
> > To: Frank Li <frank.li@xxxxxxx>; vkoul@xxxxxxxxxx
> > Cc: devicetree@xxxxxxxxxxxxxxx; dmaengine@xxxxxxxxxxxxxxx;
> > imx@xxxxxxxxxxxxxxx; Joy Zou <joy.zou@xxxxxxx>;
> > krzysztof.kozlowski+dt@xxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; Peng Fan
> > <peng.fan@xxxxxxx>; robh+dt@xxxxxxxxxx; Shenwei Wang
> > <shenwei.wang@xxxxxxx>
> > Subject: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for
> > i.MX95
> > 
> > In i.MX95's edma version 5, the TCD structure is extended to support 64-bit
> > addresses for fields like saddr and daddr. To prevent code duplication, employ
> > help macros to handle the fields, as the field names remain the same between
> > TCD and TCD64.
> > 
> > Change local variables related to TCD addresses from 'u32' to 'dma_addr_t'
> > to accept 64-bit DMA addresses.
> > 
> > Change 'vtcd' type to 'void *' to avoid direct use. Use helper macros to access
> > the TCD fields correctly.
> > 
> > Call 'dma_set_mask_and_coherent(64)' when TCD64 is supported.
> > 
> > Signed-off-by: Frank Li <Frank.Li@xxxxxxx>
> > ---
> >  drivers/dma/fsl-edma-common.c |  34 ++++---
> > drivers/dma/fsl-edma-common.h | 165
> > +++++++++++++++++++++++++++-------
> >  drivers/dma/fsl-edma-main.c   |  14 +++
> >  3 files changed, 170 insertions(+), 43 deletions(-)
> > 
> > diff --git a/drivers/dma/fsl-edma-common.c
> > b/drivers/dma/fsl-edma-common.c index 65f466ab9d4da..c8acff09308fd
> > 100644
> > --- a/drivers/dma/fsl-edma-common.c
> > +++ b/drivers/dma/fsl-edma-common.c
> > @@ -351,7 +351,7 @@ static size_t fsl_edma_desc_residue(struct
> > fsl_edma_chan *fsl_chan,  {
> >  	struct fsl_edma_desc *edesc = fsl_chan->edesc;
> >  	enum dma_transfer_direction dir = edesc->dirn;
> > -	dma_addr_t cur_addr, dma_addr;
> > +	dma_addr_t cur_addr, dma_addr, old_addr;
> >  	size_t len, size;
> >  	u32 nbytes = 0;
> >  	int i;
> > @@ -367,10 +367,16 @@ static size_t fsl_edma_desc_residue(struct
> > fsl_edma_chan *fsl_chan,
> >  	if (!in_progress)
> >  		return len;
> > 
> > -	if (dir == DMA_MEM_TO_DEV)
> > -		cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> > -	else
> > -		cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +	/* 64bit read is not atomic, need read retry when high 32bit changed */
> > +	do {
> > +		if (dir == DMA_MEM_TO_DEV) {
> > +			old_addr = edma_read_tcdreg(fsl_chan, saddr);
> > +			cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> > +		} else {
> > +			old_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +			cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +		}
> > +	} while (upper_32_bits(cur_addr) != upper_32_bits(old_addr));
> > 
> >  	/* figure out the finished and calculate the residue */
> >  	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) { @@ -426,8 +432,7 @@
> > enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
> >  	return fsl_chan->status;
> >  }
> > 
> > -static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
> > -				  struct fsl_edma_hw_tcd *tcd)
> > +static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan, void
> > +*tcd)
> >  {
> >  	u16 csr = 0;
> > 
> > @@ -478,9 +483,9 @@ static void fsl_edma_set_tcd_regs(struct
> > fsl_edma_chan *fsl_chan,
> > 
> >  static inline
> >  void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
> > -		       struct fsl_edma_hw_tcd *tcd, u32 src, u32 dst,
> > -		       u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
> > -		       u16 biter, u16 doff, u32 dlast_sga, bool major_int,
> > +		       struct fsl_edma_hw_tcd *tcd, dma_addr_t src, dma_addr_t
> > dst,
> > +		       u16 attr, u16 soff, u32 nbytes, dma_addr_t slast, u16 citer,
> > +		       u16 biter, u16 doff, dma_addr_t dlast_sga, bool major_int,
> >  		       bool disable_req, bool enable_sg)  {
> >  	struct dma_slave_config *cfg = &fsl_chan->cfg; @@ -581,8 +586,9 @@
> > struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
> >  	dma_addr_t dma_buf_next;
> >  	bool major_int = true;
> >  	int sg_len, i;
> > -	u32 src_addr, dst_addr, last_sg, nbytes;
> > +	dma_addr_t src_addr, dst_addr, last_sg;
> >  	u16 soff, doff, iter;
> > +	u32 nbytes;
> > 
> >  	if (!is_slave_direction(direction))
> >  		return NULL;
> > @@ -654,8 +660,9 @@ struct dma_async_tx_descriptor
> > *fsl_edma_prep_slave_sg(
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> >  	struct fsl_edma_desc *fsl_desc;
> >  	struct scatterlist *sg;
> > -	u32 src_addr, dst_addr, last_sg, nbytes;
> > +	dma_addr_t src_addr, dst_addr, last_sg;
> >  	u16 soff, doff, iter;
> > +	u32 nbytes;
> >  	int i;
> > 
> >  	if (!is_slave_direction(direction))
> > @@ -804,7 +811,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan
> > *chan)
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> > 
> >  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
> > -				sizeof(struct fsl_edma_hw_tcd),
> > +				fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
> > +				sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct
> > fsl_edma_hw_tcd),
> >  				32, 0);
> >  	return 0;
> >  }
> > diff --git a/drivers/dma/fsl-edma-common.h
> > b/drivers/dma/fsl-edma-common.h index 4f39a548547a6..6afceb9fded1b
> > 100644
> > --- a/drivers/dma/fsl-edma-common.h
> > +++ b/drivers/dma/fsl-edma-common.h
> > @@ -87,6 +87,20 @@ struct fsl_edma_hw_tcd {
> >  	__le16	biter;
> >  };
> > 
> > +struct fsl_edma_hw_tcd64 {
> > +	__le64  saddr;
> > +	__le16  soff;
> > +	__le16  attr;
> > +	__le32  nbytes;
> > +	__le64  slast;
> > +	__le64  daddr;
> > +	__le64  dlast_sga;
> > +	__le16  doff;
> > +	__le16  citer;
> > +	__le16  csr;
> > +	__le16  biter;
> > +} __packed;
> > +
> >  struct fsl_edma3_ch_reg {
> >  	__le32	ch_csr;
> >  	__le32	ch_es;
> > @@ -96,7 +110,10 @@ struct fsl_edma3_ch_reg {
> >  	__le32	ch_mux;
> >  	__le32  ch_mattr; /* edma4, reserved for edma3 */
> >  	__le32  ch_reserved;
> > -	struct fsl_edma_hw_tcd tcd;
> > +	union {
> > +		struct fsl_edma_hw_tcd tcd;
> > +		struct fsl_edma_hw_tcd tcd64;
> > +	};
> >  } __packed; 
> The tcd64 should be fsl_edma_hw_tcd64?
> BR

With help macro, it is not imporant, only used to caculate ch_reg address
from tcd address.

Anyway, it should change to fsl_edma_hw_tcd64 for better maintaince. 

Frank

> Joy Zou 
> > 
> >  /*
> > @@ -125,7 +142,7 @@ struct edma_regs {
> > 
> >  struct fsl_edma_sw_tcd {
> >  	dma_addr_t			ptcd;
> > -	struct fsl_edma_hw_tcd		*vtcd;
> > +	void				*vtcd;
> 




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux