Message ID | 20180907062502.8241-4-andrea.merello@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v5,1/7] dmaengine: xilinx_dma: commonize DMA copy size calculation | expand |
On 07-09-18, 08:24, Andrea Merello wrote: > From: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> > > AXI-DMA IP supports configurable (c_sg_length_width) buffer length > register width, hence read buffer length (xlnx,sg-length-width) DT > property and ensure that driver doesn't program buffer length > exceeding the supported limit. For VDMA and CDMA there is no change. > > Cc: Rob Herring <robh+dt@kernel.org> > Cc: Mark Rutland <mark.rutland@arm.com> > Cc: devicetree@vger.kernel.org > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> > Signed-off-by: Michal Simek <michal.simek@xilinx.com> > Signed-off-by: Andrea Merello <andrea.merello@gmail.com> [rebase, reword] > --- > Changes in v2: > - drop original patch and replace with the one in Xilinx tree > Changes in v3: > - cc DT maintainers/ML > Changes in v4: > - upper bound for the property should be 26, not 23 > - add warn for width > 23 as per xilinx original patch > - rework due to changes introduced in 1/6 > Changes in v5: > None > --- > drivers/dma/xilinx/xilinx_dma.c | 36 +++++++++++++++++++++++++-------- > 1 file changed, 28 insertions(+), 8 deletions(-) > > diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c > index aaa6de8a70e4..b17f24e4ec35 100644 > --- a/drivers/dma/xilinx/xilinx_dma.c > +++ b/drivers/dma/xilinx/xilinx_dma.c > @@ -158,7 +158,9 @@ > #define XILINX_DMA_REG_BTT 0x28 > > /* AXI DMA Specific Masks/Bit fields */ > -#define XILINX_DMA_MAX_TRANS_LEN GENMASK(22, 0) > +#define XILINX_DMA_MAX_TRANS_LEN_MIN 8 > +#define XILINX_DMA_MAX_TRANS_LEN_MAX 23 > +#define XILINX_DMA_V2_MAX_TRANS_LEN_MAX 26 > #define XILINX_DMA_CR_COALESCE_MAX GENMASK(23, 16) > #define XILINX_DMA_CR_CYCLIC_BD_EN_MASK BIT(4) > #define XILINX_DMA_CR_COALESCE_SHIFT 16 > @@ -418,6 +420,7 @@ struct xilinx_dma_config { > * @rxs_clk: DMA s2mm stream clock > * @nr_channels: Number of channels DMA device supports > * @chan_id: DMA channel identifier > + * @max_buffer_len: Max buffer length > */ > struct xilinx_dma_device { > void __iomem *regs; > @@ -437,6 +440,7 @@ struct xilinx_dma_device { > struct clk *rxs_clk; > u32 nr_channels; > u32 chan_id; > + u32 max_buffer_len; > }; > > /* Macros */ > @@ -964,7 +968,7 @@ static int xilinx_dma_calc_copysize(struct xilinx_dma_chan *chan, > int size, int done) > { > size_t copy = min_t(size_t, size - done, > - XILINX_DMA_MAX_TRANS_LEN); > + chan->xdev->max_buffer_len); hmm why not add max_buffer_len in patch 1 again, and then use default len as XILINX_DMA_MAX_TRANS_LEN and add multiple lengths here :) - ~Vinod
On Tue, Sep 18, 2018 at 6:25 PM Vinod <vkoul@kernel.org> wrote: > > On 07-09-18, 08:24, Andrea Merello wrote: > > From: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> > > > > AXI-DMA IP supports configurable (c_sg_length_width) buffer length > > register width, hence read buffer length (xlnx,sg-length-width) DT > > property and ensure that driver doesn't program buffer length > > exceeding the supported limit. For VDMA and CDMA there is no change. > > > > Cc: Rob Herring <robh+dt@kernel.org> > > Cc: Mark Rutland <mark.rutland@arm.com> > > Cc: devicetree@vger.kernel.org > > Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com> > > Signed-off-by: Michal Simek <michal.simek@xilinx.com> > > Signed-off-by: Andrea Merello <andrea.merello@gmail.com> [rebase, reword] > > --- > > Changes in v2: > > - drop original patch and replace with the one in Xilinx tree > > Changes in v3: > > - cc DT maintainers/ML > > Changes in v4: > > - upper bound for the property should be 26, not 23 > > - add warn for width > 23 as per xilinx original patch > > - rework due to changes introduced in 1/6 > > Changes in v5: > > None > > --- > > drivers/dma/xilinx/xilinx_dma.c | 36 +++++++++++++++++++++++++-------- > > 1 file changed, 28 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c > > index aaa6de8a70e4..b17f24e4ec35 100644 > > --- a/drivers/dma/xilinx/xilinx_dma.c > > +++ b/drivers/dma/xilinx/xilinx_dma.c > > @@ -158,7 +158,9 @@ > > #define XILINX_DMA_REG_BTT 0x28 > > > > /* AXI DMA Specific Masks/Bit fields */ > > -#define XILINX_DMA_MAX_TRANS_LEN GENMASK(22, 0) > > +#define XILINX_DMA_MAX_TRANS_LEN_MIN 8 > > +#define XILINX_DMA_MAX_TRANS_LEN_MAX 23 > > +#define XILINX_DMA_V2_MAX_TRANS_LEN_MAX 26 > > #define XILINX_DMA_CR_COALESCE_MAX GENMASK(23, 16) > > #define XILINX_DMA_CR_CYCLIC_BD_EN_MASK BIT(4) > > #define XILINX_DMA_CR_COALESCE_SHIFT 16 > > @@ -418,6 +420,7 @@ struct xilinx_dma_config { > > * @rxs_clk: DMA s2mm stream clock > > * @nr_channels: Number of channels DMA device supports > > * @chan_id: DMA channel identifier > > + * @max_buffer_len: Max buffer length > > */ > > struct xilinx_dma_device { > > void __iomem *regs; > > @@ -437,6 +440,7 @@ struct xilinx_dma_device { > > struct clk *rxs_clk; > > u32 nr_channels; > > u32 chan_id; > > + u32 max_buffer_len; > > }; > > > > /* Macros */ > > @@ -964,7 +968,7 @@ static int xilinx_dma_calc_copysize(struct xilinx_dma_chan *chan, > > int size, int done) > > { > > size_t copy = min_t(size_t, size - done, > > - XILINX_DMA_MAX_TRANS_LEN); > > + chan->xdev->max_buffer_len); > > hmm why not add max_buffer_len in patch 1 again, and then use default > len as XILINX_DMA_MAX_TRANS_LEN and add multiple lengths here :) Sorry, I'm not getting your point. Could you please elaborate the "add multiple lengths here" thing ? > - > ~Vinod
On 28-09-18, 08:53, Andrea Merello wrote: > On Tue, Sep 18, 2018 at 6:25 PM Vinod <vkoul@kernel.org> wrote: > > > @@ -964,7 +968,7 @@ static int xilinx_dma_calc_copysize(struct xilinx_dma_chan *chan, > > > int size, int done) > > > { > > > size_t copy = min_t(size_t, size - done, > > > - XILINX_DMA_MAX_TRANS_LEN); > > > + chan->xdev->max_buffer_len); > > > > hmm why not add max_buffer_len in patch 1 again, and then use default > > len as XILINX_DMA_MAX_TRANS_LEN and add multiple lengths here :) > > Sorry, I'm not getting your point. Could you please elaborate the "add > multiple lengths here" thing ? IIRC (sorry been travelling and vacation), add chan->xdev->max_buffer_len in patch 1 and initialize it to XILINX_DMA_MAX_TRANS_LEN. Then in subsequent patches update the length.
On Tue, Oct 2, 2018 at 4:56 PM Vinod <vkoul@kernel.org> wrote: > > On 28-09-18, 08:53, Andrea Merello wrote: > > On Tue, Sep 18, 2018 at 6:25 PM Vinod <vkoul@kernel.org> wrote: > > > > > @@ -964,7 +968,7 @@ static int xilinx_dma_calc_copysize(struct xilinx_dma_chan *chan, > > > > int size, int done) > > > > { > > > > size_t copy = min_t(size_t, size - done, > > > > - XILINX_DMA_MAX_TRANS_LEN); > > > > + chan->xdev->max_buffer_len); > > > > > > hmm why not add max_buffer_len in patch 1 again, and then use default > > > len as XILINX_DMA_MAX_TRANS_LEN and add multiple lengths here :) > > > > Sorry, I'm not getting your point. Could you please elaborate the "add > > multiple lengths here" thing ? > > IIRC (sorry been travelling and vacation), add > chan->xdev->max_buffer_len in patch 1 and initialize it to > XILINX_DMA_MAX_TRANS_LEN. Then in subsequent patches update the length. Ah ok. IMO introducing max_buffer_len seems more related to what 4/7 does (actually getting the max transfer len from DT, thus it is not constant anymore) rather than to what 1/7 does (commonizing the calculation of transfer len as it is).. This is why I've introduced it in 4/7.. .. But if you prefer this way, I'll change this :) .. Maybe we can change 1/7 commit message so that this change looks less off-topic.. But I have not found a very good title yet.. Something like "Prepare for DMA copy size calculation rework" ? > -- > ~Vinod
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index aaa6de8a70e4..b17f24e4ec35 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -158,7 +158,9 @@ #define XILINX_DMA_REG_BTT 0x28 /* AXI DMA Specific Masks/Bit fields */ -#define XILINX_DMA_MAX_TRANS_LEN GENMASK(22, 0) +#define XILINX_DMA_MAX_TRANS_LEN_MIN 8 +#define XILINX_DMA_MAX_TRANS_LEN_MAX 23 +#define XILINX_DMA_V2_MAX_TRANS_LEN_MAX 26 #define XILINX_DMA_CR_COALESCE_MAX GENMASK(23, 16) #define XILINX_DMA_CR_CYCLIC_BD_EN_MASK BIT(4) #define XILINX_DMA_CR_COALESCE_SHIFT 16 @@ -418,6 +420,7 @@ struct xilinx_dma_config { * @rxs_clk: DMA s2mm stream clock * @nr_channels: Number of channels DMA device supports * @chan_id: DMA channel identifier + * @max_buffer_len: Max buffer length */ struct xilinx_dma_device { void __iomem *regs; @@ -437,6 +440,7 @@ struct xilinx_dma_device { struct clk *rxs_clk; u32 nr_channels; u32 chan_id; + u32 max_buffer_len; }; /* Macros */ @@ -964,7 +968,7 @@ static int xilinx_dma_calc_copysize(struct xilinx_dma_chan *chan, int size, int done) { size_t copy = min_t(size_t, size - done, - XILINX_DMA_MAX_TRANS_LEN); + chan->xdev->max_buffer_len); if ((copy + done < size) && chan->xdev->common.copy_align) { @@ -1011,7 +1015,7 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, list_for_each_entry(segment, &desc->segments, node) { hw = &segment->hw; residue += (hw->control - hw->status) & - XILINX_DMA_MAX_TRANS_LEN; + chan->xdev->max_buffer_len; } } spin_unlock_irqrestore(&chan->lock, flags); @@ -1263,7 +1267,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) /* Start the transfer */ dma_ctrl_write(chan, XILINX_DMA_REG_BTT, - hw->control & XILINX_DMA_MAX_TRANS_LEN); + hw->control & chan->xdev->max_buffer_len); } list_splice_tail_init(&chan->pending_list, &chan->active_list); @@ -1366,7 +1370,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) /* Start the transfer */ dma_ctrl_write(chan, XILINX_DMA_REG_BTT, - hw->control & XILINX_DMA_MAX_TRANS_LEN); + hw->control & chan->xdev->max_buffer_len); } list_splice_tail_init(&chan->pending_list, &chan->active_list); @@ -1727,7 +1731,7 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst, struct xilinx_cdma_tx_segment *segment; struct xilinx_cdma_desc_hw *hw; - if (!len || len > XILINX_DMA_MAX_TRANS_LEN) + if (!len || len > chan->xdev->max_buffer_len) return NULL; desc = xilinx_dma_alloc_tx_descriptor(chan); @@ -2596,7 +2600,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) struct xilinx_dma_device *xdev; struct device_node *child, *np = pdev->dev.of_node; struct resource *io; - u32 num_frames, addr_width; + u32 num_frames, addr_width, len_width; int i, err; /* Allocate and initialize the DMA engine structure */ @@ -2628,8 +2632,24 @@ static int xilinx_dma_probe(struct platform_device *pdev) /* Retrieve the DMA engine properties from the device tree */ xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg"); - if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) + xdev->max_buffer_len = GENMASK(XILINX_DMA_MAX_TRANS_LEN_MAX - 1, 0); + + if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { xdev->mcdma = of_property_read_bool(node, "xlnx,mcdma"); + if (!of_property_read_u32(node, "xlnx,sg-length-width", + &len_width)) { + if (len_width < XILINX_DMA_MAX_TRANS_LEN_MIN || + len_width > XILINX_DMA_V2_MAX_TRANS_LEN_MAX) { + dev_warn(xdev->dev, + "invalid xlnx,sg-length-width property value. Using default width\n"); + } else { + if (len_width > XILINX_DMA_MAX_TRANS_LEN_MAX) + dev_warn(xdev->dev, "Please ensure that IP supports buffer length > 23 bits\n"); + xdev->max_buffer_len = + GENMASK(len_width - 1, 0); + } + } + } if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { err = of_property_read_u32(node, "xlnx,num-fstores",