linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] XSPI mode for LS1021A DSPI
@ 2018-06-20  7:34 Esben Haabendal
  2018-06-20  7:34 ` [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement Esben Haabendal
                   ` (11 more replies)
  0 siblings, 12 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal

From: Esben Haabendal <eha@deif.com>

This patch series contains a number of fixes and cleanups for the spi-fsl-dspi
driver (commit 1-7), and on top of that, implementation of XSPI mode for
LS1021A allowing for SPI transfers larger than 16 bits (commit 8-12).

User visible changes (improvements) are:

* Support for all transfer sizes between 4 and 16, not just 4 (which I believe
  were broken anyway), 8 and 16 bits per word.  

* Full support for transfer->cs_change flag.  Setting cs_change in last
  transfer leaves CS asserted.

* Support for all transfers sizes between 4 and 32 bits per word for LS1021A.

The XSPI mode can be trivially enabled for other target using TCQF mode.
Enable for targets using EOQ mode requires additional work due to the split
of TX FIFO into command and data FIFO.

If you like, I will happily squash the last 5 commits into a single XSPI mode
commit.

Esben Haabendal (12):
  spi: spi-fsl-dspi: Drop unreachable else if statement
  spi: spi-fsl-dspi: Drop unneeded use of dataflags bits
  spi: spi-fsl-dspi: Fix per transfer cs_change handling
  spi: spi-fsl-dspi: Simplify transfer counter handling
  spi: spi-fsl-dspi: Support 4 to 16 bits per word transfers
  spi: spi-fsl-dspi: Fixup regmap configuration
  spi: spi-fsl-dspi: Fix MCR register handling
  spi: spi-fsl-dspi: Add support for XSPI mode registers
  spi: spi-fsl-dspi: Framesize control for XSPI mode
  spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode)
  spi: spi-fsl-dspi: Advertise 32 bit for XSPI mode
  spi: spi-fsl-dspi: Enable extended SPI mode

 drivers/spi/spi-fsl-dspi.c | 458 ++++++++++++++++++++-----------------
 1 file changed, 250 insertions(+), 208 deletions(-)

-- 
2.17.1


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

* [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  8:40   ` Martin Hundebøll
  2018-06-20  7:34 ` [PATCH 02/12] spi: spi-fsl-dspi: Drop unneeded use of dataflags bits Esben Haabendal
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

The if statement just above this if/else statement triggers on the same
condition, and then invalidates it.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 0630962ce442..3ca9b9608801 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -593,8 +593,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
 			dspi_pushr |= SPI_PUSHR_EOQ;
 			if ((dspi->cs_change) && (!dspi->len))
 				dspi_pushr &= ~SPI_PUSHR_CONT;
-		} else if (tx_word && (dspi->len == 1))
-			dspi_pushr |= SPI_PUSHR_EOQ;
+		}
 
 		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
 
-- 
2.17.1


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

* [PATCH 02/12] spi: spi-fsl-dspi: Drop unneeded use of dataflags bits
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
  2018-06-20  7:34 ` [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling Esben Haabendal
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Checking directly against pointer value should be at least as fast as doing
bitmasking and compare, so let's keep it simple.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3ca9b9608801..3bf135bf8b93 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -38,8 +38,6 @@
 
 #define DRIVER_NAME "fsl-dspi"
 
-#define TRAN_STATE_RX_VOID		0x01
-#define TRAN_STATE_TX_VOID		0x02
 #define TRAN_STATE_WORD_ODD_NUM	0x04
 
 #define DSPI_FIFO_SIZE			4
@@ -232,7 +230,7 @@ static void dspi_rx_dma_callback(void *arg)
 
 	rx_word = is_double_byte_mode(dspi);
 
-	if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) {
+	if (dspi->rx) {
 		for (i = 0; i < dma->curr_xfer_len; i++) {
 			d = dspi->dma->rx_dma_buf[i];
 			rx_word ? (*(u16 *)dspi->rx = d) :
@@ -538,12 +536,13 @@ static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
 {
 	u16 d16;
 
-	if (!(dspi->dataflags & TRAN_STATE_TX_VOID))
+	if (dspi->tx) {
 		d16 = tx_word ? *(u16 *)dspi->tx : *(u8 *)dspi->tx;
-	else
+		dspi->tx += tx_word + 1;
+	} else {
 		d16 = dspi->void_write_data;
+	}
 
-	dspi->tx += tx_word + 1;
 	dspi->len -= tx_word + 1;
 
 	return	SPI_PUSHR_TXDATA(d16) |
@@ -560,10 +559,10 @@ static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word)
 	regmap_read(dspi->regmap, SPI_POPR, &val);
 	d = SPI_POPR_RXDATA(val);
 
-	if (!(dspi->dataflags & TRAN_STATE_RX_VOID))
+	if (dspi->rx) {
 		rx_word ? (*(u16 *)dspi->rx = d) : (*(u8 *)dspi->rx = d);
-
-	dspi->rx += rx_word + 1;
+		dspi->rx += rx_word + 1;
+	}
 }
 
 static int dspi_eoq_write(struct fsl_dspi *dspi)
@@ -687,12 +686,6 @@ static int dspi_transfer_one_message(struct spi_master *master,
 		dspi->rx_end = dspi->rx + transfer->len;
 		dspi->len = transfer->len;
 
-		if (!dspi->rx)
-			dspi->dataflags |= TRAN_STATE_RX_VOID;
-
-		if (!dspi->tx)
-			dspi->dataflags |= TRAN_STATE_TX_VOID;
-
 		regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
 		regmap_update_bits(dspi->regmap, SPI_MCR,
 				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
-- 
2.17.1


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

* [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
  2018-06-20  7:34 ` [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement Esben Haabendal
  2018-06-20  7:34 ` [PATCH 02/12] spi: spi-fsl-dspi: Drop unneeded use of dataflags bits Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20 13:27   ` Mark Brown
  2018-06-20  7:34 ` [PATCH 04/12] spi: spi-fsl-dspi: Simplify transfer counter handling Esben Haabendal
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

As of 92dc20d83adec565378254c0630e839ff5674e14, transfer->cs_change has
been supported for non-last transfers, but not for last transfer.

This change brings handling of cs_change in line with the specification in
spi.h, implementing handling of transfer->cs_change for all transfers.

The value for CMD FIFO is precalculated with transfer->cs_change field
taken into account, allowing for CS de-activate between transfers and
keeping CS activated after last transfer.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>

fixup! spi: spi-fsl-dspi: Fix per transfer cs_change handling
---
 drivers/spi/spi-fsl-dspi.c | 68 ++++++++++++++++++++++----------------
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3bf135bf8b93..c0c3b8bf2781 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -84,11 +84,16 @@
 #define SPI_RSER_TCFQE		0x80000000
 
 #define SPI_PUSHR		0x34
-#define SPI_PUSHR_CONT		(1 << 31)
-#define SPI_PUSHR_CTAS(x)	(((x) & 0x00000003) << 28)
-#define SPI_PUSHR_EOQ		(1 << 27)
-#define SPI_PUSHR_CTCNT	(1 << 26)
-#define SPI_PUSHR_PCS(x)	(((1 << x) & 0x0000003f) << 16)
+#define SPI_PUSHR_CMD_CONT	(1 << 15)
+#define SPI_PUSHR_CONT		(SPI_PUSHR_CMD_CONT << 16)
+#define SPI_PUSHR_CMD_CTAS(x)	(((x) & 0x0003) << 12)
+#define SPI_PUSHR_CTAS(x)	(SPI_PUSHR_CMD_CTAS(x) << 16)
+#define SPI_PUSHR_CMD_EOQ	(1 << 11)
+#define SPI_PUSHR_EOQ		(SPI_PUSHR_CMD_EOQ << 16)
+#define SPI_PUSHR_CMD_CTCNT	(1 << 10)
+#define SPI_PUSHR_CTCNT		(SPI_PUSHR_CMD_CTCNT << 16)
+#define SPI_PUSHR_CMD_PCS(x)	((1 << x) & 0x003f)
+#define SPI_PUSHR_PCS(x)	(SPI_PUSHR_CMD_PCS(x) << 16)
 #define SPI_PUSHR_TXDATA(x)	((x) & 0x0000ffff)
 
 #define SPI_PUSHR_SLAVE	0x34
@@ -189,9 +194,8 @@ struct fsl_dspi {
 	void			*rx;
 	void			*rx_end;
 	char			dataflags;
-	u8			cs;
 	u16			void_write_data;
-	u32			cs_change;
+	u16			tx_cmd;
 	const struct fsl_dspi_devtype_data *devtype_data;
 
 	wait_queue_head_t	waitq;
@@ -254,8 +258,6 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
 	for (i = 0; i < dma->curr_xfer_len; i++) {
 		dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
-		if ((dspi->cs_change) && (!dspi->len))
-			dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
 	}
 
 	dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
@@ -534,21 +536,22 @@ static void ns_delay_scale(char *psc, char *sc, int delay_ns,
 
 static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
 {
-	u16 d16;
+	u16 data, cmd;
 
 	if (dspi->tx) {
-		d16 = tx_word ? *(u16 *)dspi->tx : *(u8 *)dspi->tx;
+		data = tx_word ? *(u16 *)dspi->tx : *(u8 *)dspi->tx;
 		dspi->tx += tx_word + 1;
 	} else {
-		d16 = dspi->void_write_data;
+		data = dspi->void_write_data;
 	}
 
 	dspi->len -= tx_word + 1;
 
-	return	SPI_PUSHR_TXDATA(d16) |
-		SPI_PUSHR_PCS(dspi->cs) |
-		SPI_PUSHR_CTAS(0) |
-		SPI_PUSHR_CONT;
+	cmd = dspi->tx_cmd;
+	if (dspi->len > 0)
+		cmd |= SPI_PUSHR_CMD_CONT;
+
+	return (cmd << 16) | SPI_PUSHR_TXDATA(data);
 }
 
 static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word)
@@ -587,12 +590,9 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
 
 		dspi_pushr = dspi_data_to_pushr(dspi, tx_word);
 
-		if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) {
-			/* last transfer in the transfer */
+		if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1)
+			/* request EOQ flag for last transfer in queue */
 			dspi_pushr |= SPI_PUSHR_EOQ;
-			if ((dspi->cs_change) && (!dspi->len))
-				dspi_pushr &= ~SPI_PUSHR_CONT;
-		}
 
 		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
 
@@ -635,9 +635,6 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
 
 	dspi_pushr = dspi_data_to_pushr(dspi, tx_word);
 
-	if ((dspi->cs_change) && (!dspi->len))
-		dspi_pushr &= ~SPI_PUSHR_CONT;
-
 	regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
 
 	return tx_word + 1;
@@ -672,11 +669,26 @@ static int dspi_transfer_one_message(struct spi_master *master,
 		dspi->cur_transfer = transfer;
 		dspi->cur_msg = message;
 		dspi->cur_chip = spi_get_ctldata(spi);
-		dspi->cs = spi->chip_select;
-		dspi->cs_change = 0;
+		/* Prepare command word for CMD FIFO */
+		dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0) |
+			SPI_PUSHR_CMD_PCS(spi->chip_select);
 		if (list_is_last(&dspi->cur_transfer->transfer_list,
-				 &dspi->cur_msg->transfers) || transfer->cs_change)
-			dspi->cs_change = 1;
+				 &dspi->cur_msg->transfers)) {
+			/* Leave PCS activated after last transfer when
+			 * cs_change is set.
+			 */
+			if (transfer->cs_change)
+				dspi->tx_cmd |= SPI_PUSHR_CMD_CONT;
+		} else {
+			/* Keep PCS active between transfers in same message
+			 * when cs_change is not set, and de-activate PCS
+			 * between transfers in the same message when
+			 * cs_change is set.
+			 */
+			if (!transfer->cs_change)
+				dspi->tx_cmd |= SPI_PUSHR_CMD_CONT;
+		}
+
 		dspi->void_write_data = dspi->cur_chip->void_write_data;
 
 		dspi->dataflags = 0;
-- 
2.17.1


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

* [PATCH 04/12] spi: spi-fsl-dspi: Simplify transfer counter handling
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (2 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 05/12] spi: spi-fsl-dspi: Support 4 to 16 bits per word transfers Esben Haabendal
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Simplify driver by avoiding counter wrapping by clearing transfer counter
on first SPI transfer per interrupt instead of tracking what it was before.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 39 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index c0c3b8bf2781..2371b9978e65 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -119,8 +119,6 @@
 #define SPI_CS_ASSERT		0x02
 #define SPI_CS_DROP		0x04
 
-#define SPI_TCR_TCNT_MAX	0x10000
-
 #define DMA_COMPLETION_TIMEOUT	msecs_to_jiffies(3000)
 
 struct chip_data {
@@ -201,7 +199,6 @@ struct fsl_dspi {
 	wait_queue_head_t	waitq;
 	u32			waitflags;
 
-	u32			spi_tcnt;
 	struct fsl_dspi_dma	*dma;
 };
 
@@ -594,6 +591,10 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
 			/* request EOQ flag for last transfer in queue */
 			dspi_pushr |= SPI_PUSHR_EOQ;
 
+		/* Clear transfer counter on first transfer (in FIFO) */
+		if (tx_count == 0)
+			dspi_pushr |= SPI_PUSHR_CTCNT;
+
 		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
 
 		tx_count++;
@@ -635,6 +636,9 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
 
 	dspi_pushr = dspi_data_to_pushr(dspi, tx_word);
 
+	/* Clear transfer counter on each transfer */
+	dspi_pushr |= SPI_PUSHR_CTCNT;
+
 	regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
 
 	return tx_word + 1;
@@ -658,10 +662,6 @@ static int dspi_transfer_one_message(struct spi_master *master,
 	struct spi_transfer *transfer;
 	int status = 0;
 	enum dspi_trans_mode trans_mode;
-	u32 spi_tcr;
-
-	regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
-	dspi->spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
 
 	message->actual_length = 0;
 
@@ -831,7 +831,7 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 	struct spi_message *msg = dspi->cur_msg;
 	enum dspi_trans_mode trans_mode;
 	u32 spi_sr, spi_tcr;
-	u32 spi_tcnt, tcnt_diff;
+	u16 spi_tcnt;
 	int tx_word;
 
 	regmap_read(dspi->regmap, SPI_SR, &spi_sr);
@@ -841,26 +841,15 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 	if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) {
 		tx_word = is_double_byte_mode(dspi);
 
+		/* Get transfer counter (in number of SPI transfers). It was
+		 * reset to 0 when transfer(s) were started.
+		 */
 		regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
 		spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
-		/*
-		 * The width of SPI Transfer Counter in SPI_TCR is 16bits,
-		 * so the max couner is 65535. When the counter reach 65535,
-		 * it will wrap around, counter reset to zero.
-		 * spi_tcnt my be less than dspi->spi_tcnt, it means the
-		 * counter already wrapped around.
-		 * SPI Transfer Counter is a counter of transmitted frames.
-		 * The size of frame maybe two bytes.
-		 */
-		tcnt_diff = ((spi_tcnt + SPI_TCR_TCNT_MAX) - dspi->spi_tcnt)
-			% SPI_TCR_TCNT_MAX;
-		tcnt_diff *= (tx_word + 1);
-		if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM)
-			tcnt_diff--;
-
-		msg->actual_length += tcnt_diff;
 
-		dspi->spi_tcnt = spi_tcnt;
+		/* Update total number of bytes that were transferred */
+		msg->actual_length += spi_tcnt * (tx_word + 1) -
+			(dspi->dataflags & TRAN_STATE_WORD_ODD_NUM ? 1 : 0);
 
 		trans_mode = dspi->devtype_data->trans_mode;
 		switch (trans_mode) {
-- 
2.17.1


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

* [PATCH 05/12] spi: spi-fsl-dspi: Support 4 to 16 bits per word transfers
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (3 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 04/12] spi: spi-fsl-dspi: Simplify transfer counter handling Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 06/12] spi: spi-fsl-dspi: Fixup regmap configuration Esben Haabendal
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

This extends the driver with support for all SPI framesizes from 4 to 16
bits, and adds support for per transfer specific bits_per_word, while at
the same time reducing code size and complexity.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 251 +++++++++++++------------------------
 1 file changed, 88 insertions(+), 163 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 2371b9978e65..df07dd4722fb 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -38,8 +38,6 @@
 
 #define DRIVER_NAME "fsl-dspi"
 
-#define TRAN_STATE_WORD_ODD_NUM	0x04
-
 #define DSPI_FIFO_SIZE			4
 #define DSPI_DMA_BUFSIZE		(DSPI_FIFO_SIZE * 1024)
 
@@ -187,13 +185,13 @@ struct fsl_dspi {
 	struct spi_message	*cur_msg;
 	struct chip_data	*cur_chip;
 	size_t			len;
-	void			*tx;
-	void			*tx_end;
+	const void		*tx;
 	void			*rx;
 	void			*rx_end;
-	char			dataflags;
 	u16			void_write_data;
 	u16			tx_cmd;
+	u8			bits_per_word;
+	u8			bytes_per_word;
 	const struct fsl_dspi_devtype_data *devtype_data;
 
 	wait_queue_head_t	waitq;
@@ -202,15 +200,43 @@ struct fsl_dspi {
 	struct fsl_dspi_dma	*dma;
 };
 
-static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
+static u16 dspi_pop_tx(struct fsl_dspi *dspi)
+{
+	u16 txdata = 0;
+
+	if (dspi->tx) {
+		if (dspi->bytes_per_word == 1)
+			txdata = *(u8 *)dspi->tx;
+		else /* dspi->bytes_per_word == 2 */
+			txdata = *(u16 *)dspi->tx;
+		dspi->tx += dspi->bytes_per_word;
+	}
+	dspi->len -= dspi->bytes_per_word;
+	return txdata;
+}
 
-static inline int is_double_byte_mode(struct fsl_dspi *dspi)
+static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi)
 {
-	unsigned int val;
+	u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi);
 
-	regmap_read(dspi->regmap, SPI_CTAR(0), &val);
+	if (dspi->len > 0)
+		cmd |= SPI_PUSHR_CMD_CONT;
+	return cmd << 16 | data;
+}
+
+static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
+{
+	if (!dspi->rx)
+		return;
+
+	/* Mask of undefined bits */
+	rxdata &= (1 << dspi->bits_per_word) - 1;
 
-	return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0 : 1;
+	if (dspi->bytes_per_word == 1)
+		*(u8 *)dspi->rx = rxdata;
+	else /* dspi->bytes_per_word == 2 */
+		*(u16 *)dspi->rx = rxdata;
+	dspi->rx += dspi->bytes_per_word;
 }
 
 static void dspi_tx_dma_callback(void *arg)
@@ -225,19 +251,11 @@ static void dspi_rx_dma_callback(void *arg)
 {
 	struct fsl_dspi *dspi = arg;
 	struct fsl_dspi_dma *dma = dspi->dma;
-	int rx_word;
 	int i;
-	u16 d;
-
-	rx_word = is_double_byte_mode(dspi);
 
 	if (dspi->rx) {
-		for (i = 0; i < dma->curr_xfer_len; i++) {
-			d = dspi->dma->rx_dma_buf[i];
-			rx_word ? (*(u16 *)dspi->rx = d) :
-						(*(u8 *)dspi->rx = d);
-			dspi->rx += rx_word + 1;
-		}
+		for (i = 0; i < dma->curr_xfer_len; i++)
+			dspi_push_rx(dspi, dspi->dma->rx_dma_buf[i]);
 	}
 
 	complete(&dma->cmd_rx_complete);
@@ -248,14 +266,10 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 	struct fsl_dspi_dma *dma = dspi->dma;
 	struct device *dev = &dspi->pdev->dev;
 	int time_left;
-	int tx_word;
 	int i;
 
-	tx_word = is_double_byte_mode(dspi);
-
-	for (i = 0; i < dma->curr_xfer_len; i++) {
-		dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
-	}
+	for (i = 0; i < dma->curr_xfer_len; i++)
+		dspi->dma->tx_dma_buf[i] = dspi_pop_tx_pushr(dspi);
 
 	dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
 					dma->tx_dma_phys,
@@ -326,16 +340,14 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
 	struct device *dev = &dspi->pdev->dev;
 	int curr_remaining_bytes;
 	int bytes_per_buffer;
-	int word = 1;
 	int ret = 0;
 
-	if (is_double_byte_mode(dspi))
-		word = 2;
 	curr_remaining_bytes = dspi->len;
 	bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE;
 	while (curr_remaining_bytes) {
 		/* Check if current transfer fits the DMA buffer */
-		dma->curr_xfer_len = curr_remaining_bytes / word;
+		dma->curr_xfer_len = curr_remaining_bytes
+			/ dspi->bytes_per_word;
 		if (dma->curr_xfer_len > bytes_per_buffer)
 			dma->curr_xfer_len = bytes_per_buffer;
 
@@ -345,7 +357,8 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
 			goto exit;
 
 		} else {
-			curr_remaining_bytes -= dma->curr_xfer_len * word;
+			curr_remaining_bytes -= dma->curr_xfer_len
+				* dspi->bytes_per_word;
 			if (curr_remaining_bytes < 0)
 				curr_remaining_bytes = 0;
 		}
@@ -531,127 +544,56 @@ static void ns_delay_scale(char *psc, char *sc, int delay_ns,
 	}
 }
 
-static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word)
+static void fifo_write(struct fsl_dspi *dspi)
 {
-	u16 data, cmd;
-
-	if (dspi->tx) {
-		data = tx_word ? *(u16 *)dspi->tx : *(u8 *)dspi->tx;
-		dspi->tx += tx_word + 1;
-	} else {
-		data = dspi->void_write_data;
-	}
-
-	dspi->len -= tx_word + 1;
-
-	cmd = dspi->tx_cmd;
-	if (dspi->len > 0)
-		cmd |= SPI_PUSHR_CMD_CONT;
-
-	return (cmd << 16) | SPI_PUSHR_TXDATA(data);
+	regmap_write(dspi->regmap, SPI_PUSHR, dspi_pop_tx_pushr(dspi));
 }
 
-static void dspi_data_from_popr(struct fsl_dspi *dspi, int rx_word)
+static void dspi_tcfq_write(struct fsl_dspi *dspi)
 {
-	u16 d;
-	unsigned int val;
-
-	regmap_read(dspi->regmap, SPI_POPR, &val);
-	d = SPI_POPR_RXDATA(val);
-
-	if (dspi->rx) {
-		rx_word ? (*(u16 *)dspi->rx = d) : (*(u8 *)dspi->rx = d);
-		dspi->rx += rx_word + 1;
-	}
+	/* Clear transfer count */
+	dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT;
+	/* Write one entry to both TX FIFO and CMD FIFO simultaneously */
+	fifo_write(dspi);
 }
 
-static int dspi_eoq_write(struct fsl_dspi *dspi)
+static u32 fifo_read(struct fsl_dspi *dspi)
 {
-	int tx_count = 0;
-	int tx_word;
-	u32 dspi_pushr = 0;
-
-	tx_word = is_double_byte_mode(dspi);
+	u32 rxdata = 0;
 
-	while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) {
-		/* If we are in word mode, only have a single byte to transfer
-		 * switch to byte mode temporarily.  Will switch back at the
-		 * end of the transfer.
-		 */
-		if (tx_word && (dspi->len == 1)) {
-			dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-			regmap_update_bits(dspi->regmap, SPI_CTAR(0),
-					SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
-			tx_word = 0;
-		}
-
-		dspi_pushr = dspi_data_to_pushr(dspi, tx_word);
-
-		if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1)
-			/* request EOQ flag for last transfer in queue */
-			dspi_pushr |= SPI_PUSHR_EOQ;
-
-		/* Clear transfer counter on first transfer (in FIFO) */
-		if (tx_count == 0)
-			dspi_pushr |= SPI_PUSHR_CTCNT;
-
-		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
-
-		tx_count++;
-	}
-
-	return tx_count * (tx_word + 1);
+	regmap_read(dspi->regmap, SPI_POPR, &rxdata);
+	return rxdata;
 }
 
-static int dspi_eoq_read(struct fsl_dspi *dspi)
+static void dspi_tcfq_read(struct fsl_dspi *dspi)
 {
-	int rx_count = 0;
-	int rx_word = is_double_byte_mode(dspi);
-
-	while ((dspi->rx < dspi->rx_end)
-			&& (rx_count < DSPI_FIFO_SIZE)) {
-		if (rx_word && (dspi->rx_end - dspi->rx) == 1)
-			rx_word = 0;
-
-		dspi_data_from_popr(dspi, rx_word);
-		rx_count++;
-	}
-
-	return rx_count;
+	dspi_push_rx(dspi, fifo_read(dspi));
 }
 
-static int dspi_tcfq_write(struct fsl_dspi *dspi)
+static void dspi_eoq_write(struct fsl_dspi *dspi)
 {
-	int tx_word;
-	u32 dspi_pushr = 0;
-
-	tx_word = is_double_byte_mode(dspi);
-
-	if (tx_word && (dspi->len == 1)) {
-		dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
-		regmap_update_bits(dspi->regmap, SPI_CTAR(0),
-				SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
-		tx_word = 0;
+	int fifo_size = DSPI_FIFO_SIZE;
+
+	/* Fill TX FIFO with as many transfers as possible */
+	while (dspi->len && fifo_size--) {
+		/* Request EOQF for last transfer in FIFO */
+		if (dspi->len == dspi->bytes_per_word || fifo_size == 0)
+			dspi->tx_cmd |= SPI_PUSHR_CMD_EOQ;
+		/* Clear transfer count for first transfer in FIFO */
+		if (fifo_size == (DSPI_FIFO_SIZE - 1))
+			dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT;
+		/* Write combined TX FIFO and CMD FIFO entry */
+		fifo_write(dspi);
 	}
-
-	dspi_pushr = dspi_data_to_pushr(dspi, tx_word);
-
-	/* Clear transfer counter on each transfer */
-	dspi_pushr |= SPI_PUSHR_CTCNT;
-
-	regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
-
-	return tx_word + 1;
 }
 
-static void dspi_tcfq_read(struct fsl_dspi *dspi)
+static void dspi_eoq_read(struct fsl_dspi *dspi)
 {
-	int rx_word = is_double_byte_mode(dspi);
-
-	if (rx_word && (dspi->rx_end - dspi->rx) == 1)
-		rx_word = 0;
+	int fifo_size = DSPI_FIFO_SIZE;
 
-	dspi_data_from_popr(dspi, rx_word);
+	/* Read one FIFO entry at and push to rx buffer */
+	while ((dspi->rx < dspi->rx_end) && fifo_size--)
+		dspi_push_rx(dspi, fifo_read(dspi));
 }
 
 static int dspi_transfer_one_message(struct spi_master *master,
@@ -691,19 +633,24 @@ static int dspi_transfer_one_message(struct spi_master *master,
 
 		dspi->void_write_data = dspi->cur_chip->void_write_data;
 
-		dspi->dataflags = 0;
-		dspi->tx = (void *)transfer->tx_buf;
-		dspi->tx_end = dspi->tx + transfer->len;
+		dspi->tx = transfer->tx_buf;
 		dspi->rx = transfer->rx_buf;
 		dspi->rx_end = dspi->rx + transfer->len;
 		dspi->len = transfer->len;
+		/* Validated transfer specific frame size (defaults applied) */
+		dspi->bits_per_word = transfer->bits_per_word;
+		if (transfer->bits_per_word <= 8)
+			dspi->bytes_per_word = 1;
+		else
+			dspi->bytes_per_word = 2;
 
 		regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
 		regmap_update_bits(dspi->regmap, SPI_MCR,
 				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
 				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
 		regmap_write(dspi->regmap, SPI_CTAR(0),
-				dspi->cur_chip->ctar_val);
+			     dspi->cur_chip->ctar_val |
+			     SPI_FRAME_BITS(transfer->bits_per_word));
 
 		trans_mode = dspi->devtype_data->trans_mode;
 		switch (trans_mode) {
@@ -754,16 +701,9 @@ static int dspi_setup(struct spi_device *spi)
 	struct fsl_dspi_platform_data *pdata;
 	u32 cs_sck_delay = 0, sck_cs_delay = 0;
 	unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
-	unsigned char pasc = 0, asc = 0, fmsz = 0;
+	unsigned char pasc = 0, asc = 0;
 	unsigned long clkrate;
 
-	if ((spi->bits_per_word >= 4) && (spi->bits_per_word <= 16)) {
-		fmsz = spi->bits_per_word - 1;
-	} else {
-		pr_err("Invalid wordsize\n");
-		return -ENODEV;
-	}
-
 	/* Only alloc on first setup */
 	chip = spi_get_ctldata(spi);
 	if (chip == NULL) {
@@ -799,8 +739,7 @@ static int dspi_setup(struct spi_device *spi)
 	/* Set After SCK delay scale values */
 	ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate);
 
-	chip->ctar_val =  SPI_CTAR_FMSZ(fmsz)
-		| SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0)
+	chip->ctar_val = SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0)
 		| SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0)
 		| SPI_CTAR_LSBFE(spi->mode & SPI_LSB_FIRST ? 1 : 0)
 		| SPI_CTAR_PCSSCK(pcssck)
@@ -832,24 +771,19 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 	enum dspi_trans_mode trans_mode;
 	u32 spi_sr, spi_tcr;
 	u16 spi_tcnt;
-	int tx_word;
 
 	regmap_read(dspi->regmap, SPI_SR, &spi_sr);
 	regmap_write(dspi->regmap, SPI_SR, spi_sr);
 
 
 	if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) {
-		tx_word = is_double_byte_mode(dspi);
-
 		/* Get transfer counter (in number of SPI transfers). It was
 		 * reset to 0 when transfer(s) were started.
 		 */
 		regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
 		spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
-
 		/* Update total number of bytes that were transferred */
-		msg->actual_length += spi_tcnt * (tx_word + 1) -
-			(dspi->dataflags & TRAN_STATE_WORD_ODD_NUM ? 1 : 0);
+		msg->actual_length += spi_tcnt * dspi->bytes_per_word;
 
 		trans_mode = dspi->devtype_data->trans_mode;
 		switch (trans_mode) {
@@ -866,14 +800,6 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id)
 		}
 
 		if (!dspi->len) {
-			if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) {
-				regmap_update_bits(dspi->regmap,
-						   SPI_CTAR(0),
-						   SPI_FRAME_BITS_MASK,
-						   SPI_FRAME_BITS(16));
-				dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM;
-			}
-
 			dspi->waitflags = 1;
 			wake_up_interruptible(&dspi->waitq);
 		} else {
@@ -973,8 +899,7 @@ static int dspi_probe(struct platform_device *pdev)
 
 	master->cleanup = dspi_cleanup;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
-	master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
-					SPI_BPW_MASK(16);
+	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (pdata) {
-- 
2.17.1


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

* [PATCH 06/12] spi: spi-fsl-dspi: Fixup regmap configuration
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (4 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 05/12] spi: spi-fsl-dspi: Support 4 to 16 bits per word transfers Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 07/12] spi: spi-fsl-dspi: Fix MCR register handling Esben Haabendal
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Mark volatile registers to avoid caching bugs.

Note: SPI_MCR is marked volatile because of CLR_TXF and CLR_RXF bits.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index df07dd4722fb..5c5905b6509f 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -862,11 +862,23 @@ static int dspi_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
 
+static const struct regmap_range dspi_volatile_ranges[] = {
+	regmap_reg_range(SPI_MCR, SPI_TCR),
+	regmap_reg_range(SPI_SR, SPI_SR),
+	regmap_reg_range(SPI_PUSHR, SPI_RXFR3),
+};
+
+static const struct regmap_access_table dspi_volatile_table = {
+	.yes_ranges     = dspi_volatile_ranges,
+	.n_yes_ranges   = ARRAY_SIZE(dspi_volatile_ranges),
+};
+
 static const struct regmap_config dspi_regmap_config = {
 	.reg_bits = 32,
 	.val_bits = 32,
 	.reg_stride = 4,
 	.max_register = 0x88,
+	.volatile_table = &dspi_volatile_table,
 };
 
 static void dspi_init(struct fsl_dspi *dspi)
-- 
2.17.1


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

* [PATCH 07/12] spi: spi-fsl-dspi: Fix MCR register handling
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (5 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 06/12] spi: spi-fsl-dspi: Fixup regmap configuration Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 08/12] spi: spi-fsl-dspi: Add support for XSPI mode registers Esben Haabendal
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

The MCR register is not changed, so initialize it in dspi_init().

The exception is the CLR_TXF and CLR_RXF bits, which should be written to
before each transfer to make sure we start with empty FIFOs.  With MCR
register now configured as volatile, the regmap_update_bits will do a real
read-modify-write cycle.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 5c5905b6509f..d83d3496d538 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -120,7 +120,6 @@
 #define DMA_COMPLETION_TIMEOUT	msecs_to_jiffies(3000)
 
 struct chip_data {
-	u32 mcr_val;
 	u32 ctar_val;
 	u16 void_write_data;
 };
@@ -644,10 +643,9 @@ static int dspi_transfer_one_message(struct spi_master *master,
 		else
 			dspi->bytes_per_word = 2;
 
-		regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
 		regmap_update_bits(dspi->regmap, SPI_MCR,
-				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
-				SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
+				   SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
+				   SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
 		regmap_write(dspi->regmap, SPI_CTAR(0),
 			     dspi->cur_chip->ctar_val |
 			     SPI_FRAME_BITS(transfer->bits_per_word));
@@ -725,9 +723,6 @@ static int dspi_setup(struct spi_device *spi)
 		sck_cs_delay = pdata->sck_cs_delay;
 	}
 
-	chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS |
-		SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
-
 	chip->void_write_data = 0;
 
 	clkrate = clk_get_rate(dspi->clk);
@@ -883,6 +878,7 @@ static const struct regmap_config dspi_regmap_config = {
 
 static void dspi_init(struct fsl_dspi *dspi)
 {
+	regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS);
 	regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
 }
 
-- 
2.17.1


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

* [PATCH 08/12] spi: spi-fsl-dspi: Add support for XSPI mode registers
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (6 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 07/12] spi: spi-fsl-dspi: Fix MCR register handling Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 09/12] spi: spi-fsl-dspi: Framesize control for XSPI mode Esben Haabendal
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

This prepares for adding support for extended SPI mode (XSPI), by extending
the regmap with the extra SREX and CTAREx registers.

An additional register map is made for allowing 16 bit access to CMD and TX
FIFO of the PUSHR register separately, which is also needed for XSPI mode
support.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 63 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index d83d3496d538..3e9dd645ee54 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -108,11 +108,21 @@
 #define SPI_RXFR2		0x84
 #define SPI_RXFR3		0x88
 
+#define SPI_CTARE(x)		(0x11c + (((x) & 0x3) * 4))
+#define SPI_CTARE_FMSZE(x)	(((x) & 0x1) << 16)
+#define SPI_CTARE_DTCP(x)	((x) & 0x7ff)
+
+#define SPI_SREX		0x13c
+
 #define SPI_FRAME_BITS(bits)	SPI_CTAR_FMSZ((bits) - 1)
 #define SPI_FRAME_BITS_MASK	SPI_CTAR_FMSZ(0xf)
 #define SPI_FRAME_BITS_16	SPI_CTAR_FMSZ(0xf)
 #define SPI_FRAME_BITS_8	SPI_CTAR_FMSZ(0x7)
 
+/* Register offsets for regmap_pushr */
+#define PUSHR_CMD		0x0
+#define PUSHR_TX		0x2
+
 #define SPI_CS_INIT		0x01
 #define SPI_CS_ASSERT		0x02
 #define SPI_CS_DROP		0x04
@@ -133,6 +143,7 @@ enum dspi_trans_mode {
 struct fsl_dspi_devtype_data {
 	enum dspi_trans_mode trans_mode;
 	u8 max_clock_factor;
+	bool xspi_mode;
 };
 
 static const struct fsl_dspi_devtype_data vf610_data = {
@@ -143,6 +154,7 @@ static const struct fsl_dspi_devtype_data vf610_data = {
 static const struct fsl_dspi_devtype_data ls1021a_v1_data = {
 	.trans_mode = DSPI_TCFQ_MODE,
 	.max_clock_factor = 8,
+	.xspi_mode = true,
 };
 
 static const struct fsl_dspi_devtype_data ls2085a_data = {
@@ -177,6 +189,7 @@ struct fsl_dspi {
 	struct platform_device	*pdev;
 
 	struct regmap		*regmap;
+	struct regmap		*regmap_pushr;
 	int			irq;
 	struct clk		*clk;
 
@@ -876,6 +889,35 @@ static const struct regmap_config dspi_regmap_config = {
 	.volatile_table = &dspi_volatile_table,
 };
 
+static const struct regmap_range dspi_xspi_volatile_ranges[] = {
+	regmap_reg_range(SPI_MCR, SPI_TCR),
+	regmap_reg_range(SPI_SR, SPI_SR),
+	regmap_reg_range(SPI_PUSHR, SPI_RXFR3),
+	regmap_reg_range(SPI_SREX, SPI_SREX),
+};
+
+static const struct regmap_access_table dspi_xspi_volatile_table = {
+	.yes_ranges     = dspi_xspi_volatile_ranges,
+	.n_yes_ranges   = ARRAY_SIZE(dspi_xspi_volatile_ranges),
+};
+
+static const struct regmap_config dspi_xspi_regmap_config[] = {
+	{
+		.reg_bits = 32,
+		.val_bits = 32,
+		.reg_stride = 4,
+		.max_register = 0x13c,
+		.volatile_table = &dspi_xspi_volatile_table,
+	},
+	{
+		.name = "pushr",
+		.reg_bits = 16,
+		.val_bits = 16,
+		.reg_stride = 2,
+		.max_register = 0x2,
+	},
+};
+
 static void dspi_init(struct fsl_dspi *dspi)
 {
 	regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS);
@@ -888,6 +930,7 @@ static int dspi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct fsl_dspi *dspi;
 	struct resource *res;
+	const struct regmap_config *regmap_config;
 	void __iomem *base;
 	struct fsl_dspi_platform_data *pdata;
 	int ret = 0, cs_num, bus_num;
@@ -946,8 +989,11 @@ static int dspi_probe(struct platform_device *pdev)
 		goto out_master_put;
 	}
 
-	dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
-						&dspi_regmap_config);
+	if (dspi->devtype_data->xspi_mode)
+		regmap_config = &dspi_xspi_regmap_config[0];
+	else
+		regmap_config = &dspi_regmap_config;
+	dspi->regmap = devm_regmap_init_mmio(&pdev->dev, base, regmap_config);
 	if (IS_ERR(dspi->regmap)) {
 		dev_err(&pdev->dev, "failed to init regmap: %ld\n",
 				PTR_ERR(dspi->regmap));
@@ -955,6 +1001,19 @@ static int dspi_probe(struct platform_device *pdev)
 		goto out_master_put;
 	}
 
+	if (dspi->devtype_data->xspi_mode) {
+		dspi->regmap_pushr = devm_regmap_init_mmio(
+			&pdev->dev, base + SPI_PUSHR,
+			&dspi_xspi_regmap_config[1]);
+		if (IS_ERR(dspi->regmap_pushr)) {
+			dev_err(&pdev->dev,
+				"failed to init pushr regmap: %ld\n",
+				PTR_ERR(dspi->regmap_pushr));
+			ret = PTR_ERR(dspi->regmap);
+			goto out_master_put;
+		}
+	}
+
 	dspi_init(dspi);
 	dspi->irq = platform_get_irq(pdev, 0);
 	if (dspi->irq < 0) {
-- 
2.17.1


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

* [PATCH 09/12] spi: spi-fsl-dspi: Framesize control for XSPI mode
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (7 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 08/12] spi: spi-fsl-dspi: Add support for XSPI mode registers Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 10/12] spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode) Esben Haabendal
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 3e9dd645ee54..ba83ff4512c9 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -119,6 +119,9 @@
 #define SPI_FRAME_BITS_16	SPI_CTAR_FMSZ(0xf)
 #define SPI_FRAME_BITS_8	SPI_CTAR_FMSZ(0x7)
 
+#define SPI_FRAME_EBITS(bits)	SPI_CTARE_FMSZE(((bits) - 1) >> 4)
+#define SPI_FRAME_EBITS_MASK	SPI_CTARE_FMSZE(1)
+
 /* Register offsets for regmap_pushr */
 #define PUSHR_CMD		0x0
 #define PUSHR_TX		0x2
@@ -662,6 +665,10 @@ static int dspi_transfer_one_message(struct spi_master *master,
 		regmap_write(dspi->regmap, SPI_CTAR(0),
 			     dspi->cur_chip->ctar_val |
 			     SPI_FRAME_BITS(transfer->bits_per_word));
+		if (dspi->devtype_data->xspi_mode)
+			regmap_write(dspi->regmap, SPI_CTARE(0),
+				     SPI_FRAME_EBITS(transfer->bits_per_word)
+				     | SPI_CTARE_DTCP(1));
 
 		trans_mode = dspi->devtype_data->trans_mode;
 		switch (trans_mode) {
@@ -922,6 +929,9 @@ static void dspi_init(struct fsl_dspi *dspi)
 {
 	regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS);
 	regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
+	if (dspi->devtype_data->xspi_mode)
+		regmap_write(dspi->regmap, SPI_CTARE(0),
+			     SPI_CTARE_FMSZE(0) | SPI_CTARE_DTCP(1));
 }
 
 static int dspi_probe(struct platform_device *pdev)
-- 
2.17.1


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

* [PATCH 10/12] spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode)
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (8 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 09/12] spi: spi-fsl-dspi: Framesize control for XSPI mode Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 11/12] spi: spi-fsl-dspi: Advertise 32 bit for XSPI mode Esben Haabendal
  2018-06-20  7:34 ` [PATCH 12/12] spi: spi-fsl-dspi: Enable extended SPI mode Esben Haabendal
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

This implements handling of split CMD and TX FIFO queues for XSPI when
running in TCFQ mode.

It should be simple to add it to EOQ mode also.  Currently, EOQ mode is
only used with coldfire.  So if coldfire DSPI supports XSPI, XSPI FIFO
handling should be added to EOQ mode also.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 55 +++++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index ba83ff4512c9..67cd2e901255 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -215,15 +215,17 @@ struct fsl_dspi {
 	struct fsl_dspi_dma	*dma;
 };
 
-static u16 dspi_pop_tx(struct fsl_dspi *dspi)
+static u32 dspi_pop_tx(struct fsl_dspi *dspi)
 {
-	u16 txdata = 0;
+	u32 txdata = 0;
 
 	if (dspi->tx) {
 		if (dspi->bytes_per_word == 1)
 			txdata = *(u8 *)dspi->tx;
-		else /* dspi->bytes_per_word == 2 */
+		else if (dspi->bytes_per_word == 2)
 			txdata = *(u16 *)dspi->tx;
+		else  /* dspi->bytes_per_word == 4 */
+			txdata = *(u32 *)dspi->tx;
 		dspi->tx += dspi->bytes_per_word;
 	}
 	dspi->len -= dspi->bytes_per_word;
@@ -249,8 +251,10 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
 
 	if (dspi->bytes_per_word == 1)
 		*(u8 *)dspi->rx = rxdata;
-	else /* dspi->bytes_per_word == 2 */
+	else if (dspi->bytes_per_word == 2)
 		*(u16 *)dspi->rx = rxdata;
+	else /* dspi->bytes_per_word == 4 */
+		*(u32 *)dspi->rx = rxdata;
 	dspi->rx += dspi->bytes_per_word;
 }
 
@@ -564,12 +568,47 @@ static void fifo_write(struct fsl_dspi *dspi)
 	regmap_write(dspi->regmap, SPI_PUSHR, dspi_pop_tx_pushr(dspi));
 }
 
+static void cmd_fifo_write(struct fsl_dspi *dspi)
+{
+	u16 cmd = dspi->tx_cmd;
+
+	if (dspi->len > 0)
+		cmd |= SPI_PUSHR_CMD_CONT;
+	regmap_write(dspi->regmap_pushr, PUSHR_CMD, cmd);
+}
+
+static void tx_fifo_write(struct fsl_dspi *dspi, u16 txdata)
+{
+	regmap_write(dspi->regmap_pushr, PUSHR_TX, txdata);
+}
+
 static void dspi_tcfq_write(struct fsl_dspi *dspi)
 {
 	/* Clear transfer count */
 	dspi->tx_cmd |= SPI_PUSHR_CMD_CTCNT;
-	/* Write one entry to both TX FIFO and CMD FIFO simultaneously */
-	fifo_write(dspi);
+
+	if (dspi->devtype_data->xspi_mode && dspi->bits_per_word > 16) {
+		/* Write two TX FIFO entries first, and then the corresponding
+		 * CMD FIFO entry.
+		 */
+		u32 data = dspi_pop_tx(dspi);
+
+		if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
+			/* LSB */
+			tx_fifo_write(dspi, data & 0xFFFF);
+			tx_fifo_write(dspi, data >> 16);
+		} else {
+			/* MSB */
+			tx_fifo_write(dspi, data >> 16);
+			tx_fifo_write(dspi, data & 0xFFFF);
+		}
+		cmd_fifo_write(dspi);
+	} else {
+		/* Write one entry to both TX FIFO and CMD FIFO
+		 * simultaneously.
+		 */
+		fifo_write(dspi);
+	}
 }
 
 static u32 fifo_read(struct fsl_dspi *dspi)
@@ -656,8 +695,10 @@ static int dspi_transfer_one_message(struct spi_master *master,
 		dspi->bits_per_word = transfer->bits_per_word;
 		if (transfer->bits_per_word <= 8)
 			dspi->bytes_per_word = 1;
-		else
+		else if (transfer->bits_per_word <= 16)
 			dspi->bytes_per_word = 2;
+		else
+			dspi->bytes_per_word = 4;
 
 		regmap_update_bits(dspi->regmap, SPI_MCR,
 				   SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
-- 
2.17.1


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

* [PATCH 11/12] spi: spi-fsl-dspi: Advertise 32 bit for XSPI mode
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (9 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 10/12] spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode) Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  2018-06-20  7:34 ` [PATCH 12/12] spi: spi-fsl-dspi: Enable extended SPI mode Esben Haabendal
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 67cd2e901255..eed55491b2c9 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -1001,7 +1001,6 @@ static int dspi_probe(struct platform_device *pdev)
 
 	master->cleanup = dspi_cleanup;
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
-	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 
 	pdata = dev_get_platdata(&pdev->dev);
 	if (pdata) {
@@ -1033,6 +1032,11 @@ static int dspi_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (dspi->devtype_data->xspi_mode)
+		master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+	else
+		master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(base)) {
-- 
2.17.1


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

* [PATCH 12/12] spi: spi-fsl-dspi: Enable extended SPI mode
  2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
                   ` (10 preceding siblings ...)
  2018-06-20  7:34 ` [PATCH 11/12] spi: spi-fsl-dspi: Advertise 32 bit for XSPI mode Esben Haabendal
@ 2018-06-20  7:34 ` Esben Haabendal
  11 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20  7:34 UTC (permalink / raw)
  To: Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

From: Esben Haabendal <eha@deif.com>

Set the XSPI bit for devices configured for XSPI mode (currently LS1021A),
and thereby switch to extended SPI mode, allowing for SPI transfers using
from 4 to 32 bits per word instead of 4 to 16 bits per word.

Signed-off-by: Esben Haabendal <eha@deif.com>
Cc: Martin Hundebøll <martin@geanix.com>
---
 drivers/spi/spi-fsl-dspi.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index eed55491b2c9..1f85dcdb2203 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -46,6 +46,7 @@
 #define SPI_MCR_PCSIS		(0x3F << 16)
 #define SPI_MCR_CLR_TXF	(1 << 11)
 #define SPI_MCR_CLR_RXF	(1 << 10)
+#define SPI_MCR_XSPI		(1 << 3)
 
 #define SPI_TCR			0x08
 #define SPI_TCR_GET_TCNT(x)	(((x) & 0xffff0000) >> 16)
@@ -968,7 +969,8 @@ static const struct regmap_config dspi_xspi_regmap_config[] = {
 
 static void dspi_init(struct fsl_dspi *dspi)
 {
-	regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS);
+	regmap_write(dspi->regmap, SPI_MCR, SPI_MCR_MASTER | SPI_MCR_PCSIS |
+		     (dspi->devtype_data->xspi_mode ? SPI_MCR_XSPI : 0));
 	regmap_write(dspi->regmap, SPI_SR, SPI_SR_CLEAR);
 	if (dspi->devtype_data->xspi_mode)
 		regmap_write(dspi->regmap, SPI_CTARE(0),
-- 
2.17.1


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

* Re: [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement
  2018-06-20  7:34 ` [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement Esben Haabendal
@ 2018-06-20  8:40   ` Martin Hundebøll
  0 siblings, 0 replies; 16+ messages in thread
From: Martin Hundebøll @ 2018-06-20  8:40 UTC (permalink / raw)
  To: Esben Haabendal, Mark Brown, linux-spi
  Cc: Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal



On 2018-06-20 09:34, Esben Haabendal wrote:
> From: Esben Haabendal <eha@deif.com>
> 
> The if statement just above this if/else statement triggers on the same
> condition, and then invalidates it.
> 
> Signed-off-by: Esben Haabendal <eha@deif.com>
> Cc: Martin Hundebøll <martin@geanix.com>

For the entire series:
Acked-by: Martin Hundebøll <martin@geanix.com>

> ---
>   drivers/spi/spi-fsl-dspi.c | 3 +--
>   1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
> index 0630962ce442..3ca9b9608801 100644
> --- a/drivers/spi/spi-fsl-dspi.c
> +++ b/drivers/spi/spi-fsl-dspi.c
> @@ -593,8 +593,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
>   			dspi_pushr |= SPI_PUSHR_EOQ;
>   			if ((dspi->cs_change) && (!dspi->len))
>   				dspi_pushr &= ~SPI_PUSHR_CONT;
> -		} else if (tx_word && (dspi->len == 1))
> -			dspi_pushr |= SPI_PUSHR_EOQ;
> +		}
>   
>   		regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
>   
> 

-- 
Kind regards,
Martin Hundebøll
Embedded Linux Consultant

+45 61 65 54 61
martin@geanix.com

Geanix IVS
DK39600706

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

* Re: [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling
  2018-06-20  7:34 ` [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling Esben Haabendal
@ 2018-06-20 13:27   ` Mark Brown
  2018-06-20 13:40     ` Esben Haabendal
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Brown @ 2018-06-20 13:27 UTC (permalink / raw)
  To: Esben Haabendal
  Cc: linux-spi, Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Esben Haabendal,
	Martin Hundebøll

[-- Attachment #1: Type: text/plain, Size: 592 bytes --]

On Wed, Jun 20, 2018 at 09:34:33AM +0200, Esben Haabendal wrote:

> As of 92dc20d83adec565378254c0630e839ff5674e14, transfer->cs_change has
> been supported for non-last transfers, but not for last transfer.

Please include human readable descriptions of things like commits and
issues being discussed in e-mail in your mails, this makes them much
easier for humans to read especially when they have no internet access.
I do frequently catch up on my mail on flights or while otherwise
travelling so this is even more pressing for me than just being about
making things a bit easier to read.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling
  2018-06-20 13:27   ` Mark Brown
@ 2018-06-20 13:40     ` Esben Haabendal
  0 siblings, 0 replies; 16+ messages in thread
From: Esben Haabendal @ 2018-06-20 13:40 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, Kurt Kanzenbach, Angelo Dureghello, Nikita Yushchenko,
	Sanchayan Maity, Yuan Yao, linux-kernel, Martin Hundebøll

Mark Brown <broonie@kernel.org> writes:

> On Wed, Jun 20, 2018 at 09:34:33AM +0200, Esben Haabendal wrote:
>
>> As of 92dc20d83adec565378254c0630e839ff5674e14, transfer->cs_change has
>> been supported for non-last transfers, but not for last transfer.
>
> Please include human readable descriptions of things like commits and
> issues being discussed in e-mail in your mails, this makes them much
> easier for humans to read especially when they have no internet access.
> I do frequently catch up on my mail on flights or while otherwise
> travelling so this is even more pressing for me than just being about
> making things a bit easier to read.

Ok.  I will add the commit title to v2.

/Esben

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

end of thread, other threads:[~2018-06-20 13:40 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-20  7:34 [PATCH 00/12] XSPI mode for LS1021A DSPI Esben Haabendal
2018-06-20  7:34 ` [PATCH 01/12] spi: spi-fsl-dspi: Drop unreachable else if statement Esben Haabendal
2018-06-20  8:40   ` Martin Hundebøll
2018-06-20  7:34 ` [PATCH 02/12] spi: spi-fsl-dspi: Drop unneeded use of dataflags bits Esben Haabendal
2018-06-20  7:34 ` [PATCH 03/12] spi: spi-fsl-dspi: Fix per transfer cs_change handling Esben Haabendal
2018-06-20 13:27   ` Mark Brown
2018-06-20 13:40     ` Esben Haabendal
2018-06-20  7:34 ` [PATCH 04/12] spi: spi-fsl-dspi: Simplify transfer counter handling Esben Haabendal
2018-06-20  7:34 ` [PATCH 05/12] spi: spi-fsl-dspi: Support 4 to 16 bits per word transfers Esben Haabendal
2018-06-20  7:34 ` [PATCH 06/12] spi: spi-fsl-dspi: Fixup regmap configuration Esben Haabendal
2018-06-20  7:34 ` [PATCH 07/12] spi: spi-fsl-dspi: Fix MCR register handling Esben Haabendal
2018-06-20  7:34 ` [PATCH 08/12] spi: spi-fsl-dspi: Add support for XSPI mode registers Esben Haabendal
2018-06-20  7:34 ` [PATCH 09/12] spi: spi-fsl-dspi: Framesize control for XSPI mode Esben Haabendal
2018-06-20  7:34 ` [PATCH 10/12] spi: spi-fsl-dspi: XSPI FIFO handling (in TCFQ mode) Esben Haabendal
2018-06-20  7:34 ` [PATCH 11/12] spi: spi-fsl-dspi: Advertise 32 bit for XSPI mode Esben Haabendal
2018-06-20  7:34 ` [PATCH 12/12] spi: spi-fsl-dspi: Enable extended SPI mode Esben Haabendal

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).