linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates
@ 2023-05-12 10:47 Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 1/3] spi: dw: Add DMA directional capability check Joy Chakraborty
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Joy Chakraborty @ 2023-05-12 10:47 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, manugautam, Joy Chakraborty

This Patch series adds support for 32 bits per word trasfers using DMA
and some defensive checks around dma controller capabilities.
---
V1 Changes : Add support for AxSize=4 bytes to support 32bits/word.
---
V1->V2 Changes : Add dma capability check to make sure address widths
are supported.
---
V2->V3 Changes : Split changes , add DMA direction check and other
cosmetic chnages.
---
V3->V4 Changes : Fix Sparce Warning
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303270715.w9sMJhIh-lkp@intel.com/
---
V4->V5 Changes : Preserve reverse xmas Tree order, move direction
check before initalisation of further capabilities, remove zero
initialisations, remove error OR'ing.
---
V5->V6 Changes :
        -Remove case of n_bytes=3 using 4_bytes buswidth
        -Avoid forward decaration
        -Break capability check patch into 2
        -round n_bytes to power of 2 ( Bug Fix)
        -Add more explanation in commit text.
---
V6->V7 Changes : Remove extra spaces, refer to functions in commit as
func()
---
V7->V8 Changes : Minor commment updates in patch 4/5
---
V8->V9 Changes : Minor formatting changes in patch 5/5
---
V9->V10 Changes : Moving "return 0" at the end of dw_spi_dma_caps_init() from patch
[4/5] to patch [3/5] to solve :
spi-dw-dma.c: In function ‘dw_spi_dma_caps_init’:
spi-dw-dma.c:100:1: control reaches end of non-void function [-Werror=return-type]
---
V10->V11 : Resend patches [3/5] to [5/5] on top of :
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git
---

Joy Chakraborty (3):
  spi: dw: Add DMA directional capability check
  spi: dw: Add DMA address widths capability check
  spi: dw: Round of n_bytes to power of 2

 drivers/spi/spi-dw-core.c |  5 +++-
 drivers/spi/spi-dw-dma.c  | 56 ++++++++++++++++++++++++++++++++-------
 drivers/spi/spi-dw.h      |  1 +
 3 files changed, 51 insertions(+), 11 deletions(-)

-- 
2.40.1.606.ga4b1b128d6-goog


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v11 1/3] spi: dw: Add DMA directional capability check
  2023-05-12 10:47 [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Joy Chakraborty
@ 2023-05-12 10:47 ` Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 2/3] spi: dw: Add DMA address widths " Joy Chakraborty
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Joy Chakraborty @ 2023-05-12 10:47 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-kernel, manugautam, Joy Chakraborty, Serge Semin

Check capabilities of DMA controller during init to make sure it is
capable of handling MEM2DEV for tx channel, DEV2MEM for rx channel.

Current DW DMA driver requires both tx and rx channel to be configured
and functional for any kind of transfers to take effect including
half duplex. Hence, check for both tx and rx direction and fail on
unavailbility of either.

Signed-off-by: Joy Chakraborty <joychakr@google.com>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
* tested on Baikal-T1 based system with DW SPI-looped back interface
transferring a chunk of data with DFS:8,12,16.
---
 drivers/spi/spi-dw-dma.c | 41 +++++++++++++++++++++++++++++++---------
 1 file changed, 32 insertions(+), 9 deletions(-)

diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
index f19c092920a1..2363317a0dca 100644
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -72,12 +72,22 @@ static void dw_spi_dma_maxburst_init(struct dw_spi *dws)
 	dw_writel(dws, DW_SPI_DMATDLR, dws->txburst);
 }
 
-static void dw_spi_dma_sg_burst_init(struct dw_spi *dws)
+static int dw_spi_dma_caps_init(struct dw_spi *dws)
 {
-	struct dma_slave_caps tx = {0}, rx = {0};
+	struct dma_slave_caps tx, rx;
+	int ret;
+
+	ret = dma_get_slave_caps(dws->txchan, &tx);
+	if (ret)
+		return ret;
 
-	dma_get_slave_caps(dws->txchan, &tx);
-	dma_get_slave_caps(dws->rxchan, &rx);
+	ret = dma_get_slave_caps(dws->rxchan, &rx);
+	if (ret)
+		return ret;
+
+	if (!(tx.directions & BIT(DMA_MEM_TO_DEV) &&
+	      rx.directions & BIT(DMA_DEV_TO_MEM)))
+		return -ENXIO;
 
 	if (tx.max_sg_burst > 0 && rx.max_sg_burst > 0)
 		dws->dma_sg_burst = min(tx.max_sg_burst, rx.max_sg_burst);
@@ -87,6 +97,8 @@ static void dw_spi_dma_sg_burst_init(struct dw_spi *dws)
 		dws->dma_sg_burst = rx.max_sg_burst;
 	else
 		dws->dma_sg_burst = 0;
+
+	return 0;
 }
 
 static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
@@ -95,6 +107,7 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
 	struct dw_dma_slave dma_rx = { .src_id = 0 }, *rx = &dma_rx;
 	struct pci_dev *dma_dev;
 	dma_cap_mask_t mask;
+	int ret = -EBUSY;
 
 	/*
 	 * Get pci device for DMA controller, currently it could only
@@ -124,20 +137,25 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
 
 	init_completion(&dws->dma_completion);
 
-	dw_spi_dma_maxburst_init(dws);
+	ret = dw_spi_dma_caps_init(dws);
+	if (ret)
+		goto free_txchan;
 
-	dw_spi_dma_sg_burst_init(dws);
+	dw_spi_dma_maxburst_init(dws);
 
 	pci_dev_put(dma_dev);
 
 	return 0;
 
+free_txchan:
+	dma_release_channel(dws->txchan);
+	dws->txchan = NULL;
 free_rxchan:
 	dma_release_channel(dws->rxchan);
 	dws->rxchan = NULL;
 err_exit:
 	pci_dev_put(dma_dev);
-	return -EBUSY;
+	return ret;
 }
 
 static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
@@ -163,12 +181,17 @@ static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws)
 
 	init_completion(&dws->dma_completion);
 
-	dw_spi_dma_maxburst_init(dws);
+	ret = dw_spi_dma_caps_init(dws);
+	if (ret)
+		goto free_txchan;
 
-	dw_spi_dma_sg_burst_init(dws);
+	dw_spi_dma_maxburst_init(dws);
 
 	return 0;
 
+free_txchan:
+	dma_release_channel(dws->txchan);
+	dws->txchan = NULL;
 free_rxchan:
 	dma_release_channel(dws->rxchan);
 	dws->rxchan = NULL;
-- 
2.40.1.606.ga4b1b128d6-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v11 2/3] spi: dw: Add DMA address widths capability check
  2023-05-12 10:47 [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 1/3] spi: dw: Add DMA directional capability check Joy Chakraborty
@ 2023-05-12 10:47 ` Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2 Joy Chakraborty
  2023-05-15 15:22 ` [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Mark Brown
  3 siblings, 0 replies; 6+ messages in thread
From: Joy Chakraborty @ 2023-05-12 10:47 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-kernel, manugautam, Joy Chakraborty, Serge Semin

Store address width capabilities of DMA controller during init and check
the same per transfer to make sure the bits/word requirement can be met.

Current DW DMA driver requires both tx and rx channel to be configured
and functional hence a subset of both tx and rx channel address width
capability is checked with the width requirement(n_bytes) for a
transfer.

Signed-off-by: Joy Chakraborty <joychakr@google.com>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
* tested on Baikal-T1 based system with DW SPI-looped back interface
transferring a chunk of data with DFS:8,12,16.
---
 drivers/spi/spi-dw-dma.c | 15 ++++++++++++++-
 drivers/spi/spi-dw.h     |  1 +
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c
index 2363317a0dca..df819652901a 100644
--- a/drivers/spi/spi-dw-dma.c
+++ b/drivers/spi/spi-dw-dma.c
@@ -98,6 +98,13 @@ static int dw_spi_dma_caps_init(struct dw_spi *dws)
 	else
 		dws->dma_sg_burst = 0;
 
+	/*
+	 * Assuming both channels belong to the same DMA controller hence the
+	 * peripheral side address width capabilities most likely would be
+	 * the same.
+	 */
+	dws->dma_addr_widths = tx.dst_addr_widths & rx.src_addr_widths;
+
 	return 0;
 }
 
@@ -239,8 +246,14 @@ static bool dw_spi_can_dma(struct spi_controller *master,
 			   struct spi_device *spi, struct spi_transfer *xfer)
 {
 	struct dw_spi *dws = spi_controller_get_devdata(master);
+	enum dma_slave_buswidth dma_bus_width;
+
+	if (xfer->len <= dws->fifo_len)
+		return false;
+
+	dma_bus_width = dw_spi_dma_convert_width(dws->n_bytes);
 
-	return xfer->len > dws->fifo_len;
+	return dws->dma_addr_widths & BIT(dma_bus_width);
 }
 
 static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed)
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 9e8eb2b52d5c..3962e6dcf880 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -190,6 +190,7 @@ struct dw_spi {
 	struct dma_chan		*rxchan;
 	u32			rxburst;
 	u32			dma_sg_burst;
+	u32			dma_addr_widths;
 	unsigned long		dma_chan_busy;
 	dma_addr_t		dma_addr; /* phy address of the Data register */
 	const struct dw_spi_dma_ops *dma_ops;
-- 
2.40.1.606.ga4b1b128d6-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2
  2023-05-12 10:47 [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 1/3] spi: dw: Add DMA directional capability check Joy Chakraborty
  2023-05-12 10:47 ` [PATCH v11 2/3] spi: dw: Add DMA address widths " Joy Chakraborty
@ 2023-05-12 10:47 ` Joy Chakraborty
  2023-05-17 23:03   ` Andy Shevchenko
  2023-05-15 15:22 ` [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Mark Brown
  3 siblings, 1 reply; 6+ messages in thread
From: Joy Chakraborty @ 2023-05-12 10:47 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-kernel, manugautam, Joy Chakraborty,
	Andy Shevchenko, Serge Semin

n_bytes variable in the driver represents the number of bytes per word
that needs to be sent/copied to fifo. Bits/word can be between 8 and 32
bits from the client but in memory they are a power of 2, same is mentioned
in spi.h header:
"
 * @bits_per_word: Data transfers involve one or more words; word sizes
 *      like eight or 12 bits are common.  In-memory wordsizes are
 *      powers of two bytes (e.g. 20 bit samples use 32 bits).
 *      This may be changed by the device's driver, or left at the
 *      default (0) indicating protocol words are eight bit bytes.
 *      The spi_transfer.bits_per_word can override this for each transfer.
"

Hence, round of n_bytes to a power of 2 to avoid values like 3 which
would generate unalligned/odd accesses to memory/fifo.

Fixes: a51acc2400d4 ("spi: dw: Add support for 32-bits max xfer size")
Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Joy Chakraborty <joychakr@google.com>
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
Tested-by: Serge Semin <fancer.lancer@gmail.com>
* tested on Baikal-T1 based system with DW SPI-looped back interface
transferring a chunk of data with DFS:8,12,16.
---
 drivers/spi/spi-dw-core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c
index ae3108c70f50..7778b19bcb6c 100644
--- a/drivers/spi/spi-dw-core.c
+++ b/drivers/spi/spi-dw-core.c
@@ -426,7 +426,10 @@ static int dw_spi_transfer_one(struct spi_controller *master,
 	int ret;
 
 	dws->dma_mapped = 0;
-	dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
+	dws->n_bytes =
+		roundup_pow_of_two(DIV_ROUND_UP(transfer->bits_per_word,
+						BITS_PER_BYTE));
+
 	dws->tx = (void *)transfer->tx_buf;
 	dws->tx_len = transfer->len / dws->n_bytes;
 	dws->rx = transfer->rx_buf;
-- 
2.40.1.606.ga4b1b128d6-goog


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates
  2023-05-12 10:47 [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Joy Chakraborty
                   ` (2 preceding siblings ...)
  2023-05-12 10:47 ` [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2 Joy Chakraborty
@ 2023-05-15 15:22 ` Mark Brown
  3 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2023-05-15 15:22 UTC (permalink / raw)
  To: Joy Chakraborty; +Cc: linux-spi, linux-kernel, manugautam

On Fri, 12 May 2023 10:47:42 +0000, Joy Chakraborty wrote:
> This Patch series adds support for 32 bits per word trasfers using DMA
> and some defensive checks around dma controller capabilities.
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] spi: dw: Add DMA directional capability check
      commit: d1ca1c5297ba9260942c0b3f1171a98a432bdfec
[2/3] spi: dw: Add DMA address widths capability check
      commit: 020a3947e7f18e790cc72785281755f8c49e11d4
[3/3] spi: dw: Round of n_bytes to power of 2
      commit: 9f34baf67e4d08908fd94ff29c825bb673295336

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2
  2023-05-12 10:47 ` [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2 Joy Chakraborty
@ 2023-05-17 23:03   ` Andy Shevchenko
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Shevchenko @ 2023-05-17 23:03 UTC (permalink / raw)
  To: Joy Chakraborty
  Cc: Mark Brown, linux-spi, linux-kernel, manugautam, Serge Semin

On Fri, May 12, 2023 at 10:47:45AM +0000, Joy Chakraborty wrote:
> n_bytes variable in the driver represents the number of bytes per word
> that needs to be sent/copied to fifo. Bits/word can be between 8 and 32

FIFO

> bits from the client but in memory they are a power of 2, same is mentioned
> in spi.h header:

> "

Just a blank line is enough here.

>  * @bits_per_word: Data transfers involve one or more words; word sizes
>  *      like eight or 12 bits are common.  In-memory wordsizes are
>  *      powers of two bytes (e.g. 20 bit samples use 32 bits).
>  *      This may be changed by the device's driver, or left at the
>  *      default (0) indicating protocol words are eight bit bytes.
>  *      The spi_transfer.bits_per_word can override this for each transfer.
> "

And here.

> Hence, round of n_bytes to a power of 2 to avoid values like 3 which
> would generate unalligned/odd accesses to memory/fifo.

FIFO

> Fixes: a51acc2400d4 ("spi: dw: Add support for 32-bits max xfer size")
> Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
> Signed-off-by: Joy Chakraborty <joychakr@google.com>
> Reviewed-by: Serge Semin <fancer.lancer@gmail.com>
> Tested-by: Serge Semin <fancer.lancer@gmail.com>

> * tested on Baikal-T1 based system with DW SPI-looped back interface
> transferring a chunk of data with DFS:8,12,16.

This shouldn't be here. It's not a tag.

-- 
With Best Regards,
Andy Shevchenko



^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-05-17 23:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-12 10:47 [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Joy Chakraborty
2023-05-12 10:47 ` [PATCH v11 1/3] spi: dw: Add DMA directional capability check Joy Chakraborty
2023-05-12 10:47 ` [PATCH v11 2/3] spi: dw: Add DMA address widths " Joy Chakraborty
2023-05-12 10:47 ` [PATCH v11 3/3] spi: dw: Round of n_bytes to power of 2 Joy Chakraborty
2023-05-17 23:03   ` Andy Shevchenko
2023-05-15 15:22 ` [PATCH v11 0/3] spi: dw: DW SPI DMA Driver updates Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).