On Thu, Jul 02, 2020 at 08:22:48PM +0530, Amit Singh Tomar wrote: > At the moment, Driver uses bit fields to describe registers of the DMA > descriptor structure that makes it less portable and maintainable, and > Andre suugested(and even sketched important bits for it) to make use of > array to describe this DMA descriptors instead. It gives the flexibility > while extending support for other platform such as Actions S700. > > This commit removes the "owl_dma_lli_hw" (that includes bit-fields) and > uses array to describe DMA descriptor. > > Suggested-by: Andre Przywara <andre.przywara@xxxxxxx> > Signed-off-by: Amit Singh Tomar <amittomer25@xxxxxxxxx> Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> Thanks, Mani > --- > Changes since v4: > * Reordered it from 01/10 to 02/10. > Changes since v3: > * Added description for enum fields. > * Restored the old comment. > * Added detailed comment about, the way FLEN > and FCNT values are filled. > Changes since v2: > * No change. > Changes since v1: > * Defined macro for frame count value. > * Introduced llc_hw_flen() from patch 2/9. > * Removed the unnecessary line break. > Changes since rfc: > * No change. > --- > drivers/dma/owl-dma.c | 98 +++++++++++++++++++++++++++++---------------------- > 1 file changed, 56 insertions(+), 42 deletions(-) > > diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c > index 66ef70b00ec0..948d1bead860 100644 > --- a/drivers/dma/owl-dma.c > +++ b/drivers/dma/owl-dma.c > @@ -120,30 +120,33 @@ > #define BIT_FIELD(val, width, shift, newshift) \ > ((((val) >> (shift)) & ((BIT(width)) - 1)) << (newshift)) > > +/* Frame count value is fixed as 1 */ > +#define FCNT_VAL 0x1 > + > /** > - * struct owl_dma_lli_hw - Hardware link list for dma transfer > - * @next_lli: physical address of the next link list > - * @saddr: source physical address > - * @daddr: destination physical address > - * @flen: frame length > - * @fcnt: frame count > - * @src_stride: source stride > - * @dst_stride: destination stride > - * @ctrla: dma_mode and linklist ctrl config > - * @ctrlb: interrupt config > - * @const_num: data for constant fill > + * owl_dmadesc_offsets - Describe DMA descriptor, hardware link > + * list for dma transfer > + * @OWL_DMADESC_NEXT_LLI: physical address of the next link list > + * @OWL_DMADESC_SADDR: source physical address > + * @OWL_DMADESC_DADDR: destination physical address > + * @OWL_DMADESC_FLEN: frame length > + * @OWL_DMADESC_SRC_STRIDE: source stride > + * @OWL_DMADESC_DST_STRIDE: destination stride > + * @OWL_DMADESC_CTRLA: dma_mode and linklist ctrl config > + * @OWL_DMADESC_CTRLB: interrupt config > + * @OWL_DMADESC_CONST_NUM: data for constant fill > */ > -struct owl_dma_lli_hw { > - u32 next_lli; > - u32 saddr; > - u32 daddr; > - u32 flen:20; > - u32 fcnt:12; > - u32 src_stride; > - u32 dst_stride; > - u32 ctrla; > - u32 ctrlb; > - u32 const_num; > +enum owl_dmadesc_offsets { > + OWL_DMADESC_NEXT_LLI = 0, > + OWL_DMADESC_SADDR, > + OWL_DMADESC_DADDR, > + OWL_DMADESC_FLEN, > + OWL_DMADESC_SRC_STRIDE, > + OWL_DMADESC_DST_STRIDE, > + OWL_DMADESC_CTRLA, > + OWL_DMADESC_CTRLB, > + OWL_DMADESC_CONST_NUM, > + OWL_DMADESC_SIZE > }; > > /** > @@ -153,7 +156,7 @@ struct owl_dma_lli_hw { > * @node: node for txd's lli_list > */ > struct owl_dma_lli { > - struct owl_dma_lli_hw hw; > + u32 hw[OWL_DMADESC_SIZE]; > dma_addr_t phys; > struct list_head node; > }; > @@ -318,6 +321,11 @@ static inline u32 llc_hw_ctrlb(u32 int_ctl) > return ctl; > } > > +static u32 llc_hw_flen(struct owl_dma_lli *lli) > +{ > + return lli->hw[OWL_DMADESC_FLEN] & GENMASK(19, 0); > +} > + > static void owl_dma_free_lli(struct owl_dma *od, > struct owl_dma_lli *lli) > { > @@ -349,8 +357,9 @@ static struct owl_dma_lli *owl_dma_add_lli(struct owl_dma_txd *txd, > list_add_tail(&next->node, &txd->lli_list); > > if (prev) { > - prev->hw.next_lli = next->phys; > - prev->hw.ctrla |= llc_hw_ctrla(OWL_DMA_MODE_LME, 0); > + prev->hw[OWL_DMADESC_NEXT_LLI] = next->phys; > + prev->hw[OWL_DMADESC_CTRLA] |= > + llc_hw_ctrla(OWL_DMA_MODE_LME, 0); > } > > return next; > @@ -363,8 +372,7 @@ static inline int owl_dma_cfg_lli(struct owl_dma_vchan *vchan, > struct dma_slave_config *sconfig, > bool is_cyclic) > { > - struct owl_dma_lli_hw *hw = &lli->hw; > - u32 mode; > + u32 mode, ctrlb; > > mode = OWL_DMA_MODE_PW(0); > > @@ -405,22 +413,28 @@ static inline int owl_dma_cfg_lli(struct owl_dma_vchan *vchan, > return -EINVAL; > } > > - hw->next_lli = 0; /* One link list by default */ > - hw->saddr = src; > - hw->daddr = dst; > - > - hw->fcnt = 1; /* Frame count fixed as 1 */ > - hw->flen = len; /* Max frame length is 1MB */ > - hw->src_stride = 0; > - hw->dst_stride = 0; > - hw->ctrla = llc_hw_ctrla(mode, > - OWL_DMA_LLC_SAV_LOAD_NEXT | > - OWL_DMA_LLC_DAV_LOAD_NEXT); > + lli->hw[OWL_DMADESC_CTRLA] = llc_hw_ctrla(mode, > + OWL_DMA_LLC_SAV_LOAD_NEXT | > + OWL_DMA_LLC_DAV_LOAD_NEXT); > > if (is_cyclic) > - hw->ctrlb = llc_hw_ctrlb(OWL_DMA_INTCTL_BLOCK); > + ctrlb = llc_hw_ctrlb(OWL_DMA_INTCTL_BLOCK); > else > - hw->ctrlb = llc_hw_ctrlb(OWL_DMA_INTCTL_SUPER_BLOCK); > + ctrlb = llc_hw_ctrlb(OWL_DMA_INTCTL_SUPER_BLOCK); > + > + lli->hw[OWL_DMADESC_NEXT_LLI] = 0; /* One link list by default */ > + lli->hw[OWL_DMADESC_SADDR] = src; > + lli->hw[OWL_DMADESC_DADDR] = dst; > + lli->hw[OWL_DMADESC_SRC_STRIDE] = 0; > + lli->hw[OWL_DMADESC_DST_STRIDE] = 0; > + /* > + * Word starts from offset 0xC is shared between frame length > + * (max frame length is 1MB) and frame count, where first 20 > + * bits are for frame length and rest of 12 bits are for frame > + * count. > + */ > + lli->hw[OWL_DMADESC_FLEN] = len | FCNT_VAL << 20; > + lli->hw[OWL_DMADESC_CTRLB] = ctrlb; > > return 0; > } > @@ -752,7 +766,7 @@ static u32 owl_dma_getbytes_chan(struct owl_dma_vchan *vchan) > /* Start from the next active node */ > if (lli->phys == next_lli_phy) { > list_for_each_entry(lli, &txd->lli_list, node) > - bytes += lli->hw.flen; > + bytes += llc_hw_flen(lli); > break; > } > } > @@ -783,7 +797,7 @@ static enum dma_status owl_dma_tx_status(struct dma_chan *chan, > if (vd) { > txd = to_owl_txd(&vd->tx); > list_for_each_entry(lli, &txd->lli_list, node) > - bytes += lli->hw.flen; > + bytes += llc_hw_flen(lli); > } else { > bytes = owl_dma_getbytes_chan(vchan); > } > -- > 2.7.4 >