linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/1] spi: Using Trigger number to transmit/receive data
@ 2014-10-06  9:54 Cao Minh Hiep
  2014-10-06  9:54 ` [PATCH v2 1/1] " Cao Minh Hiep
  0 siblings, 1 reply; 2+ messages in thread
From: Cao Minh Hiep @ 2014-10-06  9:54 UTC (permalink / raw)
  To: broonie, geert+renesas
  Cc: linux-spi, kuninori.morimoto.gx, yoshihiro.shimoda.uh,
	ryusuke.sakato.bx, linux-sh

From: Hiep Cao Minh <cm-hiep@jinso.co.jp>

Hi Geert, Mark Brown

Here is the verion 2 of the QSPI patch, I have added the DMA support on it.
In order to use DMA When the DMA is available. 
This patch supports for r8a7790 SOC and developed base on the upstream-v3.17-rc7
and have tested on the Lager board.

Version 1:

This is the patch of QSPI that support for r8a7790 SOC. The pupose of 
this patch is to transmit and receive the 32 bytes of data when the data 
already has prepared on Transmit/Receive Buffer. Using Transmit/Receive 
Buffer Data Trigger Number to do that instead transmits/receives a byte 
of data. With this patch will improve the speed of transfer data.
This patch was developed base on the upstream-v3.17-rc5 and have 
tested on the Lager board.


Best Regards,
Cao Minh Hiep 

Hiep Cao Minh (1):
  spi: Using Trigger number to transmit/receive data

 drivers/spi/spi-rspi.c | 138 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 125 insertions(+), 13 deletions(-)

-- 
1.9.1


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

* [PATCH v2 1/1] spi: Using Trigger number to transmit/receive data
  2014-10-06  9:54 [PATCH v2 0/1] spi: Using Trigger number to transmit/receive data Cao Minh Hiep
@ 2014-10-06  9:54 ` Cao Minh Hiep
  0 siblings, 0 replies; 2+ messages in thread
From: Cao Minh Hiep @ 2014-10-06  9:54 UTC (permalink / raw)
  To: broonie, geert+renesas
  Cc: linux-spi, kuninori.morimoto.gx, yoshihiro.shimoda.uh,
	ryusuke.sakato.bx, linux-sh

From: Hiep Cao Minh <cm-hiep@jinso.co.jp>

In order to transmit and receive data when have 32 bytes of data that
ready has prepared on Transmit/Receive Buffer to transmit or receive.
Instead transmits/receives a byte data using Transmit/Receive Buffer
Data Triggering Number will improve the speed of transfer data.

Signed-off-by: Hiep Cao Minh <cm-hiep@jinso.co.jp>
---
 drivers/spi/spi-rspi.c | 138 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 125 insertions(+), 13 deletions(-)

diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index ad87a98..2d2dff2 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -182,6 +182,13 @@
 #define SPBFCR_RXRST		0x40	/* Receive Buffer Data Reset */
 #define SPBFCR_TXTRG_MASK	0x30	/* Transmit Buffer Data Triggering Number */
 #define SPBFCR_RXTRG_MASK	0x07	/* Receive Buffer Data Triggering Number */
+/* QSPI on R-Car H2 */
+#define SPBFCR_TXTRG_32B	0x00	/* 32Byte Transmit Buffer Triggering */
+#define SPBFCR_TXTRG_1B		0x30	/* 1Byte Transmit Buffer Triggering */
+#define SPBFCR_RXTRG_1B		0x00	/* 32Byte Receive Buffer Triggering */
+#define SPBFCR_RXTRG_32B	0x07	/* 1Byte Receive Buffer Triggering */
+
+#define QSPI_BUFFER_SIZE        32
 
 struct rspi_data {
 	void __iomem *addr;
@@ -371,6 +378,52 @@ static int qspi_set_config_register(struct rspi_data *rspi, int access_size)
 	return 0;
 }
 
+static void qspi_update(const struct rspi_data *rspi, u8 mask, u8 val, u8 reg)
+{
+	u8 data;
+
+	data = rspi_read8(rspi, reg);
+	data &= ~mask;
+	data |= (val & mask);
+	rspi_write8(rspi, data, reg);
+}
+
+static int qspi_set_send_trigger(struct rspi_data *rspi, int len)
+{
+	int n;
+
+	n = min(len, QSPI_BUFFER_SIZE);
+
+	if (len >= QSPI_BUFFER_SIZE) {
+		/* sets triggering number to 32 bytes */
+		qspi_update(rspi, SPBFCR_TXTRG_MASK,
+			     SPBFCR_TXTRG_32B, QSPI_SPBFCR);
+	} else {
+		/* sets triggering number to 1 byte */
+		qspi_update(rspi, SPBFCR_TXTRG_MASK,
+			     SPBFCR_TXTRG_1B, QSPI_SPBFCR);
+	}
+
+	return n;
+}
+
+static void qspi_set_receive_trigger(struct rspi_data *rspi, int len)
+{
+	int n;
+
+	n = min(len, QSPI_BUFFER_SIZE);
+
+	if (len >= QSPI_BUFFER_SIZE) {
+		/* sets triggering number to 32 bytes */
+		qspi_update(rspi, SPBFCR_RXTRG_MASK,
+			     SPBFCR_RXTRG_32B, QSPI_SPBFCR);
+	} else {
+		/* sets triggering number to 1 byte */
+		qspi_update(rspi, SPBFCR_RXTRG_MASK,
+			     SPBFCR_RXTRG_1B, QSPI_SPBFCR);
+	}
+}
+
 #define set_config_register(spi, n) spi->ops->set_config_register(spi, n)
 
 static void rspi_enable_irq(const struct rspi_data *rspi, u8 enable)
@@ -410,27 +463,40 @@ static inline int rspi_wait_for_rx_full(struct rspi_data *rspi)
 	return rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE);
 }
 
-static int rspi_data_out(struct rspi_data *rspi, u8 data)
+static int rspi_wait_for_tx_empty_check(struct rspi_data *rspi)
 {
 	int error = rspi_wait_for_tx_empty(rspi);
 	if (error < 0) {
 		dev_err(&rspi->master->dev, "transmit timeout\n");
 		return error;
 	}
-	rspi_write_data(rspi, data);
+
 	return 0;
 }
 
-static int rspi_data_in(struct rspi_data *rspi)
+static int rspi_wait_for_rx_full_check(struct rspi_data *rspi)
 {
-	int error;
-	u8 data;
-
-	error = rspi_wait_for_rx_full(rspi);
+	int error = rspi_wait_for_rx_full(rspi);
 	if (error < 0) {
 		dev_err(&rspi->master->dev, "receive timeout\n");
 		return error;
 	}
+
+	return 0;
+}
+
+static int rspi_data_out(struct rspi_data *rspi, u8 data)
+{
+	rspi_wait_for_tx_empty_check(rspi);
+	rspi_write_data(rspi, data);
+	return 0;
+}
+
+static int rspi_data_in(struct rspi_data *rspi)
+{
+	u8 data;
+
+	rspi_wait_for_rx_full_check(rspi);
 	data = rspi_read_data(rspi);
 	return data;
 }
@@ -614,19 +680,28 @@ static bool rspi_can_dma(struct spi_master *master, struct spi_device *spi,
 	return __rspi_can_dma(rspi, xfer);
 }
 
-static int rspi_common_transfer(struct rspi_data *rspi,
-				struct spi_transfer *xfer)
+static int rspi_dma_check_then_transfer(struct rspi_data *rspi,
+					 struct spi_transfer *xfer)
 {
-	int ret;
-
 	if (rspi->master->can_dma && __rspi_can_dma(rspi, xfer)) {
 		/* rx_buf can be NULL on RSPI on SH in TX-only Mode */
-		ret = rspi_dma_transfer(rspi, &xfer->tx_sg,
+		int ret = rspi_dma_transfer(rspi, &xfer->tx_sg,
 					xfer->rx_buf ? &xfer->rx_sg : NULL);
 		if (ret != -EAGAIN)
 			return ret;
 	}
 
+	return 0;
+}
+
+static int rspi_common_transfer(struct rspi_data *rspi,
+				struct spi_transfer *xfer)
+{
+	int ret;
+
+	ret = rspi_dma_check_then_transfer(rspi, xfer);
+	if (ret < 0)
+		return ret;
 	ret = rspi_pio_transfer(rspi, xfer->tx_buf, xfer->rx_buf, xfer->len);
 	if (ret < 0)
 		return ret;
@@ -666,12 +741,49 @@ static int rspi_rz_transfer_one(struct spi_master *master,
 	return rspi_common_transfer(rspi, xfer);
 }
 
+static int qspi_trigger_transfer_out_int(struct rspi_data *rspi, const u8 *tx,
+					u8 *rx, unsigned int len)
+{
+	int i, n, ret;
+
+	while (len > 0) {
+		n = qspi_set_send_trigger(rspi, len);
+		qspi_set_receive_trigger(rspi, len);
+		if (n == QSPI_BUFFER_SIZE) {
+			rspi_wait_for_tx_empty_check(rspi);
+			for (i = 0; i < n; i++)
+				rspi_write_data(rspi, *tx++);
+			rspi_wait_for_rx_full_check(rspi);
+			for (i = 0; i < n; i++)
+				*rx++ = rspi_read_data(rspi);
+		} else {
+			ret = rspi_pio_transfer(rspi, tx, rx, n);
+			if (ret < 0)
+				return ret;
+		}
+		len -= n;
+	}
+
+	return 0;
+}
+
 static int qspi_transfer_out_in(struct rspi_data *rspi,
 				struct spi_transfer *xfer)
 {
+	int ret;
+
 	qspi_receive_init(rspi);
 
-	return rspi_common_transfer(rspi, xfer);
+	ret = rspi_dma_check_then_transfer(rspi, xfer);
+	if (ret < 0)
+		return ret;
+
+	ret = qspi_trigger_transfer_out_int(rspi, xfer->tx_buf,
+					    xfer->rx_buf, xfer->len);
+	if (ret < 0)
+		return ret;
+
+	return 0;
 }
 
 static int qspi_transfer_out(struct rspi_data *rspi, struct spi_transfer *xfer)
-- 
1.9.1


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

end of thread, other threads:[~2014-10-06  9:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-06  9:54 [PATCH v2 0/1] spi: Using Trigger number to transmit/receive data Cao Minh Hiep
2014-10-06  9:54 ` [PATCH v2 1/1] " Cao Minh Hiep

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