diff --git a/Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml b/Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml index e82c7f8d0b98..5d86cc87e4fb 100644 --- a/Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml +++ b/Documentation/devicetree/bindings/spi/spacemit,k1-spi.yaml @@ -24,7 +24,11 @@ allOf: properties: compatible: - const: spacemit,k1-spi + oneOf: + - const: spacemit,k1-spi + - items: + - const: spacemit,k3-spi + - const: spacemit,k1-spi reg: maxItems: 1 diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 9b4e5b7013ae..af1a05e78492 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -388,11 +388,13 @@ static inline void cdns_spi_writer(struct cdns_spi *xspi) /** * cdns_spi_process_fifo - Fills the TX FIFO, and drain the RX FIFO + * @ctlr: Pointer to the spi_controller structure * @xspi: Pointer to the cdns_spi structure * @ntx: Number of bytes to pack into the TX FIFO * @nrx: Number of bytes to drain from the RX FIFO */ -static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx) +static void cdns_spi_process_fifo(struct spi_controller *ctlr, + struct cdns_spi *xspi, int ntx, int nrx) { ntx = clamp(ntx, 0, xspi->tx_bytes); nrx = clamp(nrx, 0, xspi->rx_bytes); @@ -407,6 +409,16 @@ static void cdns_spi_process_fifo(struct cdns_spi *xspi, int ntx, int nrx) } if (ntx) { + /* When xspi in busy condition, bytes may send failed, + * then spi control didn't work thoroughly, add one byte + * delay. Only in host mode; in target mode this delay + * causes data corruption as the target fails to prepare + * data in time. + */ + if (!spi_controller_is_target(ctlr) && + (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL)) + udelay(10); + cdns_spi_writer(xspi); ntx--; } @@ -460,14 +472,14 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id) cdns_spi_write(xspi, CDNS_SPI_THLD, 1); if (xspi->tx_bytes) { - cdns_spi_process_fifo(xspi, trans_cnt, trans_cnt); + cdns_spi_process_fifo(ctlr, xspi, trans_cnt, trans_cnt); } else { /* Fixed delay due to controller limitation with * RX_NEMPTY incorrect status * Xilinx AR:65885 contains more details */ udelay(10); - cdns_spi_process_fifo(xspi, 0, trans_cnt); + cdns_spi_process_fifo(ctlr, xspi, 0, trans_cnt); cdns_spi_write(xspi, CDNS_SPI_IDR, CDNS_SPI_IXR_DEFAULT); spi_finalize_current_transfer(ctlr); @@ -520,17 +532,11 @@ static int cdns_transfer_one(struct spi_controller *ctlr, cdns_spi_write(xspi, CDNS_SPI_THLD, xspi->tx_fifo_depth >> 1); } - /* When xspi in busy condition, bytes may send failed, - * then spi control didn't work thoroughly, add one byte delay - */ - if (cdns_spi_read(xspi, CDNS_SPI_ISR) & CDNS_SPI_IXR_TXFULL) - udelay(10); - xspi->n_bytes = cdns_spi_n_bytes(transfer); xspi->tx_bytes = DIV_ROUND_UP(xspi->tx_bytes, xspi->n_bytes); xspi->rx_bytes = DIV_ROUND_UP(xspi->rx_bytes, xspi->n_bytes); - cdns_spi_process_fifo(xspi, xspi->tx_fifo_depth, 0); + cdns_spi_process_fifo(ctlr, xspi, xspi->tx_fifo_depth, 0); cdns_spi_write(xspi, CDNS_SPI_IER, CDNS_SPI_IXR_DEFAULT); return transfer->len; diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index caf55a6f70b3..e9fdefa9d65d 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -775,7 +775,8 @@ static int qcom_qspi_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "could not set DMA mask\n"); host->max_speed_hz = 300000000; - host->max_dma_len = 65536; /* as per HPG */ + /* as per HPG, it is 64KB, limit to 60KB to avoid boundary condition failures */ + host->max_dma_len = 0xf000; host->dma_alignment = QSPI_ALIGN_REQ; host->num_chipselect = QSPI_NUM_CS; host->bus_num = -1; diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index 19812400124f..1e2fc875cd66 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c @@ -1376,6 +1376,22 @@ static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, snandc->regs->addr0 = cpu_to_le32(op->addr.val); snandc->regs->addr1 = cpu_to_le32(0); + /* + * The feature value has to reach NAND_FLASH_FEATURES before the + * command is executed, otherwise the controller programs the chip + * with whatever the register happened to hold from a previous + * operation. + */ + if (opcode == SPINAND_SET_FEATURE) { + u32 ftr = 0; + + memcpy(&ftr, op->data.buf.out, + min_t(size_t, op->data.nbytes, sizeof(ftr))); + snandc->regs->flash_feature = cpu_to_le32(ftr); + qcom_write_reg_dma(snandc, &snandc->regs->flash_feature, + NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL); + } + qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL); qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -1413,10 +1429,8 @@ static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const struct spi_ copy_ftr = true; break; case SPINAND_SET_FEATURE: - snandc->regs->flash_feature = cpu_to_le32(*(u32 *)op->data.buf.out); - qcom_write_reg_dma(snandc, &snandc->regs->flash_feature, - NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL); - break; + /* fully handled by qcom_spi_send_cmdaddr() */ + return 0; case SPINAND_PROGRAM_EXECUTE: case SPINAND_WRITE_EN: case SPINAND_RESET: diff --git a/drivers/spi/spi-spacemit-k1.c b/drivers/spi/spi-spacemit-k1.c index 4348d77ec77c..d03a93d149ec 100644 --- a/drivers/spi/spi-spacemit-k1.c +++ b/drivers/spi/spi-spacemit-k1.c @@ -278,27 +278,27 @@ static int k1_spi_dma_one(struct spi_controller *host, struct spi_device *spi, struct spi_transfer *transfer) { struct k1_spi_driver_data *drv_data = spi_controller_get_devdata(host); - struct dma_async_tx_descriptor *desc; + struct dma_async_tx_descriptor *txdesc, *rxdesc; u32 val; - /* Prepare the TX descriptor and submit it */ - desc = k1_spi_dma_prep(drv_data, transfer, true); - if (!desc) + /* Prepare the TX descriptor */ + txdesc = k1_spi_dma_prep(drv_data, transfer, true); + if (!txdesc) goto fallback; - dmaengine_submit(desc); /* Prepare the RX descriptor and submit it */ - desc = k1_spi_dma_prep(drv_data, transfer, false); - if (!desc) { + rxdesc = k1_spi_dma_prep(drv_data, transfer, false); + if (!rxdesc) { dmaengine_terminate_sync(host->dma_tx); goto fallback; } /* When RX is complete we also know TX has completed */ - desc->callback = k1_spi_dma_callback; - desc->callback_param = drv_data; + rxdesc->callback = k1_spi_dma_callback; + rxdesc->callback_param = drv_data; - dmaengine_submit(desc); + dmaengine_submit(txdesc); + dmaengine_submit(rxdesc); val = readl(drv_data->base + SSP_TOP_CTRL); val |= TOP_TRAIL; /* Trailing bytes handled by DMA */ @@ -496,8 +496,8 @@ static bool k1_spi_write(struct k1_spi_driver_data *drv_data, u32 val) { unsigned int count; - /* Get the number of open slots in the FIFO; zero means all */ - count = FIELD_GET(SSP_STATUS_TFL, val) ? : K1_SPI_FIFO_SIZE; + /* Get the number of free slots in the FIFO */ + count = K1_SPI_FIFO_SIZE - FIELD_GET(SSP_STATUS_TFL, val); /* * Limit how much we try to send at a time, to reduce the