mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/5] spi: tegra114: Allow PIO fallback when DMA is unavailable
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
@ 2026-08-18 14:34 ` Vishwaroop A
  2026-08-18 14:54 ` [PATCH 2/5] spi: tegra114: Run per-transfer delay before ending the transfer Vishwaroop A
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-08-18 14:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

From: Krishna Yarlagadda <kyarlagadda@nvidia.com>

The driver can still use PIO if DMA is not declared in DT. The DT
binding lists 'dmas' as required, but tolerate its absence by
falling back to PIO instead of failing probe. This lets platforms
that legitimately do not wire up a DMA controller use the SPI
controller in PIO-only mode.

The runtime transfer path only takes DMA when both channels are
set, so PIO-only probes automatically stay on the PIO path.

Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Signed-off-by: Vishwaroop A <va@nvidia.com>
---
 drivers/spi/spi-tegra114.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 333fb549214e..f9bd783cb4dc 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -901,7 +901,8 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
 	ret = tegra_spi_flush_fifos(tspi);
 	if (ret < 0)
 		return ret;
-	if (total_fifo_words > SPI_FIFO_DEPTH)
+	if (total_fifo_words > SPI_FIFO_DEPTH &&
+	    tspi->tx_dma_chan && tspi->rx_dma_chan)
 		ret = tegra_spi_start_dma_based_transfer(tspi, t);
 	else
 		ret = tegra_spi_start_cpu_based_transfer(tspi, t);
@@ -1366,15 +1367,21 @@ static int tegra_spi_probe(struct platform_device *pdev)
 	tspi->max_buf_size = SPI_FIFO_DEPTH << 2;
 	tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
 
-	ret = tegra_spi_init_dma_param(tspi, true);
-	if (ret < 0)
-		return ret;
-	ret = tegra_spi_init_dma_param(tspi, false);
-	if (ret < 0)
-		goto exit_rx_dma_free;
-	tspi->max_buf_size = tspi->dma_buf_size;
-	init_completion(&tspi->tx_dma_complete);
-	init_completion(&tspi->rx_dma_complete);
+	if (of_property_present(pdev->dev.of_node, "dmas")) {
+		ret = tegra_spi_init_dma_param(tspi, true);
+		if (ret < 0)
+			return ret;
+		ret = tegra_spi_init_dma_param(tspi, false);
+		if (ret < 0)
+			goto exit_rx_dma_free;
+
+		tspi->max_buf_size = tspi->dma_buf_size;
+		init_completion(&tspi->tx_dma_complete);
+		init_completion(&tspi->rx_dma_complete);
+	} else {
+		dev_warn(&pdev->dev,
+			 "'dmas' is required by the binding, falling back to PIO\n");
+	}
 
 	init_completion(&tspi->xfer_completion);
 

base-commit: b810335a0699d1810683796b0e3ffe8827ddfe6c
-- 
2.17.1


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

* [PATCH 2/5] spi: tegra114: Run per-transfer delay before ending the transfer
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
  2026-08-18 14:34 ` [PATCH 1/5] spi: tegra114: Allow PIO fallback when DMA is unavailable Vishwaroop A
@ 2026-08-18 14:54 ` Vishwaroop A
  2026-08-18 14:55 ` [PATCH 4/5] spi: tegra114: Decide the chip-select mode once per message Vishwaroop A
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-08-18 14:54 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

This driver implements transfer_one_message(), so it must follow the
SPI core sequence for the per-transfer delay: spi_transfer->delay is
the settle time after the transfer completes and must elapse while
CS is still asserted, before CS is deasserted.

The current sequence deasserts CS via tegra_spi_transfer_end() and
only then runs spi_transfer_delay_exec(), which drops the delay to
after CS has already gone inactive. Run the delay first on the paths
that drop CS.

Fixes: f4fade12d506 ("spi/tegra114: Correct support for cs_change")
Signed-off-by: Vishwaroop A <va@nvidia.com>
---
 drivers/spi/spi-tegra114.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index f9bd783cb4dc..d1118f1f2cb3 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1096,20 +1096,20 @@ static int tegra_spi_transfer_one_message(struct spi_controller *host,
 
 complete_xfer:
 		if (ret < 0 || skip) {
-			tegra_spi_transfer_end(spi);
 			spi_transfer_delay_exec(xfer);
+			tegra_spi_transfer_end(spi);
 			goto exit;
 		} else if (list_is_last(&xfer->transfer_list,
 					&msg->transfers)) {
 			if (xfer->cs_change)
 				tspi->cs_control = spi;
 			else {
-				tegra_spi_transfer_end(spi);
 				spi_transfer_delay_exec(xfer);
+				tegra_spi_transfer_end(spi);
 			}
 		} else if (xfer->cs_change) {
-			tegra_spi_transfer_end(spi);
 			spi_transfer_delay_exec(xfer);
+			tegra_spi_transfer_end(spi);
 		}
 
 	}
-- 
2.17.1


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

* [PATCH 4/5] spi: tegra114: Decide the chip-select mode once per message
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
  2026-08-18 14:34 ` [PATCH 1/5] spi: tegra114: Allow PIO fallback when DMA is unavailable Vishwaroop A
  2026-08-18 14:54 ` [PATCH 2/5] spi: tegra114: Run per-transfer delay before ending the transfer Vishwaroop A
@ 2026-08-18 14:55 ` Vishwaroop A
  2026-08-18 14:56 ` [PATCH 5/5] spi: tegra114: Keep software CS across bus-locked messages Vishwaroop A
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-08-18 14:55 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

tegra_spi_setup_transfer_one() picks between hardware and software
chip-select from "is_single_xfer && !t->cs_change", re-evaluated on
the first transfer of every message. Both inputs are properties of
the message rather than of the transfer, and the next change needs
the chip-select mode before the transfer loop starts.

Compute it once in tegra_spi_transfer_one_message() and pass it down
as use_hw_cs. No functional change intended: for a singular message
the new test is the old test, and for a multi-transfer message both
forms select software CS.

Signed-off-by: Vishwaroop A <va@nvidia.com>
---
 drivers/spi/spi-tegra114.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index bd7b13c7f5df..389dcdf15923 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -770,7 +770,7 @@ static int tegra_spi_set_hw_cs_timing(struct spi_device *spi)
 static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
 					struct spi_transfer *t,
 					bool is_first_of_msg,
-					bool is_single_xfer)
+					bool use_hw_cs)
 {
 	struct tegra_spi_data *tspi = spi_controller_get_devdata(spi->controller);
 	struct tegra_spi_client_data *cdata = spi->controller_data;
@@ -829,7 +829,7 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
 		if (spi_get_csgpiod(spi, 0))
 			gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
 
-		if (is_single_xfer && !(t->cs_change)) {
+		if (use_hw_cs) {
 			tspi->use_hw_based_cs = true;
 			command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL);
 		} else {
@@ -1038,19 +1038,30 @@ static int tegra_spi_transfer_one_message(struct spi_controller *host,
 	struct spi_device *spi = msg->spi;
 	int ret;
 	bool skip = false;
-	int single_xfer;
+	bool use_hw_cs = false;
 
 	msg->status = 0;
 	msg->actual_length = 0;
 
-	single_xfer = list_is_singular(&msg->transfers);
+	/*
+	 * Use hardware CS only for a single-transfer message with
+	 * cs_change=0. The controller treats each programmed packet as
+	 * a separate transaction and would pulse CS between transfers of
+	 * a multi-transfer message.
+	 */
+	if (list_is_singular(&msg->transfers)) {
+		xfer = list_first_entry(&msg->transfers,
+					struct spi_transfer, transfer_list);
+		use_hw_cs = !xfer->cs_change;
+	}
+
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 		u32 cmd1;
 
 		reinit_completion(&tspi->xfer_completion);
 
 		cmd1 = tegra_spi_setup_transfer_one(spi, xfer, is_first_msg,
-						    single_xfer);
+						    use_hw_cs);
 
 		if (!xfer->len) {
 			ret = 0;
-- 
2.17.1


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

* [PATCH 5/5] spi: tegra114: Keep software CS across bus-locked messages
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
                   ` (2 preceding siblings ...)
  2026-08-18 14:55 ` [PATCH 4/5] spi: tegra114: Decide the chip-select mode once per message Vishwaroop A
@ 2026-08-18 14:56 ` Vishwaroop A
  2026-09-29  9:41 ` [PATCH 3/5] spi: tegra114: Assert CS between transfers when cs_change is set Vishwaroop A
  2026-10-27  6:57 ` [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Karl Mehltretter
  5 siblings, 0 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-08-18 14:56 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

A client may hold CS across multiple spi_message submissions under
spi_bus_lock() by setting cs_change=1 on the last transfer. The driver
records that device in tspi->cs_control so the next message inherits
the held-CS state.

When CS is controlled by hardware (i.e. for single transfers with
cs_change=0), the controller drops CS while it waits for the next
packet, which breaks protocols such as TCG TIS-SPI that must keep CS
low from command through flow-control polling to the data phase.

Keep software CS when cs_control matches the current device, and build
COMMAND1 from the running command1_reg rather than def_command1_reg so
SPI_CS_SW_HW and SPI_CS_SW_VAL are inherited instead of recomputed. The
COMMAND1 write in start_transfer_one() then updates bit length, mode,
LSB-first and 3-wire for the new transfer while leaving the asserted CS
untouched.

Fixes: 1bf9f3c9232d ("spi: tegra114: add support for hw based cs")
Signed-off-by: Vishwaroop A <va@nvidia.com>
---
 drivers/spi/spi-tegra114.c | 69 +++++++++++++++++++++++++-------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 389dcdf15923..14e506374aed 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -779,6 +779,7 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
 	u32 command1, command2;
 	int req_mode;
 	u32 tx_tap = 0, rx_tap = 0;
+	bool keep_cs;
 
 	if (speed != tspi->cur_speed) {
 		clk_set_rate(tspi->clk, speed);
@@ -794,7 +795,17 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
 	if (is_first_of_msg) {
 		tegra_spi_clear_status(tspi);
 
-		command1 = tspi->def_command1_reg;
+		/*
+		 * If the previous message left CS asserted (cs_change=1
+		 * on its last transfer, e.g. across a bus-locked group),
+		 * start from the current SPI_COMMAND1 value so the
+		 * software CS bits are inherited as-is. Otherwise start
+		 * from the reset default and program CS below.
+		 */
+		keep_cs = (tspi->cs_control == spi);
+		command1 = keep_cs ? tspi->command1_reg : tspi->def_command1_reg;
+
+		command1 &= ~SPI_BIT_LENGTH(~0);
 		command1 |= SPI_BIT_LENGTH(bits_per_word - 1);
 
 		command1 &= ~SPI_CONTROL_MODE_MASK;
@@ -818,28 +829,35 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi,
 		else
 			command1 &= ~SPI_BIDIROE;
 
-		if (tspi->cs_control) {
-			if (tspi->cs_control != spi)
-				tegra_spi_writel(tspi, command1, SPI_COMMAND1);
-			tspi->cs_control = NULL;
-		} else
+		if (keep_cs) {
+			/*
+			 * CS is already asserted and the CS bits above
+			 * were inherited from command1_reg, so the
+			 * SPI_COMMAND1 write in start_transfer_one() will
+			 * update bit length / mode / LSB / BIDIROE for
+			 * this transfer while leaving CS untouched.
+			 */
+			tspi->use_hw_based_cs = false;
+		} else {
 			tegra_spi_writel(tspi, command1, SPI_COMMAND1);
 
-		/* GPIO based chip select control */
-		if (spi_get_csgpiod(spi, 0))
-			gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
+			/* GPIO based chip select control */
+			if (spi_get_csgpiod(spi, 0))
+				gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
 
-		if (use_hw_cs) {
-			tspi->use_hw_based_cs = true;
-			command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL);
-		} else {
-			tspi->use_hw_based_cs = false;
-			command1 |= SPI_CS_SW_HW;
-			if (spi->mode & SPI_CS_HIGH)
-				command1 |= SPI_CS_SW_VAL;
-			else
-				command1 &= ~SPI_CS_SW_VAL;
+			if (use_hw_cs) {
+				tspi->use_hw_based_cs = true;
+				command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL);
+			} else {
+				tspi->use_hw_based_cs = false;
+				command1 |= SPI_CS_SW_HW;
+				if (spi->mode & SPI_CS_HIGH)
+					command1 |= SPI_CS_SW_VAL;
+				else
+					command1 &= ~SPI_CS_SW_VAL;
+			}
 		}
+		tspi->cs_control = NULL;
 
 		if (tspi->last_used_cs != spi_get_chipselect(spi, 0)) {
 			if (cdata && cdata->tx_clk_tap_delay)
@@ -1045,11 +1063,16 @@ static int tegra_spi_transfer_one_message(struct spi_controller *host,
 
 	/*
 	 * Use hardware CS only for a single-transfer message with
-	 * cs_change=0. The controller treats each programmed packet as
-	 * a separate transaction and would pulse CS between transfers of
-	 * a multi-transfer message.
+	 * cs_change=0, and only when CS is not already held from a
+	 * previous message (cs_control == spi). Switching to hardware
+	 * CS while CS is held would release it between packets, which
+	 * breaks bus-locked sequences such as TPM TIS-SPI.
+	 *
+	 * Any multi-transfer message must use software CS: the
+	 * controller treats each programmed packet as a separate
+	 * transaction and would pulse CS between transfers.
 	 */
-	if (list_is_singular(&msg->transfers)) {
+	if (tspi->cs_control != spi && list_is_singular(&msg->transfers)) {
 		xfer = list_first_entry(&msg->transfers,
 					struct spi_transfer, transfer_list);
 		use_hw_cs = !xfer->cs_change;
-- 
2.17.1


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

* [PATCH 3/5] spi: tegra114: Assert CS between transfers when cs_change is set
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
                   ` (3 preceding siblings ...)
  2026-08-18 14:56 ` [PATCH 5/5] spi: tegra114: Keep software CS across bus-locked messages Vishwaroop A
@ 2026-09-29  9:41 ` Vishwaroop A
  2026-10-27  6:57 ` [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Karl Mehltretter
  5 siblings, 0 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-09-29  9:41 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

A spi_message may set cs_change on a non-final transfer to toggle CS
before the next transfer of the same message. The driver deasserts
CS in tegra_spi_transfer_end() and, until now, never drove it active
again, so the following transfer in the same message ran with CS
inactive and clients received garbage.

After ending the current transfer, run the CS-off gap through
spi_transfer_cs_change_delay_exec() so that the core's default
minimum applies when the client leaves cs_change_delay unset, then
reassert CS for the following transfer for both GPIO CS and native
software CS.

Fixes: f4fade12d506 ("spi/tegra114: Correct support for cs_change")
Signed-off-by: Vishwaroop A <va@nvidia.com>
---
 drivers/spi/spi-tegra114.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index d1118f1f2cb3..bd7b13c7f5df 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1110,6 +1110,17 @@ static int tegra_spi_transfer_one_message(struct spi_controller *host,
 		} else if (xfer->cs_change) {
 			spi_transfer_delay_exec(xfer);
 			tegra_spi_transfer_end(spi);
+			spi_transfer_cs_change_delay_exec(msg, xfer);
+			if (spi_get_csgpiod(spi, 0))
+				gpiod_set_value(spi_get_csgpiod(spi, 0), 1);
+			if (!tspi->use_hw_based_cs) {
+				if (spi->mode & SPI_CS_HIGH)
+					tspi->command1_reg |= SPI_CS_SW_VAL;
+				else
+					tspi->command1_reg &= ~SPI_CS_SW_VAL;
+				tegra_spi_writel(tspi, tspi->command1_reg,
+						 SPI_COMMAND1);
+			}
 		}
 
 	}
-- 
2.17.1


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

* [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe
@ 2026-10-21 10:14 Vishwaroop A
  2026-08-18 14:34 ` [PATCH 1/5] spi: tegra114: Allow PIO fallback when DMA is unavailable Vishwaroop A
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Vishwaroop A @ 2026-10-21 10:14 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	Sowjanya Komatineni, Rhyland Klein, Suresh Mangipudi,
	Krishna Yarlagadda, Vishwaroop A, linux-tegra, linux-kernel

Tegra114 SPI sends each transfer as its own packet, and hardware CS
follows that packet. The driver implements transfer_one_message(), so
it has to do the per-transfer delay and cs_change itself. It gets
both wrong.

The delay runs after CS is dropped. A mid-message cs_change drops CS
and never drives it active again. When the last transfer holds CS,
the next message can turn hardware CS back on and drop the line.
TIS-SPI under spi_bus_lock() needs CS held across those messages.
Multi-transfer messages already use software CS; patch 4 only moves
that choice so patch 5 can keep it.

Patch 1 is separate. A missing "dmas" property fails probe even
though PIO works, so fall back to PIO.

Krishna Yarlagadda (1):
  spi: tegra114: Allow PIO fallback when DMA is unavailable

Vishwaroop A (4):
  spi: tegra114: Run per-transfer delay before ending the transfer
  spi: tegra114: Assert CS between transfers when cs_change is set
  spi: tegra114: Decide the chip-select mode once per message
  spi: tegra114: Keep software CS across bus-locked messages

 drivers/spi/spi-tegra114.c | 126 ++++++++++++++++++++++++++-----------
 1 file changed, 89 insertions(+), 37 deletions(-)


base-commit: b810335a0699d1810683796b0e3ffe8827ddfe6c
-- 
2.17.1

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

* Re: [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe
  2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
                   ` (4 preceding siblings ...)
  2026-09-29  9:41 ` [PATCH 3/5] spi: tegra114: Assert CS between transfers when cs_change is set Vishwaroop A
@ 2026-10-27  6:57 ` Karl Mehltretter
  5 siblings, 0 replies; 7+ messages in thread
From: Karl Mehltretter @ 2026-10-27  6:57 UTC (permalink / raw)
  To: Vishwaroop A, Krishna Yarlagadda
  Cc: Karl Mehltretter, Mark Brown, Laxman Dewangan, Thierry Reding,
	Jonathan Hunter, Sowjanya Komatineni, Rhyland Klein,
	Suresh Mangipudi, linux-spi, linux-tegra, linux-kernel

On Wed, Oct 21, 2026 at 10:14:06AM +0000, Vishwaroop A wrote:
> The delay runs after CS is dropped. A mid-message cs_change drops CS
> and never drives it active again. When the last transfer holds CS,
> the next message can turn hardware CS back on and drop the line.
> TIS-SPI under spi_bus_lock() needs CS held across those messages.
> Multi-transfer messages already use software CS; patch 4 only moves
> that choice so patch 5 can keep it.
>
> Patch 1 is separate. A missing "dmas" property fails probe even
> though PIO works, so fall back to PIO.

Tested on Jetson Nano (Tegra210) on v7.3-rc2 (5b0764a53235) with
7000d400.spi (DMA enabled) and 7000d600.spi ("dmas" omitted from DT):

1. PIO fallback (patch 1/5):
   - Unpatched: 7000d600.spi fails probe with:
     spi-tegra114 7000d600.spi: error -19: Dma channel is not available
   - With series: 7000d600.spi logs:
     spi-tegra114 7000d600.spi: 'dmas' is required by the binding, falling back to PIO
     and completes 128-byte PIO transfers on /dev/spidev1.0.

2. Mid-message cs_change reassertion (patch 3/5):
   - Two-transfer SPI_IOC_MESSAGE(2) on 7000d400.spi (SPI_MODE_0,
     active-low CS0) with cs_change = 1 on both transfers:
   - Unpatched: SPI_COMMAND1 (0x7000d400) after the message is
     0x40701827 (SPI_CS_SW_HW = 1, SPI_CS_SW_VAL = 1), leaving CS
     deasserted high during the second transfer.
   - With series: SPI_COMMAND1 is 0x40601827 (SPI_CS_SW_HW = 1,
     SPI_CS_SW_VAL = 0, CS reasserted low before the second transfer).

3. Per-transfer delay order and keeping software CS across messages
   (patches 2/5, 4/5 and 5/5):
   - Immediately following the cs_change = 1 message above, a
     single-transfer SPI_IOC_MESSAGE(1) with cs_change = 0 and
     delay_usecs = 40000 was submitted while sampling SPI_COMMAND1 at
     15 ms into the 40 ms delay window:
   - Unpatched: SPI_COMMAND1 at 15 ms is already reset to 0x40400000
     (SPI_CS_SW_HW = 0) because tegra_spi_transfer_end() ran before
     spi_transfer_delay_exec() and the transfer switched to hardware CS.
   - With series: SPI_COMMAND1 at 15 ms is 0x40601827 (SPI_CS_SW_HW = 1,
     SPI_CS_SW_VAL = 0), holding software CS active during delay_usecs,
     and returns to 0x40400000 after delay_usecs completes.

Tested-by: Karl Mehltretter <kmehltretter@gmail.com>

Thanks,
Karl

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

end of thread, other threads:[~2026-10-27  6:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 10:14 [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Vishwaroop A
2026-08-18 14:34 ` [PATCH 1/5] spi: tegra114: Allow PIO fallback when DMA is unavailable Vishwaroop A
2026-08-18 14:54 ` [PATCH 2/5] spi: tegra114: Run per-transfer delay before ending the transfer Vishwaroop A
2026-08-18 14:55 ` [PATCH 4/5] spi: tegra114: Decide the chip-select mode once per message Vishwaroop A
2026-08-18 14:56 ` [PATCH 5/5] spi: tegra114: Keep software CS across bus-locked messages Vishwaroop A
2026-09-29  9:41 ` [PATCH 3/5] spi: tegra114: Assert CS between transfers when cs_change is set Vishwaroop A
2026-10-27  6:57 ` [PATCH 0/5] spi: tegra114: chip-select fixes and PIO-only probe Karl Mehltretter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®