linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: "linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [PATCH 2/4] spi: fsl-espi: eliminate need for linearization when writing to hardware
Date: Fri, 25 Nov 2016 23:59:24 +0100	[thread overview]
Message-ID: <fe019347-2d40-7e0a-4ee4-cadaa8930d5f@gmail.com> (raw)
In-Reply-To: <2424ba57-be1a-d32d-0c14-1662c2d02409-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Eliminate need for linearization when writing to the hardware and
read from the transfer buffers directly.

Signed-off-by: Heiner Kallweit <hkallweit1-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 drivers/spi/spi-fsl-espi.c | 79 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 14 deletions(-)

diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 4222578..189ab36 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -98,6 +98,11 @@ struct fsl_espi {
 	const void *tx;
 	void *rx;
 
+	struct list_head *m_transfers;
+	struct spi_transfer *tx_t;
+	unsigned int tx_pos;
+	bool tx_done;
+
 	bool swab;
 	unsigned int rx_len;
 	unsigned int tx_len;
@@ -131,6 +136,12 @@ static inline void fsl_espi_write_reg(struct fsl_espi *espi, int offset,
 	iowrite32be(val, espi->reg_base + offset);
 }
 
+static inline void fsl_espi_write_reg16(struct fsl_espi *espi, int offset,
+					u16 val)
+{
+	iowrite16(val, espi->reg_base + offset);
+}
+
 static inline void fsl_espi_write_reg8(struct fsl_espi *espi, int offset,
 				       u8 val)
 {
@@ -260,22 +271,58 @@ static unsigned int fsl_espi_check_rxskip_mode(struct spi_message *m)
 static void fsl_espi_fill_tx_fifo(struct fsl_espi *espi, u32 events)
 {
 	u32 tx_fifo_avail;
+	unsigned int tx_left;
+	const void *tx_buf;
 
 	/* if events is zero transfer has not started and tx fifo is empty */
 	tx_fifo_avail = events ? SPIE_TXCNT(events) :  FSL_ESPI_FIFO_SIZE;
-
-	while (tx_fifo_avail >= min(4U, espi->tx_len) && espi->tx_len)
-		if (espi->tx_len >= 4) {
-			fsl_espi_write_reg(espi, ESPI_SPITF, *(u32 *)espi->tx);
-			espi->tx += 4;
-			espi->tx_len -= 4;
+start:
+	tx_left = espi->tx_t->len - espi->tx_pos;
+	tx_buf = espi->tx_t->tx_buf;
+	while (tx_fifo_avail >= min(4U, tx_left) && tx_left) {
+		if (tx_left >= 4) {
+			if (!tx_buf)
+				fsl_espi_write_reg(espi, ESPI_SPITF, 0);
+			else if (espi->swab)
+				fsl_espi_write_reg(espi, ESPI_SPITF,
+					swahb32p(tx_buf + espi->tx_pos));
+			else
+				fsl_espi_write_reg(espi, ESPI_SPITF,
+					*(u32 *)(tx_buf + espi->tx_pos));
+			espi->tx_pos += 4;
+			tx_left -= 4;
 			tx_fifo_avail -= 4;
+		} else if (tx_left >= 2 && tx_buf && espi->swab) {
+			fsl_espi_write_reg16(espi, ESPI_SPITF,
+					swab16p(tx_buf + espi->tx_pos));
+			espi->tx_pos += 2;
+			tx_left -= 2;
+			tx_fifo_avail -= 2;
 		} else {
-			fsl_espi_write_reg8(espi, ESPI_SPITF, *(u8 *)espi->tx);
-			espi->tx += 1;
-			espi->tx_len -= 1;
+			if (!tx_buf)
+				fsl_espi_write_reg8(espi, ESPI_SPITF, 0);
+			else
+				fsl_espi_write_reg8(espi, ESPI_SPITF,
+					*(u8 *)(tx_buf + espi->tx_pos));
+			espi->tx_pos += 1;
+			tx_left -= 1;
 			tx_fifo_avail -= 1;
 		}
+	}
+
+	if (!tx_left) {
+		/* Last transfer finished, in rxskip mode only one is needed */
+		if (list_is_last(&espi->tx_t->transfer_list,
+		    espi->m_transfers) || espi->rxskip) {
+			espi->tx_done = true;
+			return;
+		}
+		espi->tx_t = list_next_entry(espi->tx_t, transfer_list);
+		espi->tx_pos = 0;
+		/* continue with next transfer if tx fifo is not full */
+		if (tx_fifo_avail)
+			goto start;
+	}
 }
 
 static void fsl_espi_read_rx_fifo(struct fsl_espi *espi, u32 events)
@@ -369,9 +416,7 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
 	/* Won't hang up forever, SPI bus sometimes got lost interrupts... */
 	ret = wait_for_completion_timeout(&espi->done, 2 * HZ);
 	if (ret == 0)
-		dev_err(espi->dev,
-			"Transaction hanging up (left %u tx bytes, %u rx bytes)\n",
-			espi->tx_len, espi->rx_len);
+		dev_err(espi->dev, "Transfer timed out!\n");
 
 	/* disable rx ints */
 	fsl_espi_write_reg(espi, ESPI_SPIM, 0);
@@ -388,6 +433,12 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans)
 	/* In case of LSB-first and bits_per_word > 8 byte-swap all words */
 	espi->swab = spi->mode & SPI_LSB_FIRST && trans->bits_per_word > 8;
 
+	espi->m_transfers = &m->transfers;
+	espi->tx_t = list_first_entry(&m->transfers, struct spi_transfer,
+				      transfer_list);
+	espi->tx_pos = 0;
+	espi->tx_done = false;
+
 	espi->rxskip = fsl_espi_check_rxskip_mode(m);
 	if (trans->rx_nbits == SPI_NBITS_DUAL && !espi->rxskip) {
 		dev_err(espi->dev, "Dual output mode requires RXSKIP mode!\n");
@@ -508,10 +559,10 @@ static void fsl_espi_cpu_irq(struct fsl_espi *espi, u32 events)
 	if (espi->rx_len)
 		fsl_espi_read_rx_fifo(espi, events);
 
-	if (espi->tx_len)
+	if (!espi->tx_done)
 		fsl_espi_fill_tx_fifo(espi, events);
 
-	if (espi->tx_len || espi->rx_len)
+	if (!espi->tx_done || espi->rx_len)
 		return;
 
 	/* we're done, but check for errors before returning */
-- 
2.10.2


--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2016-11-25 22:59 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <2424ba57-be1a-d32d-0c14-1662c2d02409@gmail.com>
     [not found] ` <2424ba57-be1a-d32d-0c14-1662c2d02409-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-25 22:58   ` [PATCH 1/4] spi: fsl-espi: determine need for byte swap only once Heiner Kallweit
     [not found]     ` <bfa9887d-ed21-6d89-7e7b-d65c67571d85-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-30 18:08       ` Applied "spi: fsl-espi: determine need for byte swap only once" to the spi tree Mark Brown
2016-11-25 22:59   ` Heiner Kallweit [this message]
     [not found]     ` <fe019347-2d40-7e0a-4ee4-cadaa8930d5f-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-30 18:08       ` Applied "spi: fsl-espi: eliminate need for linearization when writing to hardware" " Mark Brown
2016-11-25 22:59   ` [PATCH 3/4] spi: fsl-espi: eliminate need for linearization when reading from hardware Heiner Kallweit
     [not found]     ` <80a5a858-dc54-ea9d-3c6e-34fdedc516d7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-30 18:07       ` Applied "spi: fsl-espi: eliminate need for linearization when reading from hardware" to the spi tree Mark Brown
2016-11-25 23:00   ` [PATCH 4/4] spi: fsl-espi: remove unused linearization code Heiner Kallweit
     [not found]     ` <4ce7fd3d-bdb2-3e28-a362-b4a61a207a89-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-11-30 18:07       ` Applied "spi: fsl-espi: remove unused linearization code" to the spi tree Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fe019347-2d40-7e0a-4ee4-cadaa8930d5f@gmail.com \
    --to=hkallweit1-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).