[PATCH v2 0/8] spi: cadence-xspi: add ACMD mode and ADSP SC846 integration
From: Nuno Sá
Date: Wed Nov 11 2026 - 08:33:48 EST
The Cadence xSPI driver currently drives every operation through STIG
mode, where the CPU builds each command and drains the data. The
controller also has an auto command (ACMD) mode where it runs whole
sequences on its own and can move data with its internal DMA, which
pays off for bulk reads.
Whether ACMD and the internal DMA can be used depends on the SoC
integration (external SRAM, the DMA bus requester interface being
wired), which the controller registers do not expose. Hence, the series
also adds support for the ADI ADSP-SC846 integration, which enables
ACMD through its driver data. On the way, the platform specifics are
moved into the driver data and optional clocks and resets support is
added for the IP.
For now, ACMD is only used for reads of at least 2048 bytes with an
address phase, using the internal DMA, and only on integrations
supporting it. Smaller reads and all other operations stay on STIG.
NOR and NAND are handled the same way: NAND operations are still issued
one by one, not combined into a single ACMD sequence, so no NAND
geometry is needed. The real gain is on large reads which, for NAND,
means chips supporting buffer/sequential read mode.
Another attempt for ACMD was sent in [1] but that relies on knowing the
NAND geometry which brings much more complexity given that it needs a
proper interface implemented in the spi-nand core. So we agreed on
starting with this simpler approach and then build on top of it if we
agree it pays off (mostly on cpu load).
Some stats:
ACMD
-----
SPI-NOR - is25wx01g (only reads > 2k are done in ACMD )
-------
flash_speed -c 5 -d /dev/mtd4
not NAND flash, assume page size is 512 bytes.
scanning for bad eraseblocks
scanned 5 eraseblocks, 0 are bad
testing eraseblock write speed
eraseblock write speed is 1054 KiB/s
testing eraseblock read speed
eraseblock read speed is 106666 KiB/s
testing page write speed
page write speed is 1035 KiB/s
testing page read speed
page read speed is 15238 KiB/s
SPI-NAND - w25n08lw (all reads are ACMD given that page size is 4k)
--------
flash_speed -c 5 -d /dev/mtd5
scanning for bad eraseblocks
scanned 5 eraseblocks, 0 are bad
testing eraseblock write speed
eraseblock write speed is 6497 KiB/s
testing eraseblock read speed
eraseblock read speed is 44137 KiB/s
testing page write speed
page write speed is 6336 KiB/s
testing page read speed
page read speed is 16842 KiB/s
STIG
----
SPI-NOR
-------
flash_speed -c 5 -d /dev/mtd4
not NAND flash, assume page size is 512 bytes.
scanning for bad eraseblocks
scanned 5 eraseblocks, 0 are bad
testing eraseblock write speed
eraseblock write speed is 1054 KiB/s
testing eraseblock read speed
eraseblock read speed is 64000 KiB/s
testing page write speed
page write speed is 1042 KiB/s
testing page read speed
page read speed is 14883 KiB/s
SPI-NAND (Cont mode)
--------
flash_speed -c 5 -d /dev/mtd5
scanning for bad eraseblocks
scanned 5 eraseblocks, 0 are bad
testing eraseblock write speed
eraseblock write speed is 6564 KiB/s
testing eraseblock read speed
eraseblock read speed is 18823 KiB/s
testing page write speed
page write speed is 6400 KiB/s
testing page read speed
page read speed is 18028 KiB/s
For now, we have a static threshold to decide to use ACMD or not. I do
understand that's not ideal. It might depend on sclk and number of lanes
so not sure if that value will be accurate for everybody. So, open to
suggestions if someone has something in mind regarding this.
Changes in v2:
- Patch 1 (new):
- Fail on command errors reported without a known cause.
- Patch 2 (new):
- Wait for the controller initialization on resume, as the IP might
lose power across suspend (Mark).
- Patch 3 (new):
- dt-bindings: add optional clocks and resets.
- Patch 4 (new):
- Get/enable the optional clock and reset the controller at probe,
waiting for its initialization after the reset.
- Patch 5 (new):
- Move the platform specifics into per compatible driver data.
- Patch 6 (new):
- dt-bindings: add the adi,adsp-sc846-xspi compatible, clocks and resets
required for it.
- Patch 7 (new):
- Add the ADI SC846 integration, PHY setup at probe and resume.
- Patch 8:
- Infer ACMD support from the compatible (driver data) instead of DT
properties (Conor).
- Invalidate the cached work mode and redo the ACMD setup on resume
(Mark).
- Always report the ACMD error from the command status, the thread
error interrupt only wakes up the waiter (sashiko).
- Comment why ACMD reads are not size limited (Mark).
- Dropped the sdma_error to xfer_error rename patch, not needed anymore.
- Dropped the cdns,has-acmd and cdns,has-internal-dma properties patch
(Conor).
- Link to v1: https://patch.msgid.link/20261029-xspi-cadence-add-acmd-v1-0-53cd44690e04@xxxxxxxxxx
[1]: https://lore.kernel.org/linux-spi/20260921093701.1341766-1-fei.xie@xxxxxxxxxxxx/
---
Nuno Sá (8):
spi: cadence-xspi: fail on command errors without a known cause
spi: cadence-xspi: wait for the controller initialization on resume
spi: dt-bindings: cdns,xspi: add clocks and resets
spi: cadence-xspi: support clocks and resets
spi: cadence-xspi: move platform specifics into driver data
spi: dt-bindings: cdns,xspi: add ADI SC846 compatible
spi: cadence-xspi: add ADI SC846 platform support
spi: cadence-xspi: add ACMD mode support
.../devicetree/bindings/spi/cdns,xspi.yaml | 16 +
drivers/spi/spi-cadence-xspi.c | 530 +++++++++++++++++----
2 files changed, 457 insertions(+), 89 deletions(-)
---
base-commit: 7da2aca123754c0e06092bbe179d58078b58d8d4
change-id: 20261027-xspi-cadence-add-acmd-3c0e342cb4f4
--
Thanks!
- Nuno Sá