* [PATCH 1/5] spi: cadence-xspi: Reconfigure to STIG mode before SPI message
2026-11-04 10:06 [PATCH 0/5] spi: cadence-xspi: Fixes and misc. changes Paul Cercueil
@ 2026-11-04 10:06 ` Paul Cercueil
2026-11-04 10:06 ` [PATCH 2/5] spi: cadence-xspi: Inform SPI core about size transferred Paul Cercueil
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Cercueil @ 2026-11-04 10:06 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-kernel, Thomas Petazzoni, Bharat Bhushan,
Sunil Kovvuri Goutham, Tanmay Jagdale, stable, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
The .transfer_one_message() function uses the STIG mode, therefore the
xSPI needs to be configured to STIG mode before starting any transfer.
Without this, .transfer_one_message() simply won't work, at least on the
CN10K SoC.
Fixes: 931e389ded0f ("spi: cadence: Add Marvell xfer operation support")
Cc: stable@vger.kernel.org
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
drivers/spi/spi-cadence-xspi.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 3687853e4ce4..e3e265f51e56 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -367,6 +367,20 @@ static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_dev *cdns_xspi)
100, 1000);
}
+static int cdns_xspi_set_stig_mode(struct cdns_xspi_dev *cdns_xspi)
+{
+ int ret;
+
+ ret = cdns_xspi_wait_for_controller_idle(cdns_xspi);
+ if (ret < 0)
+ return -EIO;
+
+ writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG),
+ cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG);
+
+ return 0;
+}
+
static void cdns_xspi_trigger_command(struct cdns_xspi_dev *cdns_xspi,
u32 cmd_regs[6])
{
@@ -536,12 +550,9 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
int ret;
int dummybytes = op->dummy.nbytes;
- ret = cdns_xspi_wait_for_controller_idle(cdns_xspi);
- if (ret < 0)
- return -EIO;
-
- writel(FIELD_PREP(CDNS_XSPI_CTRL_WORK_MODE, CDNS_XSPI_WORK_MODE_STIG),
- cdns_xspi->iobase + CDNS_XSPI_CTRL_CONFIG_REG);
+ ret = cdns_xspi_set_stig_mode(cdns_xspi);
+ if (ret)
+ return ret;
cdns_xspi->set_interrupts_handler(cdns_xspi, true);
cdns_xspi->sdma_error = false;
@@ -1112,6 +1123,11 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
int current_transfer_len;
int cs = spi_get_chipselect(spi, 0);
int cs_change = 0;
+ int ret;
+
+ ret = cdns_xspi_set_stig_mode(cdns_xspi);
+ if (ret)
+ return ret;
/* Enable xfer state machine */
if (!cdns_xspi->xfer_in_progress) {
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 2/5] spi: cadence-xspi: Inform SPI core about size transferred
2026-11-04 10:06 [PATCH 0/5] spi: cadence-xspi: Fixes and misc. changes Paul Cercueil
2026-11-04 10:06 ` [PATCH 1/5] spi: cadence-xspi: Reconfigure to STIG mode before SPI message Paul Cercueil
@ 2026-11-04 10:06 ` Paul Cercueil
2026-11-04 10:06 ` [PATCH 3/5] spi: cadence-xspi: Drop useless cdns_xspi->cur_cs Paul Cercueil
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Paul Cercueil @ 2026-11-04 10:06 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-kernel, Thomas Petazzoni, Bharat Bhushan,
Sunil Kovvuri Goutham, Tanmay Jagdale, stable, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
The SPI core expects the 'actual_length' field of the spi_message to be
updated with the number of bytes transferred.
Fixes: 931e389ded0f ("spi: cadence: Add Marvell xfer operation support")
Cc: stable@vger.kernel.org
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
drivers/spi/spi-cadence-xspi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index e3e265f51e56..3cb2f95b98f6 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -1205,6 +1205,7 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
}
cs_change = t->cs_change;
t->len -= current_transfer_len;
+ m->actual_length += current_transfer_len;
}
spi_transfer_delay_exec(t);
}
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 3/5] spi: cadence-xspi: Drop useless cdns_xspi->cur_cs
2026-11-04 10:06 [PATCH 0/5] spi: cadence-xspi: Fixes and misc. changes Paul Cercueil
2026-11-04 10:06 ` [PATCH 1/5] spi: cadence-xspi: Reconfigure to STIG mode before SPI message Paul Cercueil
2026-11-04 10:06 ` [PATCH 2/5] spi: cadence-xspi: Inform SPI core about size transferred Paul Cercueil
@ 2026-11-04 10:06 ` Paul Cercueil
2026-11-04 10:06 ` [PATCH 4/5] spi: cadence-xspi: Rework resource discovery Paul Cercueil
2026-11-04 10:06 ` [PATCH 5/5] spi: cadence-xspi: Add workaround for old Marvell firmwares Paul Cercueil
4 siblings, 0 replies; 6+ messages in thread
From: Paul Cercueil @ 2026-11-04 10:06 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-kernel, Thomas Petazzoni, Bharat Bhushan,
Sunil Kovvuri Goutham, Tanmay Jagdale, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
Make the code simpler by just passing down a 'cs' variable as argument
to the cdns_xspi_send_stig_command() function.
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
drivers/spi/spi-cadence-xspi.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 3cb2f95b98f6..04c873f28ea6 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -331,7 +331,6 @@ struct cdns_xspi_dev {
void __iomem *xferbase;
int irq;
- int cur_cs;
unsigned int sdmasize;
unsigned int sdma_xfer_len;
@@ -543,7 +542,7 @@ static int cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
const struct spi_mem_op *op,
- bool data_phase)
+ int cs, bool data_phase)
{
u32 cmd_regs[6];
u32 cmd_status;
@@ -566,8 +565,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
} else {
cmd_regs[3] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, 0);
}
- cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op,
- cdns_xspi->cur_cs);
+ cmd_regs[4] = CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, cs);
cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
@@ -576,8 +574,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
cmd_regs[1] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_1(op);
cmd_regs[2] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op);
cmd_regs[3] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes);
- cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op,
- cdns_xspi->cur_cs);
+ cmd_regs[4] = CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, cs);
cdns_xspi->in_buffer = op->data.buf.in;
cdns_xspi->out_buffer = op->data.buf.out;
@@ -612,11 +609,9 @@ static int cdns_xspi_mem_op(struct cdns_xspi_dev *cdns_xspi,
const struct spi_mem_op *op)
{
enum spi_mem_data_dir dir = op->data.dir;
+ int cs = spi_get_chipselect(mem->spi, 0);
- if (cdns_xspi->cur_cs != spi_get_chipselect(mem->spi, 0))
- cdns_xspi->cur_cs = spi_get_chipselect(mem->spi, 0);
-
- return cdns_xspi_send_stig_command(cdns_xspi, op,
+ return cdns_xspi_send_stig_command(cdns_xspi, op, cs,
(dir != SPI_MEM_NO_DATA));
}
@@ -1265,7 +1260,6 @@ static int cdns_xspi_probe(struct platform_device *pdev)
cdns_xspi->pdev = pdev;
cdns_xspi->host = host;
cdns_xspi->dev = &pdev->dev;
- cdns_xspi->cur_cs = 0;
init_completion(&cdns_xspi->cmd_complete);
init_completion(&cdns_xspi->auto_cmd_complete);
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 4/5] spi: cadence-xspi: Rework resource discovery
2026-11-04 10:06 [PATCH 0/5] spi: cadence-xspi: Fixes and misc. changes Paul Cercueil
` (2 preceding siblings ...)
2026-11-04 10:06 ` [PATCH 3/5] spi: cadence-xspi: Drop useless cdns_xspi->cur_cs Paul Cercueil
@ 2026-11-04 10:06 ` Paul Cercueil
2026-11-04 10:06 ` [PATCH 5/5] spi: cadence-xspi: Add workaround for old Marvell firmwares Paul Cercueil
4 siblings, 0 replies; 6+ messages in thread
From: Paul Cercueil @ 2026-11-04 10:06 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-kernel, Thomas Petazzoni, Bharat Bhushan,
Sunil Kovvuri Goutham, Tanmay Jagdale, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
The previous code worked, but calling
devm_platform_ioremap_resource_byname() on ACPI where resources aren't
named causes warnings to be printed, one per call:
cadence-xspi PRP0001:02: error -EINVAL: invalid resource (null)
cadence-xspi PRP0001:02: error -EINVAL: invalid resource (null)
cadence-xspi PRP0001:02: error -EINVAL: invalid resource (null)
cadence-xspi PRP0001:02: error -EINVAL: invalid resource (null)
We can avoid these warnings by first obtaining a pointer to the resource
with platform_get_resource_byname() and fallback to
platform_get_resource() if it fails, and then ioremap the resource using
devm_ioremap_resource().
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
drivers/spi/spi-cadence-xspi.c | 50 ++++++++++++++++++----------------
1 file changed, 27 insertions(+), 23 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 04c873f28ea6..48a109f3fcdb 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -1269,44 +1269,48 @@ static int cdns_xspi_probe(struct platform_device *pdev)
if (ret)
return -ENODEV;
- cdns_xspi->iobase = devm_platform_ioremap_resource_byname(pdev, "io");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "io");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ cdns_xspi->iobase = devm_ioremap_resource(dev, res);
if (IS_ERR(cdns_xspi->iobase)) {
- cdns_xspi->iobase = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(cdns_xspi->iobase)) {
- dev_err(dev, "Failed to remap controller base address\n");
- return PTR_ERR(cdns_xspi->iobase);
- }
+ dev_err(dev, "Failed to remap controller base address\n");
+ return PTR_ERR(cdns_xspi->iobase);
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sdma");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+
cdns_xspi->sdmabase = devm_ioremap_resource(dev, res);
if (IS_ERR(cdns_xspi->sdmabase)) {
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- cdns_xspi->sdmabase = devm_ioremap_resource(dev, res);
- if (IS_ERR(cdns_xspi->sdmabase))
- return PTR_ERR(cdns_xspi->sdmabase);
+ dev_err(dev, "Failed to remap sdma address\n");
+ return PTR_ERR(cdns_xspi->sdmabase);
}
cdns_xspi->sdmasize = resource_size(res);
- cdns_xspi->auxbase = devm_platform_ioremap_resource_byname(pdev, "aux");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aux");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+
+ cdns_xspi->auxbase = devm_ioremap_resource(dev, res);
if (IS_ERR(cdns_xspi->auxbase)) {
- cdns_xspi->auxbase = devm_platform_ioremap_resource(pdev, 2);
- if (IS_ERR(cdns_xspi->auxbase)) {
- dev_err(dev, "Failed to remap AUX address\n");
- return PTR_ERR(cdns_xspi->auxbase);
- }
+ dev_err(dev, "Failed to remap AUX address\n");
+ return PTR_ERR(cdns_xspi->auxbase);
}
#ifdef CONFIG_64BIT
if (cdns_xspi->driver_data->mrvl_hw_overlay) {
- cdns_xspi->xferbase = devm_platform_ioremap_resource_byname(pdev, "xfer");
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xfer");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+
+ cdns_xspi->xferbase = devm_ioremap_resource(dev, res);
if (IS_ERR(cdns_xspi->xferbase)) {
- cdns_xspi->xferbase = devm_platform_ioremap_resource(pdev, 3);
- if (IS_ERR(cdns_xspi->xferbase)) {
- dev_info(dev, "XFER register base not found, set it\n");
- // For compatibility with older firmware
- cdns_xspi->xferbase = cdns_xspi->iobase + 0x8000;
- }
+ dev_info(dev, "XFER register base not found, set it\n");
+ // For compatibility with older firmware
+ cdns_xspi->xferbase = cdns_xspi->iobase + 0x8000;
}
}
#endif
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 5/5] spi: cadence-xspi: Add workaround for old Marvell firmwares
2026-11-04 10:06 [PATCH 0/5] spi: cadence-xspi: Fixes and misc. changes Paul Cercueil
` (3 preceding siblings ...)
2026-11-04 10:06 ` [PATCH 4/5] spi: cadence-xspi: Rework resource discovery Paul Cercueil
@ 2026-11-04 10:06 ` Paul Cercueil
4 siblings, 0 replies; 6+ messages in thread
From: Paul Cercueil @ 2026-11-04 10:06 UTC (permalink / raw)
To: Mark Brown
Cc: linux-spi, linux-kernel, Thomas Petazzoni, Bharat Bhushan,
Sunil Kovvuri Goutham, Tanmay Jagdale, Paul Cercueil
From: Tanmay Jagdale <tanmay@marvell.com>
Older firmwares from Marvell used the cdns,xspi-nor compatible string
for the Marvell-specific xSPI IP, which is incompatible.
Add a workaround to support this by assuming that if the "xfer" resource
is found, it means that a Marvell IP is used.
Signed-off-by: Tanmay Jagdale <tanmay@marvell.com>
Co-developed-by: Paul Cercueil <paul.cercueil@bootlin.com>
Signed-off-by: Paul Cercueil <paul.cercueil@bootlin.com>
---
drivers/spi/spi-cadence-xspi.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 48a109f3fcdb..d326589a6ca3 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -1301,11 +1301,21 @@ static int cdns_xspi_probe(struct platform_device *pdev)
}
#ifdef CONFIG_64BIT
- if (cdns_xspi->driver_data->mrvl_hw_overlay) {
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xfer");
- if (!res)
- res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "xfer");
+ if (!res)
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+
+ if (res && !cdns_xspi->driver_data->mrvl_hw_overlay) {
+ /*
+ * Handle old Marvell firmwares using the cdns,xspi-nor string
+ * instead of the marvell,cn10-xspi-nor string.
+ */
+ dev_warn(dev, "Marvell-specific xfer resource passed, but using the cdns,xspi-nor compatible string. Please fix firmware!\n");
+ cdns_xspi->driver_data = &marvell_driver_data;
+ }
+
+ if (cdns_xspi->driver_data->mrvl_hw_overlay) {
cdns_xspi->xferbase = devm_ioremap_resource(dev, res);
if (IS_ERR(cdns_xspi->xferbase)) {
dev_info(dev, "XFER register base not found, set it\n");
--
2.47.3
^ permalink raw reply [flat|nested] 6+ messages in thread