diff mbox series

[v2,10/19] spi: dw: Use DMA max burst to set the request thresholds

Message ID 20200515104758.6934-11-Sergey.Semin@baikalelectronics.ru (mailing list archive)
State Superseded
Headers show
Series spi: dw: Add generic DW DMA controller support | expand

Commit Message

Serge Semin May 15, 2020, 10:47 a.m. UTC
Each channel of DMA controller may have a limited length of burst
transaction (number of IO operations performed at ones in a single
DMA client request). This parameter can be used to setup the most
optimal DMA Tx/Rx data level values. In order to avoid the Tx buffer
overrun we can set the DMA Tx level to be of FIFO depth minus the
maximum burst transactions length. To prevent the Rx buffer underflow
the DMA Rx level should be set to the maximum burst transactions length.
This commit setups the DMA channels and the DW SPI DMA Tx/Rx levels
in accordance with these rules.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Allison Randal <allison@lohutok.net>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Gareth Williams <gareth.williams.jx@renesas.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: devicetree@vger.kernel.org
---
 drivers/spi/spi-dw-mid.c | 37 +++++++++++++++++++++++++++++++++----
 drivers/spi/spi-dw.h     |  2 ++
 2 files changed, 35 insertions(+), 4 deletions(-)

Comments

Andy Shevchenko May 15, 2020, 2:38 p.m. UTC | #1
On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:
> Each channel of DMA controller may have a limited length of burst
> transaction (number of IO operations performed at ones in a single
> DMA client request). This parameter can be used to setup the most
> optimal DMA Tx/Rx data level values. In order to avoid the Tx buffer
> overrun we can set the DMA Tx level to be of FIFO depth minus the
> maximum burst transactions length. To prevent the Rx buffer underflow
> the DMA Rx level should be set to the maximum burst transactions length.
> This commit setups the DMA channels and the DW SPI DMA Tx/Rx levels
> in accordance with these rules.

It's good one, but see my comments.


I think this patch should go before previous one.
(and without changes regarding FIFO length)

> +static void mid_spi_maxburst_init(struct dw_spi *dws)
> +{
> +	struct dma_slave_caps caps;
> +	u32 max_burst, def_burst;
> +	int ret;
> +
> +	def_burst = dws->fifo_len / 2;
> +
> +	ret = dma_get_slave_caps(dws->rxchan, &caps);
> +	if (!ret && caps.max_burst)
> +		max_burst = caps.max_burst;
> +	else
> +		max_burst = RX_BURST_LEVEL;
> +

> +	dws->rxburst = (def_burst > max_burst) ? max_burst : def_burst;

min() ?

> +
> +	ret = dma_get_slave_caps(dws->txchan, &caps);
> +	if (!ret && caps.max_burst)
> +		max_burst = caps.max_burst;
> +	else
> +		max_burst = TX_BURST_LEVEL;
> +

> +	dws->txburst = (def_burst > max_burst) ? max_burst : def_burst;

Ditto.

> +}
> +
>  static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
>  {
>  	struct dw_dma_slave slave = {0};
> @@ -67,6 +92,8 @@ static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
>  	dws->master->dma_rx = dws->rxchan;
>  	dws->master->dma_tx = dws->txchan;
>  
> +	mid_spi_maxburst_init(dws);
> +
>  	return 0;
>  
>  free_rxchan:
> @@ -92,6 +119,8 @@ static int mid_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
>  	dws->master->dma_rx = dws->rxchan;
>  	dws->master->dma_tx = dws->txchan;
>  
> +	mid_spi_maxburst_init(dws);
> +
>  	return 0;
>  }
>  
> @@ -195,7 +224,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws,
>  	memset(&txconf, 0, sizeof(txconf));
>  	txconf.direction = DMA_MEM_TO_DEV;
>  	txconf.dst_addr = dws->dma_addr;
> -	txconf.dst_maxburst = TX_BURST_LEVEL;
> +	txconf.dst_maxburst = dws->txburst;
>  	txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>  	txconf.dst_addr_width = convert_dma_width(dws->n_bytes);
>  	txconf.device_fc = false;
> @@ -268,7 +297,7 @@ static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
>  	memset(&rxconf, 0, sizeof(rxconf));
>  	rxconf.direction = DMA_DEV_TO_MEM;
>  	rxconf.src_addr = dws->dma_addr;
> -	rxconf.src_maxburst = RX_BURST_LEVEL;
> +	rxconf.src_maxburst = dws->rxburst;
>  	rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
>  	rxconf.src_addr_width = convert_dma_width(dws->n_bytes);
>  	rxconf.device_fc = false;
> @@ -293,8 +322,8 @@ static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
>  {
>  	u16 imr = 0, dma_ctrl = 0;
>  
> -	dw_writel(dws, DW_SPI_DMARDLR, RX_BURST_LEVEL - 1);
> -	dw_writel(dws, DW_SPI_DMATDLR, dws->fifo_len - TX_BURST_LEVEL);
> +	dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1);
> +	dw_writel(dws, DW_SPI_DMATDLR, dws->fifo_len - dws->txburst);
>  
>  	if (xfer->tx_buf) {
>  		dma_ctrl |= SPI_DMA_TDMAE;

...

>  	/* DMA info */
>  	struct dma_chan		*txchan;
> +	u32			txburst;
>  	struct dma_chan		*rxchan;
> +	u32			rxburst;

Leave u32 together, it may be optimal on 64-bit architectures where ABIs require padding.
Andy Shevchenko May 18, 2020, 11:03 a.m. UTC | #2
On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:
> > > Each channel of DMA controller may have a limited length of burst
> > > transaction (number of IO operations performed at ones in a single
> > > DMA client request). This parameter can be used to setup the most
> > > optimal DMA Tx/Rx data level values. In order to avoid the Tx buffer
> > > overrun we can set the DMA Tx level to be of FIFO depth minus the
> > > maximum burst transactions length. To prevent the Rx buffer underflow
> > > the DMA Rx level should be set to the maximum burst transactions length.
> > > This commit setups the DMA channels and the DW SPI DMA Tx/Rx levels
> > > in accordance with these rules.

...

> > >  	/* DMA info */
> > >  	struct dma_chan		*txchan;
> > > +	u32			txburst;
> > >  	struct dma_chan		*rxchan;
> > > +	u32			rxburst;
> > 
> > Leave u32 together, it may be optimal on 64-bit architectures where ABIs require padding.
> 
> It's not like anyone cared about padding in this structure in the first place)

I think I have been caring (to some extend).

> Though if v3 is required I'll group these members together.

From what I see v3 is what Mark and me are waiting for. Mark, are we on the
same page here?
Mark Brown May 18, 2020, 12:43 p.m. UTC | #3
On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:

> > Though if v3 is required I'll group these members together.

> From what I see v3 is what Mark and me are waiting for. Mark, are we on the
> same page here?

I loose track of what's going on with this specific patch, sorry - it's
patch 10 in the series so there's a good chance it has dependencies on
some of the earlier changes anyway.
Serge Semin May 18, 2020, 12:52 p.m. UTC | #4
On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> > On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:
> > > > Each channel of DMA controller may have a limited length of burst
> > > > transaction (number of IO operations performed at ones in a single
> > > > DMA client request). This parameter can be used to setup the most
> > > > optimal DMA Tx/Rx data level values. In order to avoid the Tx buffer
> > > > overrun we can set the DMA Tx level to be of FIFO depth minus the
> > > > maximum burst transactions length. To prevent the Rx buffer underflow
> > > > the DMA Rx level should be set to the maximum burst transactions length.
> > > > This commit setups the DMA channels and the DW SPI DMA Tx/Rx levels
> > > > in accordance with these rules.
> 
> ...
> 
> > > >  	/* DMA info */
> > > >  	struct dma_chan		*txchan;
> > > > +	u32			txburst;
> > > >  	struct dma_chan		*rxchan;
> > > > +	u32			rxburst;
> > > 
> > > Leave u32 together, it may be optimal on 64-bit architectures where ABIs require padding.
> > 
> > It's not like anyone cared about padding in this structure in the first place)
> 
> I think I have been caring (to some extend).

Well, If you have then instead of asking to rearrange just two members (which
by the way finely grouped by the Tx-Rx affiliation) why not sending a
patch, which would refactor the whole structure so to be optimal for the x64
platforms? I don't really see why this gets very important for you seeing
Mark is Ok with this. My current commit follows the common driver design
including the DW SSI data members grouping. On the second thought I'll leave
it as is then.

-Sergey

> 
> > Though if v3 is required I'll group these members together.
> 
> From what I see v3 is what Mark and me are waiting for. Mark, are we on the
> same page here?
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
>
Andy Shevchenko May 18, 2020, 1:25 p.m. UTC | #5
On Mon, May 18, 2020 at 3:53 PM Serge Semin
<Sergey.Semin@baikalelectronics.ru> wrote:
> On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> > On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> > > On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > > > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:

...

> > > > >         struct dma_chan         *txchan;
> > > > > +       u32                     txburst;
> > > > >         struct dma_chan         *rxchan;
> > > > > +       u32                     rxburst;
> > > >
> > > > Leave u32 together, it may be optimal on 64-bit architectures where ABIs require padding.
> > >
> > > It's not like anyone cared about padding in this structure in the first place)
> >
> > I think I have been caring (to some extend).
>
> Well, If you have then instead of asking to rearrange just two members (which
> by the way finely grouped by the Tx-Rx affiliation) why not sending a
> patch, which would refactor the whole structure so to be optimal for the x64
> platforms? I don't really see why this gets very important for you seeing
> Mark is Ok with this. My current commit follows the common driver design
> including the DW SSI data members grouping. On the second thought I'll leave
> it as is then.

Again same issue here. What is really easy to do for you here, will
become a burden and additional churn to anybody else.
So, why not to minimize it in the first place? Same with comma in
another patch. Sorry, I really don't get it.
Serge Semin May 18, 2020, 1:43 p.m. UTC | #6
On Mon, May 18, 2020 at 04:25:20PM +0300, Andy Shevchenko wrote:
> On Mon, May 18, 2020 at 3:53 PM Serge Semin
> <Sergey.Semin@baikalelectronics.ru> wrote:
> > On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> > > On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> > > > On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > > > > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:
> 
> ...
> 
> > > > > >         struct dma_chan         *txchan;
> > > > > > +       u32                     txburst;
> > > > > >         struct dma_chan         *rxchan;
> > > > > > +       u32                     rxburst;
> > > > >
> > > > > Leave u32 together, it may be optimal on 64-bit architectures where ABIs require padding.
> > > >
> > > > It's not like anyone cared about padding in this structure in the first place)
> > >
> > > I think I have been caring (to some extend).
> >
> > Well, If you have then instead of asking to rearrange just two members (which
> > by the way finely grouped by the Tx-Rx affiliation) why not sending a
> > patch, which would refactor the whole structure so to be optimal for the x64
> > platforms? I don't really see why this gets very important for you seeing
> > Mark is Ok with this. My current commit follows the common driver design
> > including the DW SSI data members grouping. On the second thought I'll leave
> > it as is then.
> 
> Again same issue here. What is really easy to do for you here, will
> become a burden and additional churn to anybody else.
> So, why not to minimize it in the first place? Same with comma in
> another patch. Sorry, I really don't get it.

If comma is more or less understandable (though adding it is absolutely
redundant there and doesn't worth even a bit of time spending for the
discussion), here you consider the patch from padding point of view.
The driver developer didn't care about it, but did care about grouping the
members in a corresponding way. The padding burden will be there anyway and
should be fixed for the whole structure in an additional patch. Until then
the way of grouping should be preserved.

-Sergey

> 
> -- 
> With Best Regards,
> Andy Shevchenko
Andy Shevchenko May 18, 2020, 2:48 p.m. UTC | #7
On Mon, May 18, 2020 at 04:43:06PM +0300, Serge Semin wrote:
> On Mon, May 18, 2020 at 04:25:20PM +0300, Andy Shevchenko wrote:
> > On Mon, May 18, 2020 at 3:53 PM Serge Semin
> > <Sergey.Semin@baikalelectronics.ru> wrote:
> > > On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> > > > On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> > > > > On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > > > > > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:

...

> > > > > It's not like anyone cared about padding in this structure in the first place)
> > > >
> > > > I think I have been caring (to some extend).
> > >
> > > Well, If you have then instead of asking to rearrange just two members (which
> > > by the way finely grouped by the Tx-Rx affiliation) why not sending a
> > > patch, which would refactor the whole structure so to be optimal for the x64
> > > platforms? I don't really see why this gets very important for you seeing
> > > Mark is Ok with this. My current commit follows the common driver design
> > > including the DW SSI data members grouping. On the second thought I'll leave
> > > it as is then.
> > 
> > Again same issue here. What is really easy to do for you here, will
> > become a burden and additional churn to anybody else.
> > So, why not to minimize it in the first place? Same with comma in
> > another patch. Sorry, I really don't get it.
> 
> If comma is more or less understandable (though adding it is absolutely
> redundant there and doesn't worth even a bit of time spending for the
> discussion), here you consider the patch from padding point of view.
> The driver developer didn't care about it, but did care about grouping the
> members in a corresponding way. The padding burden will be there anyway and
> should be fixed for the whole structure in an additional patch. Until then
> the way of grouping should be preserved.

Like you said, we spent already much more time than that simple change can be
satisfied. And like you said, "deleloper ... did care about groupping members
in a corresponding way". So, if we look at this in the original code, my
suggestion, besides padding benefit, is consistent with existing pattern in
that data structure.

Note, I agree on extern keyword change can be postponed (it was in the original
code), but here you introduce a new code...
Serge Semin May 18, 2020, 2:59 p.m. UTC | #8
On Mon, May 18, 2020 at 05:48:34PM +0300, Andy Shevchenko wrote:
> On Mon, May 18, 2020 at 04:43:06PM +0300, Serge Semin wrote:
> > On Mon, May 18, 2020 at 04:25:20PM +0300, Andy Shevchenko wrote:
> > > On Mon, May 18, 2020 at 3:53 PM Serge Semin
> > > <Sergey.Semin@baikalelectronics.ru> wrote:
> > > > On Mon, May 18, 2020 at 02:03:43PM +0300, Andy Shevchenko wrote:
> > > > > On Sat, May 16, 2020 at 11:01:33PM +0300, Serge Semin wrote:
> > > > > > On Fri, May 15, 2020 at 05:38:42PM +0300, Andy Shevchenko wrote:
> > > > > > > On Fri, May 15, 2020 at 01:47:49PM +0300, Serge Semin wrote:
> 
> ...
> 
> > > > > > It's not like anyone cared about padding in this structure in the first place)
> > > > >
> > > > > I think I have been caring (to some extend).
> > > >
> > > > Well, If you have then instead of asking to rearrange just two members (which
> > > > by the way finely grouped by the Tx-Rx affiliation) why not sending a
> > > > patch, which would refactor the whole structure so to be optimal for the x64
> > > > platforms? I don't really see why this gets very important for you seeing
> > > > Mark is Ok with this. My current commit follows the common driver design
> > > > including the DW SSI data members grouping. On the second thought I'll leave
> > > > it as is then.
> > > 
> > > Again same issue here. What is really easy to do for you here, will
> > > become a burden and additional churn to anybody else.
> > > So, why not to minimize it in the first place? Same with comma in
> > > another patch. Sorry, I really don't get it.
> > 
> > If comma is more or less understandable (though adding it is absolutely
> > redundant there and doesn't worth even a bit of time spending for the
> > discussion), here you consider the patch from padding point of view.
> > The driver developer didn't care about it, but did care about grouping the
> > members in a corresponding way. The padding burden will be there anyway and
> > should be fixed for the whole structure in an additional patch. Until then
> > the way of grouping should be preserved.
> 
> Like you said, we spent already much more time than that simple change can be
> satisfied. And like you said, "deleloper ... did care about groupping members
> in a corresponding way". So, if we look at this in the original code, my
> suggestion, besides padding benefit, is consistent with existing pattern in
> that data structure.

What pattern do you mean? As I see it, my implementation is consistent with
current structure structure, while yours is not.

-Sergey

> 
> Note, I agree on extern keyword change can be postponed (it was in the original
> code), but here you introduce a new code...
> 
> -- 
> With Best Regards,
> Andy Shevchenko
> 
>
diff mbox series

Patch

diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index e43914dbcadf..70cb68290385 100644
--- a/drivers/spi/spi-dw-mid.c
+++ b/drivers/spi/spi-dw-mid.c
@@ -35,6 +35,31 @@  static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
 	return true;
 }
 
+static void mid_spi_maxburst_init(struct dw_spi *dws)
+{
+	struct dma_slave_caps caps;
+	u32 max_burst, def_burst;
+	int ret;
+
+	def_burst = dws->fifo_len / 2;
+
+	ret = dma_get_slave_caps(dws->rxchan, &caps);
+	if (!ret && caps.max_burst)
+		max_burst = caps.max_burst;
+	else
+		max_burst = RX_BURST_LEVEL;
+
+	dws->rxburst = (def_burst > max_burst) ? max_burst : def_burst;
+
+	ret = dma_get_slave_caps(dws->txchan, &caps);
+	if (!ret && caps.max_burst)
+		max_burst = caps.max_burst;
+	else
+		max_burst = TX_BURST_LEVEL;
+
+	dws->txburst = (def_burst > max_burst) ? max_burst : def_burst;
+}
+
 static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
 {
 	struct dw_dma_slave slave = {0};
@@ -67,6 +92,8 @@  static int mid_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
 	dws->master->dma_rx = dws->rxchan;
 	dws->master->dma_tx = dws->txchan;
 
+	mid_spi_maxburst_init(dws);
+
 	return 0;
 
 free_rxchan:
@@ -92,6 +119,8 @@  static int mid_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
 	dws->master->dma_rx = dws->rxchan;
 	dws->master->dma_tx = dws->txchan;
 
+	mid_spi_maxburst_init(dws);
+
 	return 0;
 }
 
@@ -195,7 +224,7 @@  static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws,
 	memset(&txconf, 0, sizeof(txconf));
 	txconf.direction = DMA_MEM_TO_DEV;
 	txconf.dst_addr = dws->dma_addr;
-	txconf.dst_maxburst = TX_BURST_LEVEL;
+	txconf.dst_maxburst = dws->txburst;
 	txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	txconf.dst_addr_width = convert_dma_width(dws->n_bytes);
 	txconf.device_fc = false;
@@ -268,7 +297,7 @@  static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
 	memset(&rxconf, 0, sizeof(rxconf));
 	rxconf.direction = DMA_DEV_TO_MEM;
 	rxconf.src_addr = dws->dma_addr;
-	rxconf.src_maxburst = RX_BURST_LEVEL;
+	rxconf.src_maxburst = dws->rxburst;
 	rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 	rxconf.src_addr_width = convert_dma_width(dws->n_bytes);
 	rxconf.device_fc = false;
@@ -293,8 +322,8 @@  static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
 {
 	u16 imr = 0, dma_ctrl = 0;
 
-	dw_writel(dws, DW_SPI_DMARDLR, RX_BURST_LEVEL - 1);
-	dw_writel(dws, DW_SPI_DMATDLR, dws->fifo_len - TX_BURST_LEVEL);
+	dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1);
+	dw_writel(dws, DW_SPI_DMATDLR, dws->fifo_len - dws->txburst);
 
 	if (xfer->tx_buf) {
 		dma_ctrl |= SPI_DMA_TDMAE;
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 4902f937c3d7..d0c8b7d3a5d2 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -141,7 +141,9 @@  struct dw_spi {
 
 	/* DMA info */
 	struct dma_chan		*txchan;
+	u32			txburst;
 	struct dma_chan		*rxchan;
+	u32			rxburst;
 	unsigned long		dma_chan_busy;
 	dma_addr_t		dma_addr; /* phy address of the Data register */
 	const struct dw_spi_dma_ops *dma_ops;