summaryrefslogtreecommitdiff
path: root/target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch')
-rw-r--r--target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch198
1 files changed, 0 insertions, 198 deletions
diff --git a/target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch b/target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
deleted file mode 100644
index 83f21a5c0a..0000000000
--- a/target/linux/pistachio/patches-5.10/102-spi-img-spfi-Implement-dual-and-quad-mode.patch
+++ /dev/null
@@ -1,198 +0,0 @@
-From cd2a6af51553d38072cd31699b58d16ca6176ef5 Mon Sep 17 00:00:00 2001
-From: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Date: Thu, 2 Feb 2017 16:46:14 +0000
-Subject: spi: img-spfi: Implement dual and quad mode
-
-For dual and quad modes to work the SPFI controller needs
-to have information about command/address/dummy bytes in the
-transaction register. This information is not relevant for
-single mode, and therefore it can have any value in the
-allowed range. Therefore, for any read or write transfers of less
-than 8 bytes (cmd = 1 byte, addr up to 7 bytes), SPFI will be
-configured, but not enabled (unless it is the last transfer in
-the queue). The transfer will be enabled by the subsequent tranfer.
-A pending transfer is determined by the content of the transaction
-register: if command part is set and tsize is not.
-
-This way we ensure that for dual and quad transactions
-the command request size will apear in the command/address part
-of the transaction register, while the data size will be in
-tsize, all data being sent/received in the same transaction (as
-set up in the transaction register).
-
-Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com>
-Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
----
- drivers/spi/spi-img-spfi.c | 96 ++++++++++++++++++++++++++++++++++++++++------
- 1 file changed, 85 insertions(+), 11 deletions(-)
-
---- a/drivers/spi/spi-img-spfi.c
-+++ b/drivers/spi/spi-img-spfi.c
-@@ -36,7 +36,8 @@
- #define SPFI_CONTROL_SOFT_RESET BIT(11)
- #define SPFI_CONTROL_SEND_DMA BIT(10)
- #define SPFI_CONTROL_GET_DMA BIT(9)
--#define SPFI_CONTROL_SE BIT(8)
-+#define SPFI_CONTROL_SE BIT(8)
-+#define SPFI_CONTROL_TX_RX BIT(1)
- #define SPFI_CONTROL_TMODE_SHIFT 5
- #define SPFI_CONTROL_TMODE_MASK 0x7
- #define SPFI_CONTROL_TMODE_SINGLE 0
-@@ -47,6 +48,10 @@
- #define SPFI_TRANSACTION 0x18
- #define SPFI_TRANSACTION_TSIZE_SHIFT 16
- #define SPFI_TRANSACTION_TSIZE_MASK 0xffff
-+#define SPFI_TRANSACTION_CMD_SHIFT 13
-+#define SPFI_TRANSACTION_CMD_MASK 0x7
-+#define SPFI_TRANSACTION_ADDR_SHIFT 10
-+#define SPFI_TRANSACTION_ADDR_MASK 0x7
-
- #define SPFI_PORT_STATE 0x1c
- #define SPFI_PORT_STATE_DEV_SEL_SHIFT 20
-@@ -83,6 +88,7 @@
- */
- #define SPFI_32BIT_FIFO_SIZE 64
- #define SPFI_8BIT_FIFO_SIZE 16
-+#define SPFI_DATA_REQUEST_MAX_SIZE 8
-
- struct img_spfi {
- struct device *dev;
-@@ -99,6 +105,8 @@ struct img_spfi {
- struct dma_chan *tx_ch;
- bool tx_dma_busy;
- bool rx_dma_busy;
-+
-+ bool complete;
- };
-
- static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg)
-@@ -115,9 +123,11 @@ static inline void spfi_start(struct img
- {
- u32 val;
-
-- val = spfi_readl(spfi, SPFI_CONTROL);
-- val |= SPFI_CONTROL_SPFI_EN;
-- spfi_writel(spfi, val, SPFI_CONTROL);
-+ if (spfi->complete) {
-+ val = spfi_readl(spfi, SPFI_CONTROL);
-+ val |= SPFI_CONTROL_SPFI_EN;
-+ spfi_writel(spfi, val, SPFI_CONTROL);
-+ }
- }
-
- static inline void spfi_reset(struct img_spfi *spfi)
-@@ -130,12 +140,21 @@ static int spfi_wait_all_done(struct img
- {
- unsigned long timeout = jiffies + msecs_to_jiffies(50);
-
-+ if (!(spfi->complete))
-+ return 0;
-+
- while (time_before(jiffies, timeout)) {
- u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
-
- if (status & SPFI_INTERRUPT_ALLDONETRIG) {
- spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
- SPFI_INTERRUPT_CLEAR);
-+ /*
-+ * Disable SPFI for it not to interfere with
-+ * pending transactions
-+ */
-+ spfi_writel(spfi, spfi_readl(spfi, SPFI_CONTROL)
-+ & ~SPFI_CONTROL_SPFI_EN, SPFI_CONTROL);
- return 0;
- }
- cpu_relax();
-@@ -441,9 +460,32 @@ static void img_spfi_config(struct spi_m
- struct spi_transfer *xfer)
- {
- struct img_spfi *spfi = spi_master_get_devdata(spi->master);
-- u32 val, div;
-+ u32 val, div, transact;
-+ bool is_pending;
-
- /*
-+ * For read or write transfers of less than 8 bytes (cmd = 1 byte,
-+ * addr up to 7 bytes), SPFI will be configured, but not enabled
-+ * (unless it is the last transfer in the queue).The transfer will
-+ * be enabled by the subsequent transfer.
-+ * A pending transfer is determined by the content of the
-+ * transaction register: if command part is set and tsize
-+ * is not
-+ */
-+ transact = spfi_readl(spfi, SPFI_TRANSACTION);
-+ is_pending = ((transact >> SPFI_TRANSACTION_CMD_SHIFT) &
-+ SPFI_TRANSACTION_CMD_MASK) &&
-+ (!((transact >> SPFI_TRANSACTION_TSIZE_SHIFT) &
-+ SPFI_TRANSACTION_TSIZE_MASK));
-+
-+ /* If there are no pending transactions it's OK to soft reset */
-+ if (!is_pending) {
-+ /* Start the transaction from a known (reset) state */
-+ spfi_reset(spfi);
-+ }
-+
-+ /*
-+ * Before anything else, set up parameters.
- * output = spfi_clk * (BITCLK / 512), where BITCLK must be a
- * power of 2 up to 128
- */
-@@ -456,20 +498,52 @@ static void img_spfi_config(struct spi_m
- val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT;
- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select));
-
-- spfi_writel(spfi, xfer->len << SPFI_TRANSACTION_TSIZE_SHIFT,
-- SPFI_TRANSACTION);
-+ if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) &&
-+ /*
-+ * For duplex mode (both the tx and rx buffers are !NULL) the
-+ * CMD, ADDR, and DUMMY byte parts of the transaction register
-+ * should always be 0 and therefore the pending transfer
-+ * technique cannot be used.
-+ */
-+ (xfer->tx_buf) && (!xfer->rx_buf) &&
-+ (xfer->len <= SPFI_DATA_REQUEST_MAX_SIZE) && !is_pending) {
-+ transact = (1 & SPFI_TRANSACTION_CMD_MASK) <<
-+ SPFI_TRANSACTION_CMD_SHIFT;
-+ transact |= ((xfer->len - 1) & SPFI_TRANSACTION_ADDR_MASK) <<
-+ SPFI_TRANSACTION_ADDR_SHIFT;
-+ spfi->complete = false;
-+ } else {
-+ spfi->complete = true;
-+ if (is_pending) {
-+ /* Keep setup from pending transfer */
-+ transact |= ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
-+ SPFI_TRANSACTION_TSIZE_SHIFT);
-+ } else {
-+ transact = ((xfer->len & SPFI_TRANSACTION_TSIZE_MASK) <<
-+ SPFI_TRANSACTION_TSIZE_SHIFT);
-+ }
-+ }
-+ spfi_writel(spfi, transact, SPFI_TRANSACTION);
-
- val = spfi_readl(spfi, SPFI_CONTROL);
- val &= ~(SPFI_CONTROL_SEND_DMA | SPFI_CONTROL_GET_DMA);
-- if (xfer->tx_buf)
-+ /*
-+ * We set up send DMA for pending transfers also, as
-+ * those are always send transfers
-+ */
-+ if ((xfer->tx_buf) || is_pending)
- val |= SPFI_CONTROL_SEND_DMA;
-- if (xfer->rx_buf)
-+ if (xfer->tx_buf)
-+ val |= SPFI_CONTROL_TX_RX;
-+ if (xfer->rx_buf) {
- val |= SPFI_CONTROL_GET_DMA;
-+ val &= ~SPFI_CONTROL_TX_RX;
-+ }
- val &= ~(SPFI_CONTROL_TMODE_MASK << SPFI_CONTROL_TMODE_SHIFT);
-- if (xfer->tx_nbits == SPI_NBITS_DUAL &&
-+ if (xfer->tx_nbits == SPI_NBITS_DUAL ||
- xfer->rx_nbits == SPI_NBITS_DUAL)
- val |= SPFI_CONTROL_TMODE_DUAL << SPFI_CONTROL_TMODE_SHIFT;
-- else if (xfer->tx_nbits == SPI_NBITS_QUAD &&
-+ else if (xfer->tx_nbits == SPI_NBITS_QUAD ||
- xfer->rx_nbits == SPI_NBITS_QUAD)
- val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT;
- val |= SPFI_CONTROL_SE;