From ade3f7f883723cca5e1c967e574680b410226566 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:26 +0100 Subject: [PATCH 01/11] spi: dt-bindings: cdns,qspi-nor: Drop label in example The label is useless here. Plus, if there are several examples with the same label, we'll get very useless yet annoying warnings. Acked-by: Rob Herring (Arm) Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-1-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml index 53a52fb8b819..0d47bd94d67e 100644 --- a/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml +++ b/Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml @@ -172,7 +172,7 @@ unevaluatedProperties: false examples: - | - qspi: spi@ff705000 { + spi@ff705000 { compatible = "intel,socfpga-qspi", "cdns,qspi-nor"; #address-cells = <1>; #size-cells = <0>; From 9dfc9c1c830717686908e2c16867d8dfae5cf5e7 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:28 +0100 Subject: [PATCH 02/11] spi: cadence-qspi: Align definitions Fix alignment on the #defines. Reviewed-by: Pratyush Yadav Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-3-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 791015abafee..e6eb3fa5d689 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -40,7 +40,7 @@ static_assert(CQSPI_MAX_CHIPSELECT <= SPI_DEVICE_CS_CNT_MAX); #define CQSPI_DISABLE_DAC_MODE BIT(1) #define CQSPI_SUPPORT_EXTERNAL_DMA BIT(2) #define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3) -#define CQSPI_SLOW_SRAM BIT(4) +#define CQSPI_SLOW_SRAM BIT(4) #define CQSPI_NEEDS_APB_AHB_HAZARD_WAR BIT(5) #define CQSPI_RD_NO_IRQ BIT(6) #define CQSPI_DMA_SET_MASK BIT(7) From aac733a9663682387013350b4470a81344960f5d Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:29 +0100 Subject: [PATCH 03/11] spi: cadence-qspi: Fix style and improve readability It took me several seconds to correctly understand this block. I understand the goal: showing that we are in the if, or in one of the two other cases. Improve the organization of the code to both improve readability and fix the style. Suggested-by: Pratyush Yadav Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-4-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index e6eb3fa5d689..75010f35da41 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -374,17 +374,12 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev) /* Clear interrupt */ writel(irq_status, cqspi->iobase + CQSPI_REG_IRQSTATUS); - if (cqspi->use_dma_read && ddata && ddata->get_dma_status) { - if (ddata->get_dma_status(cqspi)) { - complete(&cqspi->transfer_complete); - return IRQ_HANDLED; - } - } - - else if (!cqspi->slow_sram) - irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR; - else + if (cqspi->use_dma_read && ddata && ddata->get_dma_status) + irq_status = ddata->get_dma_status(cqspi); + else if (cqspi->slow_sram) irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR; + else + irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR; if (irq_status) complete(&cqspi->transfer_complete); From ec2da8bb0bc518ca5458d36de9aeec493ed5a790 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:30 +0100 Subject: [PATCH 04/11] spi: cadence-qspi: Fix ORing style and alignments These definitions do not follow the standard patterns. Alignments are incoherent and the logical OR symbols '|' are misplaced. Reorganize these definitions. There is no functional change. Acked-by: Pratyush Yadav Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-5-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 75010f35da41..c94f827afe2f 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -2129,26 +2129,23 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = { }; static const struct cqspi_driver_platdata socfpga_qspi = { - .quirks = CQSPI_DISABLE_DAC_MODE - | CQSPI_NO_SUPPORT_WR_COMPLETION - | CQSPI_SLOW_SRAM - | CQSPI_DISABLE_STIG_MODE - | CQSPI_DISABLE_RUNTIME_PM, + .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION | + CQSPI_SLOW_SRAM | CQSPI_DISABLE_STIG_MODE | + CQSPI_DISABLE_RUNTIME_PM, }; static const struct cqspi_driver_platdata versal_ospi = { .hwcaps_mask = CQSPI_SUPPORTS_OCTAL, - .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA - | CQSPI_DMA_SET_MASK, + .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA | + CQSPI_DMA_SET_MASK, .indirect_read_dma = cqspi_versal_indirect_read_dma, .get_dma_status = cqspi_get_versal_dma_status, }; static const struct cqspi_driver_platdata versal2_ospi = { .hwcaps_mask = CQSPI_SUPPORTS_OCTAL, - .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA - | CQSPI_DMA_SET_MASK - | CQSPI_SUPPORT_DEVICE_RESET, + .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA | + CQSPI_DMA_SET_MASK | CQSPI_SUPPORT_DEVICE_RESET, .indirect_read_dma = cqspi_versal_indirect_read_dma, .get_dma_status = cqspi_get_versal_dma_status, }; @@ -2165,7 +2162,7 @@ static const struct cqspi_driver_platdata pensando_cdns_qspi = { static const struct cqspi_driver_platdata mobileye_eyeq5_ospi = { .hwcaps_mask = CQSPI_SUPPORTS_OCTAL, .quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION | - CQSPI_RD_NO_IRQ, + CQSPI_RD_NO_IRQ, }; static const struct of_device_id cqspi_dt_ids[] = { From 453c5d60d896398c32854b683aff6d5b8386fa03 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:31 +0100 Subject: [PATCH 05/11] spi: cadence-qspi: Remove an useless operation Right above writing the register value back based on 'div' value, there is the following check: if (div > CQSPI_REG_CONFIG_BAUD_MASK) div = CQSPI_REG_CONFIG_BAUD_MASK; which means div does not need to be AND'ed against the bitfield mask. Remove this redundant operation. Reviewed-by: Pratyush Yadav Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-6-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index c94f827afe2f..a8437d9c37a7 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1258,7 +1258,7 @@ static void cqspi_config_baudrate_div(struct cqspi_st *cqspi) reg = readl(reg_base + CQSPI_REG_CONFIG); reg &= ~(CQSPI_REG_CONFIG_BAUD_MASK << CQSPI_REG_CONFIG_BAUD_LSB); - reg |= (div & CQSPI_REG_CONFIG_BAUD_MASK) << CQSPI_REG_CONFIG_BAUD_LSB; + reg |= div << CQSPI_REG_CONFIG_BAUD_LSB; writel(reg, reg_base + CQSPI_REG_CONFIG); } From bee085476d277e1f993cdec57e3c730f536594f0 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:32 +0100 Subject: [PATCH 06/11] spi: cadence-qspi: Make sure we filter out unsupported ops The Cadence driver does not support anything else than repeating the command opcode twice while in octal DTR mode. Make this clear by checking for this in the ->supports_op() hook. Reviewed-by: Pratyush Yadav Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-7-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index a8437d9c37a7..38518475858d 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1531,6 +1531,10 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem, return false; if (op->data.nbytes && op->data.buswidth != 8) return false; + + /* A single opcode is supported, it will be repeated */ + if ((op->cmd.opcode >> 8) != (op->cmd.opcode & 0xFF)) + return false; } else if (!all_false) { /* Mixed DTR modes are not supported. */ return false; From f18c8cfa4f1af2cf7d68d86989a7d6109acfa1bb Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:33 +0100 Subject: [PATCH 07/11] spi: cadence-qspi: Fix probe error path and remove The probe has been modified by many different users, it is hard to track history, but for sure its current state is partially broken. One easy rule to follow is to drop/free/release the resources in the opposite order they have been queried. Fix the labels, the order for freeing the resources, and add the missing DMA channel step. Replicate these changes in the remove path as well. Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-8-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 44 ++++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 38518475858d..9c2b2b8649de 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1889,7 +1889,7 @@ static int cqspi_probe(struct platform_device *pdev) ret = clk_prepare_enable(cqspi->clk); if (ret) { dev_err(dev, "Cannot enable QSPI clock.\n"); - goto probe_clk_failed; + goto disable_rpm; } /* Obtain QSPI reset control */ @@ -1897,14 +1897,14 @@ static int cqspi_probe(struct platform_device *pdev) if (IS_ERR(rstc)) { ret = PTR_ERR(rstc); dev_err(dev, "Cannot get QSPI reset.\n"); - goto probe_reset_failed; + goto disable_clk; } rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp"); if (IS_ERR(rstc_ocp)) { ret = PTR_ERR(rstc_ocp); dev_err(dev, "Cannot get QSPI OCP reset.\n"); - goto probe_reset_failed; + goto disable_clk; } if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) { @@ -1912,7 +1912,7 @@ static int cqspi_probe(struct platform_device *pdev) if (IS_ERR(rstc_ref)) { ret = PTR_ERR(rstc_ref); dev_err(dev, "Cannot get QSPI REF reset.\n"); - goto probe_reset_failed; + goto disable_clk; } reset_control_assert(rstc_ref); reset_control_deassert(rstc_ref); @@ -1954,7 +1954,7 @@ static int cqspi_probe(struct platform_device *pdev) if (ddata->jh7110_clk_init) { ret = cqspi_jh7110_clk_init(pdev, cqspi); if (ret) - goto probe_reset_failed; + goto disable_clk; } if (ddata->quirks & CQSPI_DISABLE_STIG_MODE) cqspi->disable_stig_mode = true; @@ -1962,7 +1962,7 @@ static int cqspi_probe(struct platform_device *pdev) if (ddata->quirks & CQSPI_DMA_SET_MASK) { ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)); if (ret) - goto probe_reset_failed; + goto disable_clks; } } @@ -1973,7 +1973,7 @@ static int cqspi_probe(struct platform_device *pdev) pdev->name, cqspi); if (ret) { dev_err(dev, "Cannot request IRQ.\n"); - goto probe_reset_failed; + goto disable_clks; } cqspi_wait_idle(cqspi); @@ -2000,31 +2000,36 @@ static int cqspi_probe(struct platform_device *pdev) ret = cqspi_request_mmap_dma(cqspi); if (ret == -EPROBE_DEFER) { dev_err_probe(&pdev->dev, ret, "Failed to request mmap DMA\n"); - goto probe_setup_failed; + goto disable_controller; } } ret = spi_register_controller(host); if (ret) { dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret); - goto probe_setup_failed; + goto release_dma_chan; } if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) pm_runtime_put_autosuspend(dev); return 0; -probe_setup_failed: - if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) - pm_runtime_disable(dev); + +release_dma_chan: + if (cqspi->rx_chan) + dma_release_channel(cqspi->rx_chan); +disable_controller: cqspi_controller_enable(cqspi, 0); -probe_reset_failed: +disable_clks: if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); - +disable_clk: if (pm_runtime_get_sync(&pdev->dev) >= 0) clk_disable_unprepare(cqspi->clk); -probe_clk_failed: +disable_rpm: + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) + pm_runtime_disable(dev); + return ret; } @@ -2042,18 +2047,19 @@ static void cqspi_remove(struct platform_device *pdev) cqspi_wait_idle(cqspi); spi_unregister_controller(cqspi->host); - cqspi_controller_enable(cqspi, 0); if (cqspi->rx_chan) dma_release_channel(cqspi->rx_chan); - if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) - if (pm_runtime_get_sync(&pdev->dev) >= 0) - clk_disable(cqspi->clk); + cqspi_controller_enable(cqspi, 0); if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) + if (pm_runtime_get_sync(&pdev->dev) >= 0) + clk_disable(cqspi->clk); + if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); From 612227b392eed94a3398dc03334a84a699a82276 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:34 +0100 Subject: [PATCH 08/11] spi: cadence-qspi: Try hard to disable the clocks In the remove path, we should try hard to perform all steps as we simply cannot fail. The "no runtime PM" quirk must only alter the state of the RPM core, but the clocks should still be disabled if that is possible. Move the disable call outside of the RPM quirk. Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-9-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 9c2b2b8649de..075505f0abcf 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -2038,6 +2038,7 @@ static void cqspi_remove(struct platform_device *pdev) const struct cqspi_driver_platdata *ddata; struct cqspi_st *cqspi = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; + int ret = 0; ddata = of_device_get_match_data(dev); @@ -2057,8 +2058,10 @@ static void cqspi_remove(struct platform_device *pdev) cqspi_jh7110_disable_clk(pdev, cqspi); if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) - if (pm_runtime_get_sync(&pdev->dev) >= 0) - clk_disable(cqspi->clk); + ret = pm_runtime_get_sync(&pdev->dev); + + if (ret >= 0) + clk_disable(cqspi->clk); if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) { pm_runtime_put_sync(&pdev->dev); From ae62e7cf6ab52cebc83feb0bcb374082eaabbf5e Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:36 +0100 Subject: [PATCH 09/11] spi: cadence-qspi: Add a flag for controllers without indirect access support Renesas RZ/N1 QSPI controllers embed the Cadence IP with some limitations/simplifications. One of the is that only direct access is supported, none of the registers related to indirect writes are populated, so create a flag to avoid these accesses and make sure only direct accessors are called. Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-11-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 075505f0abcf..5df7e6f1bdea 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -47,6 +47,7 @@ static_assert(CQSPI_MAX_CHIPSELECT <= SPI_DEVICE_CS_CNT_MAX); #define CQSPI_SUPPORT_DEVICE_RESET BIT(8) #define CQSPI_DISABLE_STIG_MODE BIT(9) #define CQSPI_DISABLE_RUNTIME_PM BIT(10) +#define CQSPI_NO_INDIRECT_MODE BIT(11) /* Capabilities */ #define CQSPI_SUPPORTS_OCTAL BIT(0) @@ -1425,7 +1426,8 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata, if (ret) return ret; - if (cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size)) + if ((cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size)) || + (cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)) return cqspi_direct_read_execute(f_pdata, buf, from, len); if (cqspi->use_dma_read && ddata && ddata->indirect_read_dma && @@ -1626,19 +1628,20 @@ static void cqspi_controller_init(struct cqspi_st *cqspi) /* Disable all interrupts. */ writel(0, cqspi->iobase + CQSPI_REG_IRQMASK); - /* Configure the SRAM split to 1:1 . */ - writel(cqspi->fifo_depth / 2, cqspi->iobase + CQSPI_REG_SRAMPARTITION); + if (!(cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)) { + /* Configure the SRAM split to 1:1 . */ + writel(cqspi->fifo_depth / 2, cqspi->iobase + CQSPI_REG_SRAMPARTITION); + /* Load indirect trigger address. */ + writel(cqspi->trigger_address, + cqspi->iobase + CQSPI_REG_INDIRECTTRIGGER); - /* Load indirect trigger address. */ - writel(cqspi->trigger_address, - cqspi->iobase + CQSPI_REG_INDIRECTTRIGGER); - - /* Program read watermark -- 1/2 of the FIFO. */ - writel(cqspi->fifo_depth * cqspi->fifo_width / 2, - cqspi->iobase + CQSPI_REG_INDIRECTRDWATERMARK); - /* Program write watermark -- 1/8 of the FIFO. */ - writel(cqspi->fifo_depth * cqspi->fifo_width / 8, - cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK); + /* Program read watermark -- 1/2 of the FIFO. */ + writel(cqspi->fifo_depth * cqspi->fifo_width / 2, + cqspi->iobase + CQSPI_REG_INDIRECTRDWATERMARK); + /* Program write watermark -- 1/8 of the FIFO. */ + writel(cqspi->fifo_depth * cqspi->fifo_width / 8, + cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK); + } /* Disable direct access controller */ if (!cqspi->use_direct_mode) { From 590f2430733f1302a78ac405370b8f01038adbf5 Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:37 +0100 Subject: [PATCH 10/11] spi: cadence-qspi: Make sure write protection is disabled Renesas RZ/N1 QSPI controllers embed the Cadence IP with some modifications. For instance, they feature a write protection of the direct mapping at the controller level, with this feature all data writes to the AHB region are aborted. Despite the fact that the flag setting write protection is disabled by default, Bootloaders may (and actually do) set it, so mark this feature as being available with a specific flag to, if applicable, make sure it is disabled. Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-12-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 5df7e6f1bdea..8e6b4e21b2cf 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -48,6 +48,7 @@ static_assert(CQSPI_MAX_CHIPSELECT <= SPI_DEVICE_CS_CNT_MAX); #define CQSPI_DISABLE_STIG_MODE BIT(9) #define CQSPI_DISABLE_RUNTIME_PM BIT(10) #define CQSPI_NO_INDIRECT_MODE BIT(11) +#define CQSPI_HAS_WR_PROTECT BIT(12) /* Capabilities */ #define CQSPI_SUPPORTS_OCTAL BIT(0) @@ -220,6 +221,8 @@ struct cqspi_driver_platdata { #define CQSPI_REG_IRQSTATUS 0x40 #define CQSPI_REG_IRQMASK 0x44 +#define CQSPI_REG_WR_PROT_CTRL 0x58 + #define CQSPI_REG_INDIRECTRD 0x60 #define CQSPI_REG_INDIRECTRD_START_MASK BIT(0) #define CQSPI_REG_INDIRECTRD_CANCEL_MASK BIT(1) @@ -1643,6 +1646,10 @@ static void cqspi_controller_init(struct cqspi_st *cqspi) cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK); } + /* Disable write protection at controller level */ + if (cqspi->ddata && cqspi->ddata->quirks & CQSPI_HAS_WR_PROTECT) + writel(0, cqspi->iobase + CQSPI_REG_WR_PROT_CTRL); + /* Disable direct access controller */ if (!cqspi->use_direct_mode) { reg = readl(cqspi->iobase + CQSPI_REG_CONFIG); From 77ee3ba5d4152f01ba4674b0e0ae51f8a51250bf Mon Sep 17 00:00:00 2001 From: "Miquel Raynal (Schneider Electric)" Date: Thu, 22 Jan 2026 16:13:38 +0100 Subject: [PATCH 11/11] spi: cadence-qspi: Use a default value for cdns,fifo-width Bindings expect 4 to be the default value for cdns,fifo-width. Said otherwise, if the property (which is not mandatory) is not provided, the OS, in order to comply with the bindings, should not error out and take 4 as default value. Comply with the bindings. This would have slighlty simplyfied my testing if it had been implemented correctly in the first place, but in practice it should have no impact on the existing boards using this controller, as they all set cdns,fifo-width to 4 explicitly in their upstream DTS. Tested-by: Wolfram Sang Signed-off-by: Miquel Raynal (Schneider Electric) Tested-by: Santhosh Kumar K Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-13-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown --- drivers/spi/spi-cadence-quadspi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 8e6b4e21b2cf..2d287950d44c 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1598,10 +1598,8 @@ static int cqspi_of_get_pdata(struct cqspi_st *cqspi) cqspi->fifo_depth = 0; } - if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width)) { - dev_err(dev, "couldn't determine fifo-width\n"); - return -ENXIO; - } + if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width)) + cqspi->fifo_width = 4; if (of_property_read_u32(np, "cdns,trigger-address", &cqspi->trigger_address)) {