Skip to content

[ADSP SC846] Add Cadence XSPI STIG support - #3478

Open
nunojsa wants to merge 22 commits into
adsp-6.18.31-yfrom
adsp-6.18.y/staging/sc846-support-xspi
Open

nunojsa wants to merge 22 commits into
adsp-6.18.31-yfrom
adsp-6.18.y/staging/sc846-support-xspi

Conversation

@nunojsa

@nunojsa nunojsa commented Aug 5, 2026 •

Copy link
Copy Markdown
Collaborator

PR Description

Add support for the cadence XSPI IP on the ADSP SC846 platforms! For now this is just a draft PR given that there are some assumptions that are being made:

  1. We can't control the xspi clock (so it just runs at whatever speed is programmed during boot).
  2. Bringing the core out of reset is also not handled by linux.
  3. The scb5 memory window shared by xspi0, spi1 and spi2 needs to be properly programmed in SPL.

So, 1. also depends on how the clock tree driver is refactored. Right now is a bit of a mess given that clk_set_rate() just silently "fails" and does not work. In theory we should allow for it (I would like to be able to honor spi-max-speed on the flash node - or properly failing if not possible) but that also depends on the said refactor.

For 2. my gut feeling is that we need to handle it in linux.

  1. is the one that genuinely can be missing in linux as we don't really have the permissions to write that scb5 register (needs to be in SPL). However I'm thinking in just having a syscon remap where we could just read the register and see if the memory region is mapped to SDMA. If not we could at least fail gracefully during probe rather than seeing some log about wrong memory jedec ID (or something like that) and start thinking that phy configurations are screwed!

@nunojsa
nunojsa marked this pull request as draft August 5, 2026 16:46
@nunojsa
nunojsa requested review from a team August 5, 2026 16:46
@nunojsa nunojsa added the sc846 Support for the ADSP-SC846 label Aug 5, 2026
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from 9b06b3b to de1e193 Compare August 7, 2026 16:04
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from de1e193 to a038fd0 Compare August 17, 2026 15:28
@pamolloy pamolloy added this to ADSP Aug 18, 2026
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from a038fd0 to c318406 Compare August 18, 2026 15:21
@nunojsa

nunojsa commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator Author

For the XSPI NAND, I reverted to use single lane! Today results were very unstable for octal and pointed to a DQ (presumbly DQ4) lane to be somehow in a bad state (given that always the same bit came wrong in a word). Also for full disclosure, the sweep reads tests and byte comparisons were done by a LLM. But the results made sense and comparing bytes (and seeing patterns) is something it's arguably good at (so I can of trust the outcome)! Also different phy settings and frequencies came up with the same bit problem (lower frequencies seem to improve the results).

But one fact is undeniable. Same setup that worked yesterday, failed today!

@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch 2 times, most recently from 8bff206 to 7be2211 Compare August 28, 2026 09:07
@nunojsa

nunojsa commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator Author
  • Add support for the W25N08LW chip and updated DT patch accordingly

@pamolloy

Copy link
Copy Markdown
Collaborator

For reference the Synaptics Linux tree that includes support for the same XSPI IP, but it looks like they're only using it to interface with NOR:

https://github.com/synaptics-astra/linux_6_12-main/commits/scarthgap_6.12_v2.5.0/

@pamolloy pamolloy added the xspi Support for the ADSP-SC846 XSPI controller label Aug 31, 2026
@pamolloy pamolloy changed the title [ADSP SC846] Add Cadence XSPI support [ADSP SC846] Add Cadence XSPI STIG support Aug 31, 2026
@pamolloy pamolloy moved this to In Development in ADSP Aug 31, 2026
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from 7be2211 to 930bcee Compare September 8, 2026 16:07
@nunojsa

nunojsa commented Sep 8, 2026 •

Copy link
Copy Markdown
Collaborator Author

New force push

  • Backports some stuff that we need for continuous reads for NANDS which together with ACMD make the real difference in terms of performance;
  • With the above, add continuous reads for W25N08LW (and I will update that on mtd: spinand: winbond: Add support for W25N08LW #3521)
  • ACMD reads added (which gave more than 2x on NOR and NAND + cont_reads)
  • Given that on the shipped boards we have two NORs on SOM and EZ kit, update xspi1 DT entry accordingly

The MISCREG integration register file of the Analog Devices ADSP-SC84x
processors holds the reset masks of the two xSPI controllers and their
PHYs, as well as the soft reset requests of the two CAN-FD
controllers. Describe them as a reset provider so that those
peripherals can get their reset line through the reset framework.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
MISCREG is the integration register file of the ADSP-SC84x processors.
It gathers glue registers of otherwise unrelated hardware blocks: xSPI
tie-offs and reset masks, CAN-FD low power and soft reset requests,
clock multiplexer selections, RGMII pad skew and the DDR prefetch
window selection.

Only the reset lines map onto a Linux provider abstraction, so the
block is described as a syscon and simple-mfd with a reset controller
child. The remaining registers are meant to be reached through the
syscon register map by the drivers owning them.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from 930bcee to ff671ec Compare September 23, 2026 12:13
The Analog Devices SC846 SoC integrates the Cadence XSPI controller with
its own PHY timing configuration, so it cannot be described by the
generic "cdns,xspi-nor" compatible. Add a platform specific compatible
for it. With it also add optional reset and clock properties needed by this
platform.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from ff671ec to fcbb478 Compare September 23, 2026 13:06
@nunojsa
nunojsa marked this pull request as ready for review September 23, 2026 13:08
As of now, we only use a single operation template when creating SPI
memory direct mappings. With the idea to extend this possibility to 2,
rename the template to reflect that we are currently setting the
"primary" operation, and create a pointer in the same structure to point
to it.

From a user point of view, the op_tmpl name remains but becomes a
pointer, leading to minor changes in both the SPI NAND and SPI NOR
cores.

There is no functional change.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
(cherry picked from commit 39d0ea3)
In order to introduce DTR support in SPI NAND, a number of macros had to
be created in the spi-mem layer. One of them remained unused at this
point, SPI_MEM_DTR_OP_CMD. Being in the process of introducing octal DTR
support now, experience shows that as-is the macro is not useful. In
order to be really useful in octal DTR mode, the command opcode (one
byte) must always be transmitted on the 8 data lines on both the rising
and falling edge of the clock. Align the macro with the real needs by
duplicating the opcode in the buffer and doubling its size.

Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260109-winbond-v6-17-rc1-oddr-v2-1-1fff6a2ddb80@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 0196932)
In some situations, direct mappings may need to use different
operation templates.

For instance, when enabling continuous reads, Winbond SPI NANDs no
longer expect address cycles because they would be ignoring them
otherwise. Hence, right after the command opcode, they start counting
dummy cycles, followed by the data cycles as usual.

This breaks the assumptions of "reads from cache" always being done
identically once the best variant has been picked up, across the
lifetime of the system.

In order to support this feature, we must give direct mapping more than
a single operation template to use, in order to switch to using
secondary operations upon request by the upper layer.

Create the concept of optional secondary operation template, which may
or may not be fulfilled by the SPI NAND and SPI NOR cores. If the
underlying SPI controller does not leverage any kind of direct mapping
acceleration, the feature has no impact and can be freely
used. Otherwise, the controller driver needs to opt-in for using this
feature, if supported.

The condition checked to know whether a secondary operation has been
provided or not is to look for a non zero opcode to limit the creation
of extra variables. In practice, the opcode 0x00 exist, but is not
related to any cache related operation.

Acked-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
(cherry picked from commit 6f96f2f)
miquelraynal and others added 7 commits September 23, 2026 14:17
In case a chip supports continuous reads, but uses a slightly different
cache operation for these, it may provide a secondary operation template
which will be used only during continuous cache read operations.

From a vendor driver point of view, enabling this feature implies
providing a new set of templates for these continuous read
operations. The core will automatically pick the fastest variant,
depending on the hardware capabilities.

[ns: Had to be adapted for 6.18.31]
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
(cherry picked from commit 6eb7c19)
Continuous reads are a way to read big chunks of data without having to
issue a page read command for each page. There are two limitations to
this feature: the OOB area is no longer accessible, and it is not
possible to cross die boundaries.

Winbond chips ignore the address bytes during continuous reads, and
because the dummy cycles are enough they indicate dropping the address
cycles from the continuous read from cache variants. This is very poorly
supported by SPI controller drivers which are "wired" to always at least
provide the column. Keep using address cycles, but reduce the number of
dummy cycles accordingly.

[ Only the register defines and the continuous read from cache operation
  templates are taken. The W35NxxJW chip entries and the changes around
  them are dropped: they depend on SPINAND_INFO_VENDOR_OPS(),
  winbond_w35_ops and the bus interface parameter of the chip
  configuration callback, none of which exist in this tree, and on
  w25w35nxxjw_ecc_get_status() which is only used by those entries. The
  templates themselves apply unchanged and are what the W25N08LW entry
  needs. ]

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
(cherry picked from commit 5e85bff62bccf07e5bc4b0b39d0e0e0a1b1e46e9)
As for the W35NxxJW family, add support for W25N{01,02}JW continuous
read support. Similar operations require to be done, such as setting a
specific bit in a configuration register, and providing a set of read
variants without the address cycles.

As read from cache variants are badly supported by SPI memory
controllers, we create a new set of read from cache templates with a
fake address cycle and just enough dummy cycles. There are two
unsupported configurations (which would require 4.5 dummy bytes), so we
just do not provide them.

The same extra value in the ECC is possible as with the W35NxxJW family,
so we reference the same helper to retrieve the ECC status.

[ The w25n0xjw_op_needs_hs() and w25n0xjw_hs_cfg() changes are dropped:
  they take an enum spinand_bus_interface argument and read
  spinand->op_templates as a pointer, neither of which exists in this
  tree. The W25N{01,02}JW entries keep their existing ECC status helper,
  w25w35nxxjw_ecc_get_status() having been left out with the W35NxxJW
  entries. ]

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
(cherry picked from commit e1ff880)
Add support for the W25N08LW, a 1.8V 8Gbit SPI-NAND made of two
4Gbit LUNs, with 4096-byte pages and 256 bytes of spare area.

The chip reuses the KV ECC status helper, but needs its own OOB
layout because the geometry of its spare area differs from the
existing Winbond parts. Only half of it is visible while the
internal ECC is enabled, so the ECC region is reported as
inaccessible and just the free bytes are exposed.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Commit af2792a ("mtd: spi-nor: sfdp: get the 1-1-8 and 1-8-8
protocol from SFDP") taught the core to discover octal read support
from BFPT, but the 4-Byte Address Instruction Table parser was never
extended accordingly.

Parse the 1-1-8 and 1-8-8 page program bits of 4BAIT DWORD1 and set the
corresponding 4-byte opcodes, so that octal writes stay available once
the flash switches to the 4-byte address instruction set.

This is in preparation of adding support for the ISSI IS25WX01G, a
1 Gbit octal flash which is beyond the 3-byte address range and
advertises 4-byte 1-1-8 and 1-8-8 page program instructions.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Signed-off-by: Michael Walle <mwalle@kernel.org>
Add support for the ISSI IS25WX01G, a 1 Gbit octal NOR flash. The part
is fully described by SFDP, so only the flash ID and two BFPT fixups are
needed.

The flash has no Status Register 2 and does not implement the 35h Read
Configuration Register command, so the default assumption of a 16-bit
Write Status command does not hold. Additionally, its BFPT Quad Enable
Requirement field carries a reserved value, which makes
spi_nor_parse_bfpt() keep the manufacturer default quad enable method;
clear it, since this is an octal-only part with no quad mode at all.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
The MISCREG register file holds the reset lines of the two xSPI
controllers, including their PHYs, and the soft resets of the two
CAN-FD controllers. Add a reset controller for them so that those
peripherals can be reset through the reset framework. It has no
register range of its own and operates on the register map of the
parent MISCREG syscon.

None of these lines is self-deasserting, so .reset() emulates a pulse
in software the way reset-simple does. As the minimum pulse width is
not documented, a conservative delay is used.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from fcbb478 to 6adafd1 Compare September 23, 2026 13:18
xhackerustc and others added 4 commits September 23, 2026 14:18
The cdns xspi controller slave dma interface may support wider data
width. Wider I/O width can benefit performance. We can know the width
by checking the CTRL_FEATURES_REG's DMA_DATA_WIDTH bit, 0 means 32bit
1 means 64bit.

A simple test with QSPI nor flash on one arm64 platform:

Use 8bit slave dma data width (now):
 # dd if=/dev/mtdblock0 of=/dev/null bs=8192 count=1000
 1000+0 records in
 1000+0 records out
 8192000 bytes (7.8MB) copied, 1.368735 seconds, 5.7MB/s

Use 32bit slave dma data width:
 # dd if=/dev/mtdblock0 of=/dev/null bs=8192 count=1000
 1000+0 records in
 1000+0 records out
 8192000 bytes (7.8MB) copied, 1.088787 seconds, 7.2MB/s

Improved by 26.3%!

Use 64bit slave dma data width:
 # dd if=/dev/mtdblock0 of=/dev/null bs=8192 count=1000
 1000+0 records in
 1000+0 records out
 8192000 bytes (7.8MB) copied, 0.831104 seconds, 9.4MB/s

Improved by 64.9%!

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Link: https://patch.msgid.link/20260602235825.28614-1-jszhang@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 4954d4e)
The driver used a mrvl_hw_overlay boolean in the driver data to decide,
at several points in the common probe path, whether the Marvell
integration specifics had to be applied. Adding another integration
would mean adding more of these conditionals.

Turn the driver data into a set of per-compatible operations instead,
including an optional init() callback for vendor specific
initialization. The probe path now just assigns these and calls init()
if present.

The Marvell XFER register mapping, clock setup and PHY configuration
move into such an init() callback. Since the PHY timing values were only
ever the Marvell ones, drop them from the driver data and write the
constants directly, and rename the helper to
cdns_mrvl_xspi_configure_phy() to make that explicit.

No functional change intended.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Add driver data for the Analog Devices SC846 integration of the Cadence
XSPI controller. It uses the generic Cadence memory operations and
handlers, and only needs an init() callback programming the SC846
specific PHY settings before resetting the DLL.

Waiting for the DLL to lock is done on the PHY DLL observable register
rather than on the register used by the Marvell path, as that is what is
documented for this platform.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Rename the sdma_error flag to xfer_error. No functional change.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
@nunojsa

nunojsa commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator Author

Should be ready for review now! Note lots of patches are just cherry-picks mainly to allow support for NAND continuous reads which is where most of the performance is gained!

@gastmaier

Copy link
Copy Markdown
Collaborator

Added cadence xspi arm exception:
50cf580

@nunojsa
nunojsa force-pushed the adsp-6.18.y/staging/sc846-support-xspi branch from 6adafd1 to 67fae9a Compare September 25, 2026 09:10
Add auto command (ACMD) mode with the controller's internal DMA master
for bulk reads above CDNS_XSPI_ACMD_MIN_BYTES. Smaller reads and all
other operations stay on STIG.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
The clocks node claims a fourth register range at 0x310a9000, which is
the MISCREG integration register file and not a clock generation
block. The driver only ever maps the first three ranges (CGU0, CGU1
and CDU), so drop it and let the region be described by its own node.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Add the xSPI0 controller node and describe the octal SPI NOR flash on
SC846 SOM.

The plain read opcode is only rated to ~50MHz on this device, hence
m25p,fast-read is required at 125MHz which is the clock configured
during boot.

While at it, rename the pinctrl group named spi0_default. It describes
the xSPI0 pins (PD_10-PD_15, PE_00-PE_06); SPI0 is on port C. The group
had no user, so rename it to xspi0_default and sort the pins by signal,
no functional change. The node name is also made hyphenated to follow
the usual pin group naming.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
The EZ-KIT routes the same OCTAL SPI NOR device as the SOM to the second
xSPI controller. Describe the controller, pinmux, and board flash.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>
The SC846 SOM has a NOR flash on xSPI0 and the EZ-KIT carrier adds a
SPI-NAND on xSPI1.

Enable the Cadence xSPI controller driver together with the SPI-NAND
layer for the EZ-KIT part. The xSPI nodes reference a reset line
provided by the MISCREG reset controller.

Signed-off-by: Nuno Sá <nuno.sa@analog.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sc846 Support for the ADSP-SC846 xspi Support for the ADSP-SC846 XSPI controller

Projects

Status: In Development

Development

Successfully merging this pull request may close these issues.

6 participants