Lemans spinor bringup - #132
Open
vandhiadevan wants to merge 14 commits into
Open
Conversation
Add a DM_SPI driver for the SPI-protocol personality of the Qualcomm GENI Serial Engine, found inside a QUPv3 wrapper on Qualcomm SoCs such as SDM845, SM8250 and SA8775P. The Serial Engine is shared across UART/I2C/SPI protocols and needs firmware for the desired protocol loaded into it before use, via the existing qcom_geni_load_firmware() helper. The driver supports both the CPU-driven FIFO transfer path and the Serial Engine's own DMA engine (SE-DMA). Whether FIFO mode is usable is read back from hardware (GENI_IF_DISABLE_RO); SE-DMA is always available. The driver picks FIFO for small transfers when FIFO is available, and SE-DMA otherwise, matching the mode-selection logic of the equivalent Linux driver. Add the register offsets and the fifo-depth helper needed by the new driver to the shared include/soc/qcom/geni-se.h, and wire up the new driver's Kconfig entry and Makefile rule. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
load_se_firmware() derives the RX_RFR_WATERMARK value from
QUPV3_SE_HW_PARAM_1 using RX_FIFO_WIDTH_BIT/RX_FIFO_WIDTH_MASK, which
decode the RX FIFO element width (bits per FIFO word), not its depth
(number of entries). The watermark register expects a depth-based
threshold, so this produces an incorrect watermark value and, on QUP
HW versions >= 3.10 where the depth field widened to 8 bits for
256-byte-deep FIFOs, an inconsistent one depending on core revision.
This mirrors geni_i2c_get_tx_fifo_depth() in drivers/i2c/geni_i2c.c,
which already reads SE_HW_PARAM_0 with the HW-version-gated
TX_FIFO_DEPTH_MSK/TX_FIFO_DEPTH_MSK_256_BYTES masks for the same
reason on the TX side.
The same depth-vs-width distinction, and the HW-version gating for
QUP HW >= 3.10, was introduced upstream in Linux by commit
fe8aa1ba0783 ("soc: qcom: geni-se: Update Tx and Rx fifo depth based
on QUP HW version"). The Linux driver this file's firmware-loading
sequence was ported from, added by commit d4bf06592ad6 ("soc: qcom:
geni-se: Add support to load QUP SE Firmware via Linux subsystem"),
computes the RX_RFR_WATERMARK value via geni_se_get_rx_fifo_depth()
which applies that same depth mask -- confirming this is a porting
bug rather than an intentional difference.
Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
mtd_blk_probe() never initializes bdesc->lba, so every MTD block device reports a block count of zero regardless of the underlying MTD device's actual size. This makes MTD block devices unusable for partition table (GPT/MBR) scanning, since partition code relies on lba to know the device's extent. Set lba from the MTD device's size and the block descriptor's blksz, mirroring how other block drivers populate this field during probe. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Add struct spi_flash_blk_plat, which will hold the struct mtd_info pointer that mtd_bind() requires when binding a SPI-NOR device into the MTD block subsystem. Forward-declare struct mtd_info since this header doesn't otherwise need the full MTD definitions. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Wire jedec_spi_nor into the existing mtd_bind() mechanism so a SPI-NOR device gets a block device usable for partition (GPT/MBR) scanning, same as NAND/eMMC-backed MTD devices. mtd_bind() defaults to a 512-byte sector and the native MTD partition scheme (mtdparts=), which suits NAND/eMMC but not NOR: NOR is commonly GPT-partitioned, and sub-erase-block writes require a read-modify-erase-write cycle anyway, so partition images for NOR are built using the erase-block size as the logical sector. Rather than teaching mtd_bind() about NOR specifics, override blksz (from optional DT property nor-blk-size, else the flash's erase size), log2blksz, lba and part_type on the resulting block device after binding. No changes to mtd_bind()'s signature or behavior for existing callers. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
blk_get_devnum_by_uclass_idname() rejected any block device whose parent's uclass differs from the uclass being looked up. This breaks lookup for MTD block devices created via mtd_bind(): their parent is the underlying storage device (e.g. UCLASS_SPI for SPI-NOR), but the block device itself declares uclass_id = UCLASS_MTD. Also accept a match against the block descriptor's own uclass_id, so such devices can still be found via interface name (e.g. "mtd"). Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Add fastboot_block_set_target() so an OEM command can point the generic block fastboot backend at a different interface/device at runtime, without requiring a rebuild. Falls back to the existing build-time CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME/ CONFIG_FASTBOOT_FLASH_BLOCK_DEVICE_ID defaults when no override is set. Expose this to fastboot clients via a new "oem set-block-target <interface> [device]" command, gated behind CONFIG_FASTBOOT_CMD_OEM_SET_BLOCK_TARGET (depends on CONFIG_FASTBOOT_FLASH_BLOCK). This is needed to target storage devices, such as SPI-NOR exposed through the MTD block uclass, that aren't known until runtime or that coexist with another default block interface on the same board. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Add an "oem spi-nor-init" fastboot command that removes the default SPI flash device and reprobes it, mirroring the remove+re-probe pattern already used by fastboot_spi_flash_probe() in fb_spi_flash.c. This lets the driver's own probe() perform any bring-up it needs (e.g. loading firmware). Some SoCs load SPI-NOR firmware from storage in a single bulk pass at boot, before a bare reprobe of the SPI flash device is enough to pick it up (e.g. if the firmware source wasn't available yet at that point). To let such platforms redo that one-time, driver-external step here without hardcoding any vendor-specific call into generic fastboot code, add a weak fastboot_oem_spi_nor_reinit() hook that is called between the removal and the reprobe. The default implementation is a no-op; SoC-specific code may override it. This is useful on boards where the SPI flash device is not usable until fastboot has flashed something it depends on, such as firmware or configuration data. It is intended to be used together with "oem set-block-target" once the device has been brought up. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
qcom_geni_fw_initialise() runs once, at EVT_LAST_STAGE_INIT, and reads GENI SE firmware from a dedicated storage partition into memory for its children to pick up during their own probe(). If that partition does not exist yet at that point (e.g. first boot, before fastboot has flashed it), it finds nothing to load and does not retry later. A later bare SPI-NOR reprobe cannot recover from that on its own, since the SPI driver's probe() only re-reads firmware already cached by qcom_geni_fw_initialise(); it does not re-read storage itself. Override the fastboot_oem_spi_nor_reinit() hook to re-run qcom_geni_fw_initialise(), so that "fastboot oem spi-nor-init" can pick up firmware that has been flashed since boot before reprobing the SPI-NOR device. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Add the clock RCG, gate bit definitions, and frequency table needed to enable and configure the SE0 (SPI) serial engine clock on QUPv3 wrapper 3, GCC_QUPV3_WRAP3_S0_CLK. This is required to bring up the GENI SPI controller on QUPv3 wrapper 3, e.g. for SPI-NOR flash attached to that wrapper. Also add the wrapper's M-AHB/S-AHB clock gates and the QSPI/AGGRE-NOC gates that must be enabled alongside the SE0 clock. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Wire up the QUPv3 wrapper 3 / SPI21 GENI SPI controller and its clock/pinctrl dependencies so the SPI-NOR flash on the LeMans EVK can be probed in U-Boot proper. Mark GCC, RPMH clock controller, Apps RSC, TLMM and QUPv3 wrapper 3 as bootph-all so they remain bound prior to relocation, add the SPI21 pinctrl state, set the SE0 clock to 48 MHz via assigned-clocks on GCC, and drop the power-domain/DMA properties on SPI21 that are not usable prior to relocation. Add a jedec,spi-nor flash child node and an spi0 alias for the SPI-NOR flash. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
Turn on the GENI/QUPv3 wrapper-3 SPI-NOR stack and the fastboot
runtime block-target override that this branch already implements,
using the existing qcom_lemans_snagboot_defconfig rather than adding
a new one:
- CONFIG_OF_UPSTREAM plus CONFIG_QCOM_COMMAND_DB for RPMH clock
resource lookups
- CONFIG_IOMMU / CONFIG_QCOM_HYP_SMMU so the QUP3 GENI SE-DMA stream
is routed through the hypervisor-backed SMMU instead of silently
faulting
- DM_SPI / SPI_GENI_QCOM, DM_SPI_FLASH / SPI_FLASH_MTD and the MTD
block layer for SPI-NOR on QUPv3 wrapper 3, SE0
- the broader SPI-NOR vendor set from drivers/mtd/spi/Kconfig
(Atmel, Dosilicon, EON, GigaDevice, ISSI, Macronix, Puya, Silicon
Kaiser, Spansion, STMicro, SST, Winbond, XMC, XTX, ZBIT), instead
of Macronix alone
- FASTBOOT_CMD_OEM_SET_BLOCK_TARGET / FASTBOOT_CMD_OEM_SPI_NOR_INIT
so fastboot can switch its block backend from the snagboot
default ("scsi") to "mtd" at runtime, once SPI-NOR has probed
Validated with a full build for lemans-evk (qcom_lemans_snagboot_defconfig),
confirming qcom_geni_spi.o, sf_probe.o, mtdblock.o and fb_block.o all
compile and link into u-boot.bin.
Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
…are() qcom_geni_load_firmware() unconditionally dereferences the firmware blob pointer cached in the GENI wrapper's private data (dev_get_priv(dev->parent)) without checking it for NULL. qcom_geni_fw_initialise() only populates that private data when it successfully locates and reads the dedicated QUP firmware partition at EVT_LAST_STAGE_INIT. If no such partition exists yet - e.g. a board with no MMC/UFS storage and an unprovisioned SPI-NOR, before any image has been flashed - it prints "QUP firmware partition not found" and returns without ever setting the wrapper's private data, leaving it NULL. Any later probe of a GENI peripheral (SPI/I2C/UART) whose firmware is not yet loaded on that hardware instance then calls qcom_geni_load_firmware(), which dereferences the NULL pointer and crashes with a synchronous abort/data abort. Add a NULL check and fail gracefully with -ENOENT, matching how the SPI caller already handles a nonzero return from this function. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
write_mbr_and_gpt_partitions() calls part_init() after writing the GPT to re-detect the partition table, but part_init() takes a fast path when desc->part_type is already cached: it only re-validates the existing driver's test() instead of re-scanning all partition drivers. On SPI-NOR/MTD block devices, part_type is cached as PART_TYPE_MTD from the initial probe, since the MTD partition driver's test() unconditionally matches. When fastboot subsequently writes a GPT to SPI-NOR (e.g. via 'gpt write'), the post-write part_init() call keeps reusing the stale MTD type instead of detecting EFI, so 'part list mtd 0' reports "Partition Type: MTD" with no partitions until an unrelated full reprobe (e.g. 'sf probe') resets part_type and forces a re-scan. Reset part_type to PART_TYPE_UNKNOWN before the post-write part_init() call so it always performs a full re-scan and correctly detects EFI immediately. Signed-off-by: Vandhiadevan Karunamoorthy <vandhiadevan.karunamoorthy@oss.qualcomm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title: arm64: lemans: Enable SPI-NOR flash support and fastboot GPT flashing
Summary
depth vs width bug, and add SA8775p QUPv3-wrapper-3 SPI clock support.
blk_desc lba fix, plat data struct) and allow blk uclass lookup by a
device's own uclass_id.
and geni firmware reinit support, to flash SPI-NOR over fastboot.
clocks, jedec,spi-nor flash node, spi0 alias) and enable it in the
snagboot defconfig.
partition-type re-detection after a fastboot GPT write to SPI-NOR
(previously showed "Partition Type: MTD" until a manual
sf probe).Test plan
qcom_lemans_snagboot_defconfig (SWIV + qtestsign tz flow).
part list mtd 0reports
Partition Type: EFIwith partitions visible immediatelyafter GPT write (no
sf probeworkaround needed).clock-driver changes.