diff options
Diffstat (limited to 'target/linux/pistachio/patches-5.15')
13 files changed, 867 insertions, 0 deletions
diff --git a/target/linux/pistachio/patches-5.15/101-dmaengine-img-mdc-Handle-early-status-read.patch b/target/linux/pistachio/patches-5.15/101-dmaengine-img-mdc-Handle-early-status-read.patch new file mode 100644 index 0000000000..031a4e3e5e --- /dev/null +++ b/target/linux/pistachio/patches-5.15/101-dmaengine-img-mdc-Handle-early-status-read.patch @@ -0,0 +1,68 @@ +From a2dd154377c9aa6ddda00d39b8c7c334e4fa16ff Mon Sep 17 00:00:00 2001 +From: Damien Horsley <damien.horsley@imgtec.com> +Date: Tue, 22 Mar 2016 12:46:09 +0000 +Subject: dmaengine: img-mdc: Handle early status read + +It is possible that mdc_tx_status may be called before the first +node has been read from memory. + +In this case, the residue value stored in the register is undefined. +Return the transfer size instead. + +Signed-off-by: Damien Horsley <damien.horsley@imgtec.com> +--- + drivers/dma/img-mdc-dma.c | 40 ++++++++++++++++++++++++---------------- + 1 file changed, 24 insertions(+), 16 deletions(-) + +--- a/drivers/dma/img-mdc-dma.c ++++ b/drivers/dma/img-mdc-dma.c +@@ -618,25 +618,33 @@ static enum dma_status mdc_tx_status(str + (MDC_CMDS_PROCESSED_CMDS_DONE_MASK + 1); + + /* +- * If the command loaded event hasn't been processed yet, then +- * the difference above includes an extra command. ++ * If the first node has not yet been read from memory, ++ * the residue register value is undefined + */ +- if (!mdesc->cmd_loaded) +- cmds--; +- else +- cmds += mdesc->list_cmds_done; +- +- bytes = mdesc->list_xfer_size; +- ldesc = mdesc->list; +- for (i = 0; i < cmds; i++) { +- bytes -= ldesc->xfer_size + 1; +- ldesc = ldesc->next_desc; +- } +- if (ldesc) { +- if (residue != MDC_TRANSFER_SIZE_MASK) +- bytes -= ldesc->xfer_size - residue; ++ if (!mdesc->cmd_loaded && !cmds) { ++ bytes = mdesc->list_xfer_size; ++ } else { ++ /* ++ * If the command loaded event hasn't been processed yet, then ++ * the difference above includes an extra command. ++ */ ++ if (!mdesc->cmd_loaded) ++ cmds--; + else ++ cmds += mdesc->list_cmds_done; ++ ++ bytes = mdesc->list_xfer_size; ++ ldesc = mdesc->list; ++ for (i = 0; i < cmds; i++) { + bytes -= ldesc->xfer_size + 1; ++ ldesc = ldesc->next_desc; ++ } ++ if (ldesc) { ++ if (residue != MDC_TRANSFER_SIZE_MASK) ++ bytes -= ldesc->xfer_size - residue; ++ else ++ bytes -= ldesc->xfer_size + 1; ++ } + } + } + spin_unlock_irqrestore(&mchan->vc.lock, flags); diff --git a/target/linux/pistachio/patches-5.15/102-spi-img-spfi-Implement-dual-and-quad-mode.patch b/target/linux/pistachio/patches-5.15/102-spi-img-spfi-Implement-dual-and-quad-mode.patch new file mode 100644 index 0000000000..83f21a5c0a --- /dev/null +++ b/target/linux/pistachio/patches-5.15/102-spi-img-spfi-Implement-dual-and-quad-mode.patch @@ -0,0 +1,198 @@ +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; diff --git a/target/linux/pistachio/patches-5.15/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch b/target/linux/pistachio/patches-5.15/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch new file mode 100644 index 0000000000..2995b7dd88 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/104-spi-img-spfi-use-device-0-configuration-for-all-devi.patch @@ -0,0 +1,64 @@ +From 905ee06a9966113fe51d6bad1819759cb30fd0bd Mon Sep 17 00:00:00 2001 +From: Ionela Voinescu <ionela.voinescu@imgtec.com> +Date: Tue, 9 Feb 2016 10:18:31 +0000 +Subject: spi: img-spfi: use device 0 configuration for all devices + +Given that we control the chip select line externally +we can use only one parameter register (device 0 parameter +register) and one set of configuration bits (port configuration +bits for device 0) for all devices (all chip select lines). + +Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com> +--- + drivers/spi/spi-img-spfi.c | 23 ++++++++++++++++------- + 1 file changed, 16 insertions(+), 7 deletions(-) + +--- a/drivers/spi/spi-img-spfi.c ++++ b/drivers/spi/spi-img-spfi.c +@@ -429,18 +429,23 @@ static int img_spfi_prepare(struct spi_m + struct img_spfi *spfi = spi_master_get_devdata(master); + u32 val; + ++ /* ++ * The chip select line is controlled externally so ++ * we can use the CS0 configuration for all devices ++ */ + val = spfi_readl(spfi, SPFI_PORT_STATE); ++ ++ /* 0 for device selection */ + val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << + SPFI_PORT_STATE_DEV_SEL_SHIFT); +- val |= msg->spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT; + if (msg->spi->mode & SPI_CPHA) +- val |= SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); ++ val |= SPFI_PORT_STATE_CK_PHASE(0); + else +- val &= ~SPFI_PORT_STATE_CK_PHASE(msg->spi->chip_select); ++ val &= ~SPFI_PORT_STATE_CK_PHASE(0); + if (msg->spi->mode & SPI_CPOL) +- val |= SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); ++ val |= SPFI_PORT_STATE_CK_POL(0); + else +- val &= ~SPFI_PORT_STATE_CK_POL(msg->spi->chip_select); ++ val &= ~SPFI_PORT_STATE_CK_POL(0); + spfi_writel(spfi, val, SPFI_PORT_STATE); + + return 0; +@@ -492,11 +497,15 @@ static void img_spfi_config(struct spi_m + div = DIV_ROUND_UP(clk_get_rate(spfi->spfi_clk), xfer->speed_hz); + div = clamp(512 / (1 << get_count_order(div)), 1, 128); + +- val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(spi->chip_select)); ++ /* ++ * The chip select line is controlled externally so ++ * we can use the CS0 parameters for all devices ++ */ ++ val = spfi_readl(spfi, SPFI_DEVICE_PARAMETER(0)); + val &= ~(SPFI_DEVICE_PARAMETER_BITCLK_MASK << + SPFI_DEVICE_PARAMETER_BITCLK_SHIFT); + val |= div << SPFI_DEVICE_PARAMETER_BITCLK_SHIFT; +- spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(spi->chip_select)); ++ spfi_writel(spfi, val, SPFI_DEVICE_PARAMETER(0)); + + if (!list_is_last(&xfer->transfer_list, &master->cur_msg->transfers) && + /* diff --git a/target/linux/pistachio/patches-5.15/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch b/target/linux/pistachio/patches-5.15/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch new file mode 100644 index 0000000000..5418503816 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/105-spi-img-spfi-RX-maximum-burst-size-for-DMA-is-8.patch @@ -0,0 +1,59 @@ +From 56466f505f58f44b69feb7eaed3b506842800456 Mon Sep 17 00:00:00 2001 +From: Ionela Voinescu <ionela.voinescu@imgtec.com> +Date: Tue, 1 Mar 2016 17:49:45 +0000 +Subject: spi: img-spfi: RX maximum burst size for DMA is 8 + +The depth of the FIFOs is 16 bytes. The DMA request line is tied +to the half full/empty (depending on the use of the TX or RX FIFO) +threshold. For the TX FIFO, if you set a burst size of 8 (equal to +half the depth) the first burst goes into FIFO without any issues, +but due the latency involved (the time the data leaves the DMA +engine to the time it arrives at the FIFO), the DMA might trigger +another burst of 8. But given that there is no space for 2 additonal +bursts of 8, this would result in a failure. Therefore, we have to +keep the burst size for TX to 4 to accomodate for an extra burst. + +For the read (RX) scenario, the DMA request line goes high when +there is at least 8 entries in the FIFO (half full), and we can +program the burst size to be 8 because the risk of accidental burst +does not exist. The DMA engine will not trigger another read until +the read data for all the burst it has sent out has been received. + +While here, move the burst size setting outside of the if/else branches +as they have the same value for both 8 and 32 bit data widths. + +Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com> +--- + drivers/spi/spi-img-spfi.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/spi/spi-img-spfi.c ++++ b/drivers/spi/spi-img-spfi.c +@@ -338,12 +338,11 @@ static int img_spfi_start_dma(struct spi + if (xfer->len % 4 == 0) { + rxconf.src_addr = spfi->phys + SPFI_RX_32BIT_VALID_DATA; + rxconf.src_addr_width = 4; +- rxconf.src_maxburst = 4; + } else { + rxconf.src_addr = spfi->phys + SPFI_RX_8BIT_VALID_DATA; + rxconf.src_addr_width = 1; +- rxconf.src_maxburst = 4; + } ++ rxconf.src_maxburst = 8; + dmaengine_slave_config(spfi->rx_ch, &rxconf); + + rxdesc = dmaengine_prep_slave_sg(spfi->rx_ch, xfer->rx_sg.sgl, +@@ -362,12 +361,11 @@ static int img_spfi_start_dma(struct spi + if (xfer->len % 4 == 0) { + txconf.dst_addr = spfi->phys + SPFI_TX_32BIT_VALID_DATA; + txconf.dst_addr_width = 4; +- txconf.dst_maxburst = 4; + } else { + txconf.dst_addr = spfi->phys + SPFI_TX_8BIT_VALID_DATA; + txconf.dst_addr_width = 1; +- txconf.dst_maxburst = 4; + } ++ txconf.dst_maxburst = 4; + dmaengine_slave_config(spfi->tx_ch, &txconf); + + txdesc = dmaengine_prep_slave_sg(spfi->tx_ch, xfer->tx_sg.sgl, diff --git a/target/linux/pistachio/patches-5.15/106-spi-img-spfi-finish-every-transfer-cleanly.patch b/target/linux/pistachio/patches-5.15/106-spi-img-spfi-finish-every-transfer-cleanly.patch new file mode 100644 index 0000000000..ea1f9f28cc --- /dev/null +++ b/target/linux/pistachio/patches-5.15/106-spi-img-spfi-finish-every-transfer-cleanly.patch @@ -0,0 +1,120 @@ +From 5fcca3fd4b621d7b5bdeca18d36dfc6ca6cfe383 Mon Sep 17 00:00:00 2001 +From: Ionela Voinescu <ionela.voinescu@imgtec.com> +Date: Wed, 10 Aug 2016 11:42:26 +0100 +Subject: spi: img-spfi: finish every transfer cleanly + +Before this change, the interrupt status bit that signaled +the end of a tranfers was cleared in the wait_all_done +function. That functionality triggered issues for DMA +duplex transactions where the wait function was called +twice, in both the TX and RX callbacks. + +In order to fix the issue, clear all interrupt data bits +at the end of a PIO transfer or at the end of both TX and RX +duplex transfers, if the transfer is not a pending tranfer +(command waiting for data). After that, the status register +is checked for new incoming data or new data requests to be +signaled. If SPFI finished cleanly, no new interrupt data +bits should be set. + +Signed-off-by: Ionela Voinescu <ionela.voinescu@imgtec.com> +--- + drivers/spi/spi-img-spfi.c | 49 +++++++++++++++++++++++++++++++++------------- + 1 file changed, 35 insertions(+), 14 deletions(-) + +--- a/drivers/spi/spi-img-spfi.c ++++ b/drivers/spi/spi-img-spfi.c +@@ -79,6 +79,14 @@ + #define SPFI_INTERRUPT_SDE BIT(1) + #define SPFI_INTERRUPT_SDTRIG BIT(0) + ++#define SPFI_INTERRUPT_DATA_BITS (SPFI_INTERRUPT_SDHF |\ ++ SPFI_INTERRUPT_SDFUL |\ ++ SPFI_INTERRUPT_GDEX32BIT |\ ++ SPFI_INTERRUPT_GDHF |\ ++ SPFI_INTERRUPT_GDFUL |\ ++ SPFI_INTERRUPT_ALLDONETRIG |\ ++ SPFI_INTERRUPT_GDEX8BIT) ++ + /* + * There are four parallel FIFOs of 16 bytes each. The word buffer + * (*_32BIT_VALID_DATA) accesses all four FIFOs at once, resulting in an +@@ -136,6 +144,23 @@ static inline void spfi_reset(struct img + spfi_writel(spfi, 0, SPFI_CONTROL); + } + ++static inline void spfi_finish(struct img_spfi *spfi) ++{ ++ if (!(spfi->complete)) ++ return; ++ ++ /* Clear data bits as all transfers(TX and RX) have finished */ ++ spfi_writel(spfi, SPFI_INTERRUPT_DATA_BITS, SPFI_INTERRUPT_CLEAR); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & SPFI_INTERRUPT_DATA_BITS) { ++ dev_err(spfi->dev, "SPFI did not finish transfer cleanly.\n"); ++ spfi_reset(spfi); ++ } ++ /* Disable SPFI for it not to interfere with pending transactions */ ++ spfi_writel(spfi, ++ spfi_readl(spfi, SPFI_CONTROL) & ~SPFI_CONTROL_SPFI_EN, ++ SPFI_CONTROL); ++} ++ + static int spfi_wait_all_done(struct img_spfi *spfi) + { + unsigned long timeout = jiffies + msecs_to_jiffies(50); +@@ -144,19 +169,9 @@ static int spfi_wait_all_done(struct img + 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); ++ if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & ++ SPFI_INTERRUPT_ALLDONETRIG) + return 0; +- } + cpu_relax(); + } + +@@ -288,6 +303,8 @@ static int img_spfi_start_pio(struct spi + } + + ret = spfi_wait_all_done(spfi); ++ spfi_finish(spfi); ++ + if (ret < 0) + return ret; + +@@ -303,8 +320,10 @@ static void img_spfi_dma_rx_cb(void *dat + + spin_lock_irqsave(&spfi->lock, flags); + spfi->rx_dma_busy = false; +- if (!spfi->tx_dma_busy) ++ if (!spfi->tx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } + +@@ -317,8 +336,10 @@ static void img_spfi_dma_tx_cb(void *dat + + spin_lock_irqsave(&spfi->lock, flags); + spfi->tx_dma_busy = false; +- if (!spfi->rx_dma_busy) ++ if (!spfi->rx_dma_busy) { ++ spfi_finish(spfi); + spi_finalize_current_transfer(spfi->master); ++ } + spin_unlock_irqrestore(&spfi->lock, flags); + } + diff --git a/target/linux/pistachio/patches-5.15/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch b/target/linux/pistachio/patches-5.15/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch new file mode 100644 index 0000000000..6fddbe269a --- /dev/null +++ b/target/linux/pistachio/patches-5.15/108-clk-pistachio-Fix-wrong-SDHost-card-speed.patch @@ -0,0 +1,49 @@ +From 3642843a06025ec333d7e92580cf52cb8db2a652 Mon Sep 17 00:00:00 2001 +From: Govindraj Raja <Govindraj.Raja@imgtec.com> +Date: Fri, 8 Jan 2016 16:36:07 +0000 +Subject: clk: pistachio: Fix wrong SDHost card speed + +The SDHost currently clocks the card 4x slower than it +should do, because there is fixed divide by 4 in the +sdhost wrapper that is not present in the clock tree. +To model this add a fixed divide by 4 clock node in +the SDHost clock path. + +This will ensure the right clock frequency is selected when +the mmc driver tries to configure frequency on card insert. + +Signed-off-by: Govindraj Raja <Govindraj.Raja@imgtec.com> +--- + drivers/clk/pistachio/clk-pistachio.c | 3 ++- + include/dt-bindings/clock/pistachio-clk.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/clk/pistachio/clk-pistachio.c ++++ b/drivers/clk/pistachio/clk-pistachio.c +@@ -41,7 +41,7 @@ static struct pistachio_gate pistachio_g + GATE(CLK_AUX_ADC_INTERNAL, "aux_adc_internal", "sys_internal_div", + 0x104, 22), + GATE(CLK_AUX_ADC, "aux_adc", "aux_adc_div", 0x104, 23), +- GATE(CLK_SD_HOST, "sd_host", "sd_host_div", 0x104, 24), ++ GATE(CLK_SD_HOST, "sd_host", "sd_host_div4", 0x104, 24), + GATE(CLK_BT, "bt", "bt_div", 0x104, 25), + GATE(CLK_BT_DIV4, "bt_div4", "bt_div4_div", 0x104, 26), + GATE(CLK_BT_DIV8, "bt_div8", "bt_div8_div", 0x104, 27), +@@ -51,6 +51,7 @@ static struct pistachio_gate pistachio_g + static struct pistachio_fixed_factor pistachio_ffs[] __initdata = { + FIXED_FACTOR(CLK_WIFI_DIV4, "wifi_div4", "wifi_pll", 4), + FIXED_FACTOR(CLK_WIFI_DIV8, "wifi_div8", "wifi_pll", 8), ++ FIXED_FACTOR(CLK_SDHOST_DIV4, "sd_host_div4", "sd_host_div", 4), + }; + + static struct pistachio_div pistachio_divs[] __initdata = { +--- a/include/dt-bindings/clock/pistachio-clk.h ++++ b/include/dt-bindings/clock/pistachio-clk.h +@@ -18,6 +18,7 @@ + /* Fixed-factor clocks */ + #define CLK_WIFI_DIV4 16 + #define CLK_WIFI_DIV8 17 ++#define CLK_SDHOST_DIV4 18 + + /* Gate clocks */ + #define CLK_MIPS 32 diff --git a/target/linux/pistachio/patches-5.15/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch b/target/linux/pistachio/patches-5.15/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch new file mode 100644 index 0000000000..cec424a0ce --- /dev/null +++ b/target/linux/pistachio/patches-5.15/109-MIPS-DTS-img-marduk-switch-mmc-to-1-bit-mode.patch @@ -0,0 +1,47 @@ +From 981c1d416af45eff207227aec106381ac23aac99 Mon Sep 17 00:00:00 2001 +From: Ian Pozella <Ian.Pozella@imgtec.com> +Date: Mon, 20 Feb 2017 10:00:52 +0000 +Subject: MIPS: DTS: img: marduk: switch mmc to 1 bit mode + +The mmc block in Pistachio allows 1 to 8 data bits to be used. +Marduk uses 4 bits allowing the upper 4 bits to be allocated +to the Mikrobus ports. However these bits are still connected +internally meaning the mmc block recieves signals on all data lines +and seems the internal HW CRC checks get corrupted by this erroneous +data. + +We cannot control what data is sent on these lines because they go +to external ports. 1 bit mode does not exhibit the issue hence the +safe default is to use this. If a user knows that in their use case +they will not use the upper bits then they can set to 4 bit mode in +order to improve performance. + +Also make sure that the upper 4 bits don't get allocated to the mmc +driver (the default is to assign all 8 pins) so they can be allocated +to other drivers. Allocating all 4 despite setting 1 bit mode as this +matches what is there in hardware. + +Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com> +--- + arch/mips/boot/dts/img/pistachio_marduk.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -117,7 +117,7 @@ + + &sdhost { + status = "okay"; +- bus-width = <4>; ++ bus-width = <1>; + disable-wp; + }; + +@@ -127,6 +127,7 @@ + + &pin_sdhost_data { + drive-strength = <2>; ++ pins = "mfio17", "mfio18", "mfio19", "mfio20"; + }; + + &pwm { diff --git a/target/linux/pistachio/patches-5.15/401-mtd-nor-support-mtd-name-from-device-tree.patch b/target/linux/pistachio/patches-5.15/401-mtd-nor-support-mtd-name-from-device-tree.patch new file mode 100644 index 0000000000..c6569c81ce --- /dev/null +++ b/target/linux/pistachio/patches-5.15/401-mtd-nor-support-mtd-name-from-device-tree.patch @@ -0,0 +1,54 @@ +From f32bc2aa01edcba2f2ed5db151cf183eac9ef919 Mon Sep 17 00:00:00 2001 +From: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com> +Date: Sat, 25 Feb 2017 16:42:50 +0000 +Subject: mtd: nor: support mtd name from device tree + +Signed-off-by: Abhimanyu Vishwakarma <Abhimanyu.Vishwakarma@imgtec.com> +--- + drivers/mtd/spi-nor/spi-nor.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/spi-nor/core.c ++++ b/drivers/mtd/spi-nor/core.c +@@ -3143,6 +3143,7 @@ int spi_nor_scan(struct spi_nor *nor, co + struct device *dev = nor->dev; + struct mtd_info *mtd = &nor->mtd; + struct device_node *np = spi_nor_get_flash_node(nor); ++ const char __maybe_unused *of_mtd_name = NULL; + int ret; + int i; + +@@ -3197,7 +3198,12 @@ int spi_nor_scan(struct spi_nor *nor, co + if (ret) + return ret; + +- if (!mtd->name) ++#ifdef CONFIG_MTD_OF_PARTS ++ of_property_read_string(np, "linux,mtd-name", &of_mtd_name); ++#endif ++ if (of_mtd_name) ++ mtd->name = of_mtd_name; ++ else if (!mtd->name) + mtd->name = dev_name(dev); + mtd->priv = nor; + mtd->type = MTD_NORFLASH; +--- a/drivers/mtd/mtdcore.c ++++ b/drivers/mtd/mtdcore.c +@@ -850,6 +850,17 @@ out_error: + */ + static void mtd_set_dev_defaults(struct mtd_info *mtd) + { ++#ifdef CONFIG_MTD_OF_PARTS ++ const char __maybe_unused *of_mtd_name = NULL; ++ struct device_node *np; ++ ++ np = mtd_get_of_node(mtd); ++ if (np && !mtd->name) { ++ of_property_read_string(np, "linux,mtd-name", &of_mtd_name); ++ if (of_mtd_name) ++ mtd->name = of_mtd_name; ++ } else ++#endif + if (mtd->dev.parent) { + if (!mtd->owner && mtd->dev.parent->driver) + mtd->owner = mtd->dev.parent->driver->owner; diff --git a/target/linux/pistachio/patches-5.15/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch b/target/linux/pistachio/patches-5.15/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch new file mode 100644 index 0000000000..cd97e38e00 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/901-MIPS-DTS-img-marduk-Add-SPI-NAND-flash.patch @@ -0,0 +1,30 @@ +From 0023c706f7e0f0f02bd48a63a2f3c04c839532ae Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 15 Aug 2020 16:04:53 +0200 +Subject: [PATCH 901/904] MIPS: DTS: img: marduk: Add SPI NAND flash + +Add Gigadevice GD5F4GQ4UCYIGT SPI NAND flash to the device tree. + +The NAND flash chip is connected with quad SPI, but reading currently +fails in quad SPI mode. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/boot/dts/img/pistachio_marduk.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -88,6 +88,12 @@ + reg = <0>; + spi-max-frequency = <50000000>; + }; ++ ++ flash@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <50000000>; ++ }; + }; + + &uart0 { diff --git a/target/linux/pistachio/patches-5.15/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch b/target/linux/pistachio/patches-5.15/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch new file mode 100644 index 0000000000..af1882e287 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/902-MIPS-DTS-img-marduk-Add-Cascoda-CA8210-6LoWPAN.patch @@ -0,0 +1,43 @@ +From b7700154d75e8d7c9a2022f09c2d5430137606fa Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 15 Aug 2020 16:05:25 +0200 +Subject: [PATCH 902/904] MIPS: DTS: img: marduk: Add Cascoda CA8210 6LoWPAN + +Add Cascoda CA8210 6LoWPAN controller to device tree. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/boot/dts/img/pistachio_marduk.dts | 22 +++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -75,6 +75,28 @@ + VDD-supply = <&internal_dac_supply>; + }; + ++&spfi0 { ++ status = "okay"; ++ pinctrl-0 = <&spim0_pins>, <&spim0_cs0_alt_pin>, <&spim0_cs2_alt_pin>, <&spim0_cs3_alt_pin>, <&spim0_cs4_alt_pin>; ++ pinctrl-names = "default"; ++ ++ cs-gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>, <&gpio0 2 GPIO_ACTIVE_HIGH>, ++ <&gpio1 12 GPIO_ACTIVE_HIGH>, <&gpio1 13 GPIO_ACTIVE_HIGH>; ++ ++ ca8210: ca8210@0 { ++ status = "okay"; ++ compatible = "cascoda,ca8210"; ++ reg = <0>; ++ spi-max-frequency = <4000000>; ++ spi-cpol; ++ reset-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; ++ irq-gpio = <&gpio2 12 GPIO_ACTIVE_HIGH>; ++ extclock-enable; ++ extclock-freq = <16000000>; ++ extclock-gpio = <2>; ++ }; ++}; ++ + &spfi1 { + status = "okay"; + diff --git a/target/linux/pistachio/patches-5.15/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch b/target/linux/pistachio/patches-5.15/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch new file mode 100644 index 0000000000..0814658998 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/903-MIPS-DTS-img-marduk-Add-NXP-SC16IS752IPW.patch @@ -0,0 +1,81 @@ +From ad4eba0c36ce8af6ab9ea1bc163e4c1ac7c271c3 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Sat, 15 Aug 2020 16:09:02 +0200 +Subject: [PATCH 903/904] MIPS: DTS: img: marduk: Add NXP SC16IS752IPW + +Add NXP SC16IS752IPW SPI-UART controller to device tree. + +This controller drives 2 UARTs and 7 LEDs on the board. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +--- + arch/mips/boot/dts/img/pistachio_marduk.dts | 51 +++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -46,6 +46,46 @@ + regulator-max-microvolt = <1800000>; + }; + ++ /* EXT clock from ca8210 is fed to sc16is752 */ ++ ca8210_ext_clk: ca8210-ext-clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <16000000>; ++ clock-output-names = "ca8210_ext_clock"; ++ }; ++ ++ gpioleds { ++ compatible = "gpio-leds"; ++ user1 { ++ label = "marduk:red:user1"; ++ gpios = <&sc16is752 0 GPIO_ACTIVE_LOW>; ++ }; ++ user2 { ++ label = "marduk:red:user2"; ++ gpios = <&sc16is752 1 GPIO_ACTIVE_LOW>; ++ }; ++ user3 { ++ label = "marduk:red:user3"; ++ gpios = <&sc16is752 2 GPIO_ACTIVE_LOW>; ++ }; ++ user4 { ++ label = "marduk:red:user4"; ++ gpios = <&sc16is752 3 GPIO_ACTIVE_LOW>; ++ }; ++ user5 { ++ label = "marduk:red:user5"; ++ gpios = <&sc16is752 4 GPIO_ACTIVE_LOW>; ++ }; ++ user6 { ++ label = "marduk:red:user6"; ++ gpios = <&sc16is752 5 GPIO_ACTIVE_LOW>; ++ }; ++ user7 { ++ label = "marduk:red:user7"; ++ gpios = <&sc16is752 6 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ + leds { + compatible = "pwm-leds"; + heartbeat { +@@ -95,6 +135,17 @@ + extclock-freq = <16000000>; + extclock-gpio = <2>; + }; ++ ++ sc16is752: sc16is752@1 { ++ compatible = "nxp,sc16is752"; ++ reg = <1>; ++ clocks = <&ca8210_ext_clk>; ++ spi-max-frequency = <4000000>; ++ interrupt-parent = <&gpio0>; ++ interrupts = <11 IRQ_TYPE_EDGE_FALLING>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; + }; + + &spfi1 { diff --git a/target/linux/pistachio/patches-5.15/904-MIPS-DTS-img-marduk-Add-partition-name.patch b/target/linux/pistachio/patches-5.15/904-MIPS-DTS-img-marduk-Add-partition-name.patch new file mode 100644 index 0000000000..ce41c67461 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/904-MIPS-DTS-img-marduk-Add-partition-name.patch @@ -0,0 +1,27 @@ +From ff0e950b605047bf50d470023e0fb2fc2003a0f0 Mon Sep 17 00:00:00 2001 +From: Ian Pozella <Ian.Pozella@imgtec.com> +Date: Mon, 20 Feb 2017 10:38:07 +0000 +Subject: [PATCH 904/904] MIPS: DTS: img: marduk: Add partition name + +Signed-off-by: Ian Pozella <Ian.Pozella@imgtec.com> +--- + arch/mips/boot/dts/img/pistachio_marduk.dts | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -160,12 +160,14 @@ + compatible = "spansion,s25fl016k", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; ++ linux,mtd-name = "spi-nor"; + }; + + flash@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <50000000>; ++ linux,mtd-name = "spi-nand"; + }; + }; + diff --git a/target/linux/pistachio/patches-5.15/905-MIPS-DTS-img-marduk-Add-led-aliases.patch b/target/linux/pistachio/patches-5.15/905-MIPS-DTS-img-marduk-Add-led-aliases.patch new file mode 100644 index 0000000000..c6cf5acbb8 --- /dev/null +++ b/target/linux/pistachio/patches-5.15/905-MIPS-DTS-img-marduk-Add-led-aliases.patch @@ -0,0 +1,27 @@ +--- a/arch/mips/boot/dts/img/pistachio_marduk.dts ++++ b/arch/mips/boot/dts/img/pistachio_marduk.dts +@@ -19,6 +19,11 @@ + ethernet0 = &enet; + spi0 = &spfi0; + spi1 = &spfi1; ++ ++ led-boot = &led_heartbeat; ++ led-failsafe = &led_heartbeat; ++ led-running = &led_heartbeat; ++ led-upgrade = &led_heartbeat; + }; + + chosen { +@@ -88,11 +93,10 @@ + + leds { + compatible = "pwm-leds"; +- heartbeat { ++ led_heartbeat: heartbeat { + label = "marduk:red:heartbeat"; + pwms = <&pwm 3 300000>; + max-brightness = <255>; +- linux,default-trigger = "heartbeat"; + }; + }; + |