mirror of
https://github.com/torvalds/linux.git
synced 2026-03-13 23:46:14 +01:00
spi: cadence-qspi: Add support for the Renesas RZ/N1 controller
Renesas RZ/N1 QSPI controllers embed a modified version of the Cadence IP with the following settings: - a limited bus clock range - no DTR support - no DMA - no useful interrupt flag - only direct accesses (no INDAC mode) - write protection The controller has been tested by running the SPI NOR check list with a custom RZ/N1D400 based board mounted with a Spansion s25fl128s1 quad SPI. Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com> Link: https://patch.msgid.link/20260205-schneider-6-19-rc1-qspi-v5-3-843632b3c674@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
324ecc7788
commit
a40236feb6
1 changed files with 42 additions and 14 deletions
|
|
@ -110,6 +110,7 @@ struct cqspi_st {
|
|||
bool apb_ahb_hazard;
|
||||
|
||||
bool is_jh7110; /* Flag for StarFive JH7110 SoC */
|
||||
bool is_rzn1; /* Flag for Renesas RZ/N1 SoC */
|
||||
bool disable_stig_mode;
|
||||
refcount_t refcount;
|
||||
refcount_t inflight_ops;
|
||||
|
|
@ -1337,8 +1338,9 @@ static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
|
|||
* mode. So, we can not use direct mode when in DTR mode for writing
|
||||
* data.
|
||||
*/
|
||||
if (!op->cmd.dtr && cqspi->use_direct_mode &&
|
||||
cqspi->use_direct_mode_wr && ((to + len) <= cqspi->ahb_size)) {
|
||||
if ((!op->cmd.dtr && cqspi->use_direct_mode &&
|
||||
cqspi->use_direct_mode_wr && ((to + len) <= cqspi->ahb_size)) ||
|
||||
(cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)) {
|
||||
memcpy_toio(cqspi->ahb_base + to, buf, len);
|
||||
return cqspi_wait_idle(cqspi);
|
||||
}
|
||||
|
|
@ -1512,6 +1514,7 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
|
|||
static bool cqspi_supports_mem_op(struct spi_mem *mem,
|
||||
const struct spi_mem_op *op)
|
||||
{
|
||||
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
|
||||
bool all_true, all_false;
|
||||
|
||||
/*
|
||||
|
|
@ -1538,6 +1541,9 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
|
|||
/* A single opcode is supported, it will be repeated */
|
||||
if ((op->cmd.opcode >> 8) != (op->cmd.opcode & 0xFF))
|
||||
return false;
|
||||
|
||||
if (cqspi->is_rzn1)
|
||||
return false;
|
||||
} else if (!all_false) {
|
||||
/* Mixed DTR modes are not supported. */
|
||||
return false;
|
||||
|
|
@ -1591,18 +1597,20 @@ static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
|
|||
|
||||
cqspi->is_decoded_cs = of_property_read_bool(np, "cdns,is-decoded-cs");
|
||||
|
||||
if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth)) {
|
||||
/* Zero signals FIFO depth should be runtime detected. */
|
||||
cqspi->fifo_depth = 0;
|
||||
}
|
||||
if (!(cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)) {
|
||||
if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth)) {
|
||||
/* Zero signals FIFO depth should be runtime detected. */
|
||||
cqspi->fifo_depth = 0;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
|
||||
cqspi->fifo_width = 4;
|
||||
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)) {
|
||||
dev_err(dev, "couldn't determine trigger-address\n");
|
||||
return -ENXIO;
|
||||
if (of_property_read_u32(np, "cdns,trigger-address",
|
||||
&cqspi->trigger_address)) {
|
||||
dev_err(dev, "couldn't determine trigger-address\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
}
|
||||
|
||||
if (of_property_read_u32(np, "num-cs", &cqspi->num_chipselect))
|
||||
|
|
@ -1666,6 +1674,9 @@ static void cqspi_controller_detect_fifo_depth(struct cqspi_st *cqspi)
|
|||
struct device *dev = &cqspi->pdev->dev;
|
||||
u32 reg, fifo_depth;
|
||||
|
||||
if (cqspi->ddata && cqspi->ddata->quirks & CQSPI_NO_INDIRECT_MODE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Bits N-1:0 are writable while bits 31:N are read as zero, with 2^N
|
||||
* the FIFO depth.
|
||||
|
|
@ -1790,6 +1801,8 @@ static int cqspi_probe(struct platform_device *pdev)
|
|||
cqspi = spi_controller_get_devdata(host);
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi"))
|
||||
cqspi->is_jh7110 = true;
|
||||
if (of_device_is_compatible(pdev->dev.of_node, "renesas,rzn1-qspi"))
|
||||
cqspi->is_rzn1 = true;
|
||||
|
||||
cqspi->pdev = pdev;
|
||||
cqspi->host = host;
|
||||
|
|
@ -1887,7 +1900,12 @@ static int cqspi_probe(struct platform_device *pdev)
|
|||
reset_control_deassert(rstc_ocp);
|
||||
|
||||
cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clks[CLK_QSPI_REF].clk);
|
||||
host->max_speed_hz = cqspi->master_ref_clk_hz;
|
||||
if (!cqspi->is_rzn1) {
|
||||
host->max_speed_hz = cqspi->master_ref_clk_hz;
|
||||
} else {
|
||||
host->max_speed_hz = cqspi->master_ref_clk_hz / 2;
|
||||
host->min_speed_hz = cqspi->master_ref_clk_hz / 32;
|
||||
}
|
||||
|
||||
/* write completion is supported by default */
|
||||
cqspi->wr_completion = true;
|
||||
|
|
@ -1952,7 +1970,7 @@ static int cqspi_probe(struct platform_device *pdev)
|
|||
if (ddata && (ddata->quirks & CQSPI_SUPPORT_DEVICE_RESET))
|
||||
cqspi_device_reset(cqspi);
|
||||
|
||||
if (cqspi->use_direct_mode) {
|
||||
if (cqspi->use_direct_mode && !cqspi->is_rzn1) {
|
||||
ret = cqspi_request_mmap_dma(cqspi);
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
dev_err_probe(&pdev->dev, ret, "Failed to request mmap DMA\n");
|
||||
|
|
@ -2132,6 +2150,12 @@ static const struct cqspi_driver_platdata mobileye_eyeq5_ospi = {
|
|||
CQSPI_RD_NO_IRQ,
|
||||
};
|
||||
|
||||
static const struct cqspi_driver_platdata renesas_rzn1_qspi = {
|
||||
.hwcaps_mask = CQSPI_SUPPORTS_QUAD,
|
||||
.quirks = CQSPI_NO_SUPPORT_WR_COMPLETION | CQSPI_RD_NO_IRQ |
|
||||
CQSPI_HAS_WR_PROTECT | CQSPI_NO_INDIRECT_MODE,
|
||||
};
|
||||
|
||||
static const struct of_device_id cqspi_dt_ids[] = {
|
||||
{
|
||||
.compatible = "cdns,qspi-nor",
|
||||
|
|
@ -2173,6 +2197,10 @@ static const struct of_device_id cqspi_dt_ids[] = {
|
|||
.compatible = "amd,versal2-ospi",
|
||||
.data = &versal2_ospi,
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,rzn1-qspi",
|
||||
.data = &renesas_rzn1_qspi,
|
||||
},
|
||||
{ /* end of table */ }
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue