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; >