Skip to content

Commit 65ce115

Browse files
committed
spi: cadence-qspi: Add Renesas RZ/N1 support
Merge series from "Miquel Raynal (Schneider Electric)" <miquel.raynal@bootlin.com>: This series adds support for the QSPI controller available on Renesas RZ/N1S and RZ/N1D SoC. It has been tested with a custom board (see last SPI patch for details), but has been tested by Wolfram (thank you!) on the DB board. Link: https://lore.kernel.org/linux-devicetree/20260116114852.52948-2-wsa+renesas@sang-engineering.com/ Adding support for this SoC required a few adaptations in the Cadence QSPI driver. The bulk of the work is in the few last patches. Everything else is just misc style fixes and improvements which bothered me while I was wandering. In order to support all constraints, I sometimes used a new quirk (for the write protection feature and the "no indirect mode"), and sometimes used the compatible directly. The ones I thought might not be RZ/N1 specific have been implemented under the form of a quirk, in order to ease their reuse. The other adaptations, which I believe are more Renesas specific, have been handled using the compatible. This is all very arbitrary, and can be discussed.
2 parents 7ae4d09 + 77ee3ba commit 65ce115

2 files changed

Lines changed: 72 additions & 59 deletions

File tree

Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ unevaluatedProperties: false
172172

173173
examples:
174174
- |
175-
qspi: spi@ff705000 {
175+
spi@ff705000 {
176176
compatible = "intel,socfpga-qspi", "cdns,qspi-nor";
177177
#address-cells = <1>;
178178
#size-cells = <0>;

drivers/spi/spi-cadence-quadspi.c

Lines changed: 71 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ static_assert(CQSPI_MAX_CHIPSELECT <= SPI_DEVICE_CS_CNT_MAX);
4040
#define CQSPI_DISABLE_DAC_MODE BIT(1)
4141
#define CQSPI_SUPPORT_EXTERNAL_DMA BIT(2)
4242
#define CQSPI_NO_SUPPORT_WR_COMPLETION BIT(3)
43-
#define CQSPI_SLOW_SRAM BIT(4)
43+
#define CQSPI_SLOW_SRAM BIT(4)
4444
#define CQSPI_NEEDS_APB_AHB_HAZARD_WAR BIT(5)
4545
#define CQSPI_RD_NO_IRQ BIT(6)
4646
#define CQSPI_DMA_SET_MASK BIT(7)
4747
#define CQSPI_SUPPORT_DEVICE_RESET BIT(8)
4848
#define CQSPI_DISABLE_STIG_MODE BIT(9)
4949
#define CQSPI_DISABLE_RUNTIME_PM BIT(10)
50+
#define CQSPI_NO_INDIRECT_MODE BIT(11)
51+
#define CQSPI_HAS_WR_PROTECT BIT(12)
5052

5153
/* Capabilities */
5254
#define CQSPI_SUPPORTS_OCTAL BIT(0)
@@ -219,6 +221,8 @@ struct cqspi_driver_platdata {
219221
#define CQSPI_REG_IRQSTATUS 0x40
220222
#define CQSPI_REG_IRQMASK 0x44
221223

224+
#define CQSPI_REG_WR_PROT_CTRL 0x58
225+
222226
#define CQSPI_REG_INDIRECTRD 0x60
223227
#define CQSPI_REG_INDIRECTRD_START_MASK BIT(0)
224228
#define CQSPI_REG_INDIRECTRD_CANCEL_MASK BIT(1)
@@ -374,17 +378,12 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
374378
/* Clear interrupt */
375379
writel(irq_status, cqspi->iobase + CQSPI_REG_IRQSTATUS);
376380

377-
if (cqspi->use_dma_read && ddata && ddata->get_dma_status) {
378-
if (ddata->get_dma_status(cqspi)) {
379-
complete(&cqspi->transfer_complete);
380-
return IRQ_HANDLED;
381-
}
382-
}
383-
384-
else if (!cqspi->slow_sram)
385-
irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
386-
else
381+
if (cqspi->use_dma_read && ddata && ddata->get_dma_status)
382+
irq_status = ddata->get_dma_status(cqspi);
383+
else if (cqspi->slow_sram)
387384
irq_status &= CQSPI_IRQ_MASK_RD_SLOW_SRAM | CQSPI_IRQ_MASK_WR;
385+
else
386+
irq_status &= CQSPI_IRQ_MASK_RD | CQSPI_IRQ_MASK_WR;
388387

389388
if (irq_status)
390389
complete(&cqspi->transfer_complete);
@@ -1263,7 +1262,7 @@ static void cqspi_config_baudrate_div(struct cqspi_st *cqspi)
12631262

12641263
reg = readl(reg_base + CQSPI_REG_CONFIG);
12651264
reg &= ~(CQSPI_REG_CONFIG_BAUD_MASK << CQSPI_REG_CONFIG_BAUD_LSB);
1266-
reg |= (div & CQSPI_REG_CONFIG_BAUD_MASK) << CQSPI_REG_CONFIG_BAUD_LSB;
1265+
reg |= div << CQSPI_REG_CONFIG_BAUD_LSB;
12671266
writel(reg, reg_base + CQSPI_REG_CONFIG);
12681267
}
12691268

@@ -1430,7 +1429,8 @@ static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
14301429
if (ret)
14311430
return ret;
14321431

1433-
if (cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size))
1432+
if ((cqspi->use_direct_mode && ((from + len) <= cqspi->ahb_size)) ||
1433+
(cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE))
14341434
return cqspi_direct_read_execute(f_pdata, buf, from, len);
14351435

14361436
if (cqspi->use_dma_read && ddata && ddata->indirect_read_dma &&
@@ -1536,6 +1536,10 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
15361536
return false;
15371537
if (op->data.nbytes && op->data.buswidth != 8)
15381538
return false;
1539+
1540+
/* A single opcode is supported, it will be repeated */
1541+
if ((op->cmd.opcode >> 8) != (op->cmd.opcode & 0xFF))
1542+
return false;
15391543
} else if (!all_false) {
15401544
/* Mixed DTR modes are not supported. */
15411545
return false;
@@ -1594,10 +1598,8 @@ static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
15941598
cqspi->fifo_depth = 0;
15951599
}
15961600

1597-
if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width)) {
1598-
dev_err(dev, "couldn't determine fifo-width\n");
1599-
return -ENXIO;
1600-
}
1601+
if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
1602+
cqspi->fifo_width = 4;
16011603

16021604
if (of_property_read_u32(np, "cdns,trigger-address",
16031605
&cqspi->trigger_address)) {
@@ -1627,19 +1629,24 @@ static void cqspi_controller_init(struct cqspi_st *cqspi)
16271629
/* Disable all interrupts. */
16281630
writel(0, cqspi->iobase + CQSPI_REG_IRQMASK);
16291631

1630-
/* Configure the SRAM split to 1:1 . */
1631-
writel(cqspi->fifo_depth / 2, cqspi->iobase + CQSPI_REG_SRAMPARTITION);
1632+
if (!(cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)) {
1633+
/* Configure the SRAM split to 1:1 . */
1634+
writel(cqspi->fifo_depth / 2, cqspi->iobase + CQSPI_REG_SRAMPARTITION);
1635+
/* Load indirect trigger address. */
1636+
writel(cqspi->trigger_address,
1637+
cqspi->iobase + CQSPI_REG_INDIRECTTRIGGER);
16321638

1633-
/* Load indirect trigger address. */
1634-
writel(cqspi->trigger_address,
1635-
cqspi->iobase + CQSPI_REG_INDIRECTTRIGGER);
1639+
/* Program read watermark -- 1/2 of the FIFO. */
1640+
writel(cqspi->fifo_depth * cqspi->fifo_width / 2,
1641+
cqspi->iobase + CQSPI_REG_INDIRECTRDWATERMARK);
1642+
/* Program write watermark -- 1/8 of the FIFO. */
1643+
writel(cqspi->fifo_depth * cqspi->fifo_width / 8,
1644+
cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK);
1645+
}
16361646

1637-
/* Program read watermark -- 1/2 of the FIFO. */
1638-
writel(cqspi->fifo_depth * cqspi->fifo_width / 2,
1639-
cqspi->iobase + CQSPI_REG_INDIRECTRDWATERMARK);
1640-
/* Program write watermark -- 1/8 of the FIFO. */
1641-
writel(cqspi->fifo_depth * cqspi->fifo_width / 8,
1642-
cqspi->iobase + CQSPI_REG_INDIRECTWRWATERMARK);
1647+
/* Disable write protection at controller level */
1648+
if (cqspi->ddata && cqspi->ddata->quirks & CQSPI_HAS_WR_PROTECT)
1649+
writel(0, cqspi->iobase + CQSPI_REG_WR_PROT_CTRL);
16431650

16441651
/* Disable direct access controller */
16451652
if (!cqspi->use_direct_mode) {
@@ -1890,30 +1897,30 @@ static int cqspi_probe(struct platform_device *pdev)
18901897
ret = clk_prepare_enable(cqspi->clk);
18911898
if (ret) {
18921899
dev_err(dev, "Cannot enable QSPI clock.\n");
1893-
goto probe_clk_failed;
1900+
goto disable_rpm;
18941901
}
18951902

18961903
/* Obtain QSPI reset control */
18971904
rstc = devm_reset_control_get_optional_exclusive(dev, "qspi");
18981905
if (IS_ERR(rstc)) {
18991906
ret = PTR_ERR(rstc);
19001907
dev_err(dev, "Cannot get QSPI reset.\n");
1901-
goto probe_reset_failed;
1908+
goto disable_clk;
19021909
}
19031910

19041911
rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
19051912
if (IS_ERR(rstc_ocp)) {
19061913
ret = PTR_ERR(rstc_ocp);
19071914
dev_err(dev, "Cannot get QSPI OCP reset.\n");
1908-
goto probe_reset_failed;
1915+
goto disable_clk;
19091916
}
19101917

19111918
if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
19121919
rstc_ref = devm_reset_control_get_optional_exclusive(dev, "rstc_ref");
19131920
if (IS_ERR(rstc_ref)) {
19141921
ret = PTR_ERR(rstc_ref);
19151922
dev_err(dev, "Cannot get QSPI REF reset.\n");
1916-
goto probe_reset_failed;
1923+
goto disable_clk;
19171924
}
19181925
reset_control_assert(rstc_ref);
19191926
reset_control_deassert(rstc_ref);
@@ -1955,15 +1962,15 @@ static int cqspi_probe(struct platform_device *pdev)
19551962
if (ddata->jh7110_clk_init) {
19561963
ret = cqspi_jh7110_clk_init(pdev, cqspi);
19571964
if (ret)
1958-
goto probe_reset_failed;
1965+
goto disable_clk;
19591966
}
19601967
if (ddata->quirks & CQSPI_DISABLE_STIG_MODE)
19611968
cqspi->disable_stig_mode = true;
19621969

19631970
if (ddata->quirks & CQSPI_DMA_SET_MASK) {
19641971
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
19651972
if (ret)
1966-
goto probe_reset_failed;
1973+
goto disable_clks;
19671974
}
19681975
}
19691976

@@ -1974,7 +1981,7 @@ static int cqspi_probe(struct platform_device *pdev)
19741981
pdev->name, cqspi);
19751982
if (ret) {
19761983
dev_err(dev, "Cannot request IRQ.\n");
1977-
goto probe_reset_failed;
1984+
goto disable_clks;
19781985
}
19791986

19801987
cqspi_wait_idle(cqspi);
@@ -2001,31 +2008,36 @@ static int cqspi_probe(struct platform_device *pdev)
20012008
ret = cqspi_request_mmap_dma(cqspi);
20022009
if (ret == -EPROBE_DEFER) {
20032010
dev_err_probe(&pdev->dev, ret, "Failed to request mmap DMA\n");
2004-
goto probe_setup_failed;
2011+
goto disable_controller;
20052012
}
20062013
}
20072014

20082015
ret = spi_register_controller(host);
20092016
if (ret) {
20102017
dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
2011-
goto probe_setup_failed;
2018+
goto release_dma_chan;
20122019
}
20132020

20142021
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
20152022
pm_runtime_put_autosuspend(dev);
20162023

20172024
return 0;
2018-
probe_setup_failed:
2019-
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
2020-
pm_runtime_disable(dev);
2025+
2026+
release_dma_chan:
2027+
if (cqspi->rx_chan)
2028+
dma_release_channel(cqspi->rx_chan);
2029+
disable_controller:
20212030
cqspi_controller_enable(cqspi, 0);
2022-
probe_reset_failed:
2031+
disable_clks:
20232032
if (cqspi->is_jh7110)
20242033
cqspi_jh7110_disable_clk(pdev, cqspi);
2025-
2034+
disable_clk:
20262035
if (pm_runtime_get_sync(&pdev->dev) >= 0)
20272036
clk_disable_unprepare(cqspi->clk);
2028-
probe_clk_failed:
2037+
disable_rpm:
2038+
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
2039+
pm_runtime_disable(dev);
2040+
20292041
return ret;
20302042
}
20312043

@@ -2034,6 +2046,7 @@ static void cqspi_remove(struct platform_device *pdev)
20342046
const struct cqspi_driver_platdata *ddata;
20352047
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
20362048
struct device *dev = &pdev->dev;
2049+
int ret = 0;
20372050

20382051
ddata = of_device_get_match_data(dev);
20392052

@@ -2043,18 +2056,21 @@ static void cqspi_remove(struct platform_device *pdev)
20432056
cqspi_wait_idle(cqspi);
20442057

20452058
spi_unregister_controller(cqspi->host);
2046-
cqspi_controller_enable(cqspi, 0);
20472059

20482060
if (cqspi->rx_chan)
20492061
dma_release_channel(cqspi->rx_chan);
20502062

2051-
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
2052-
if (pm_runtime_get_sync(&pdev->dev) >= 0)
2053-
clk_disable(cqspi->clk);
2063+
cqspi_controller_enable(cqspi, 0);
20542064

20552065
if (cqspi->is_jh7110)
20562066
cqspi_jh7110_disable_clk(pdev, cqspi);
20572067

2068+
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
2069+
ret = pm_runtime_get_sync(&pdev->dev);
2070+
2071+
if (ret >= 0)
2072+
clk_disable(cqspi->clk);
2073+
20582074
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
20592075
pm_runtime_put_sync(&pdev->dev);
20602076
pm_runtime_disable(&pdev->dev);
@@ -2134,26 +2150,23 @@ static const struct cqspi_driver_platdata intel_lgm_qspi = {
21342150
};
21352151

21362152
static const struct cqspi_driver_platdata socfpga_qspi = {
2137-
.quirks = CQSPI_DISABLE_DAC_MODE
2138-
| CQSPI_NO_SUPPORT_WR_COMPLETION
2139-
| CQSPI_SLOW_SRAM
2140-
| CQSPI_DISABLE_STIG_MODE
2141-
| CQSPI_DISABLE_RUNTIME_PM,
2153+
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION |
2154+
CQSPI_SLOW_SRAM | CQSPI_DISABLE_STIG_MODE |
2155+
CQSPI_DISABLE_RUNTIME_PM,
21422156
};
21432157

21442158
static const struct cqspi_driver_platdata versal_ospi = {
21452159
.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
2146-
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA
2147-
| CQSPI_DMA_SET_MASK,
2160+
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA |
2161+
CQSPI_DMA_SET_MASK,
21482162
.indirect_read_dma = cqspi_versal_indirect_read_dma,
21492163
.get_dma_status = cqspi_get_versal_dma_status,
21502164
};
21512165

21522166
static const struct cqspi_driver_platdata versal2_ospi = {
21532167
.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
2154-
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA
2155-
| CQSPI_DMA_SET_MASK
2156-
| CQSPI_SUPPORT_DEVICE_RESET,
2168+
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_SUPPORT_EXTERNAL_DMA |
2169+
CQSPI_DMA_SET_MASK | CQSPI_SUPPORT_DEVICE_RESET,
21572170
.indirect_read_dma = cqspi_versal_indirect_read_dma,
21582171
.get_dma_status = cqspi_get_versal_dma_status,
21592172
};
@@ -2170,7 +2183,7 @@ static const struct cqspi_driver_platdata pensando_cdns_qspi = {
21702183
static const struct cqspi_driver_platdata mobileye_eyeq5_ospi = {
21712184
.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
21722185
.quirks = CQSPI_DISABLE_DAC_MODE | CQSPI_NO_SUPPORT_WR_COMPLETION |
2173-
CQSPI_RD_NO_IRQ,
2186+
CQSPI_RD_NO_IRQ,
21742187
};
21752188

21762189
static const struct of_device_id cqspi_dt_ids[] = {

0 commit comments

Comments
 (0)