Re: [PATCH] spi: Handle spi-{tx,rx}-bus-width 0 as SPI_NO_TX/SPI_NO_RX
Quentin Schulz <[email protected]>
| Newsgroups | org.u-boot-project.lists.u-boot |
|---|---|
| Message-ID | <[email protected]> |
Hi Cole,
On 8/18/26 3:15 AM, Cole Munz wrote:
> The spi-peripheral-props binding shipped in dts/upstream allows a bus
> width of 0, meaning no RX or TX is possible on this device. The
> switches in spi_slave_of_to_plat() only handle 1/2/4/8, so a width of
> 0 falls through to the default case and warns "spi-rx-bus-width 0 not
> supported" on every boot, even though the devicetree is valid per the
> binding. The fact that the wire is missing is then dropped from
> plat->mode.
>
> Map 0 to new SPI_NO_TX/SPI_NO_RX mode bits, as Linux has done since
> v5.12 ("spi: Add SPI_NO_TX/RX support", mainline d962608ce218).
> Bits 16 and 17 are the first free mode bits.
>
> This comes up on devices with no MISO line at all, such as a
> write-only SPI display described with spi-rx-bus-width = <0>.
>
> Signed-off-by: Cole Munz <[email protected]>
> ---
> Raised as a boot-log warning on Flipper One, whose display has no MISO
> line at all: that pin is reused as the end-of-frame GPIO. Reported at
> flipperdevices/u-boot#33, and sent here rather than to the fork as
Please provide a full link next time, not everything is hosted on GitHub
so we wouldn't necessarily know where to look. I knew because I had at a
look at Flipper One's repos a few weeks ago and remembered. For
reference: https://github.com/flipperdevices/u-boot/issues/33
> suggested on that issue.
>
> Verified on sandbox at 527115ef6783, with spi-rx-bus-width = <0> added
> to spi.bin@0 in arch/sandbox/dts/test.dts and CONFIG_LOG disabled, so
> warn_non_xpl() reaches the console the way it does on the board.
>
> Before:
> $ ./u-boot -T -c "sf probe"
> spi-rx-bus-width 0 not supported
> spi-rx-bus-width 0 not supported
> SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB
>
> After:
> $ ./u-boot -T -c "sf probe"
> SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, 2 MiB
>
> It warns twice in sandbox because both the pre- and post-reloc DM scans
> run there; the board logs it once.
>
> ut dm spi_flash, spi_xfer, spi_find, spi_claim_bus, spi_set_wordlen and
> spi_flash_func all pass with the property in place. Nothing consumes the
> new bits yet, matching d962608ce218 in Linux, where the consumers landed
> later.
>
> drivers/spi/spi-uclass.c | 6 ++++++
> include/spi.h | 2 ++
> 2 files changed, 8 insertions(+)
>
> diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
> index 120565df1497..0f0d4b1384f2 100644
> --- a/drivers/spi/spi-uclass.c
> +++ b/drivers/spi/spi-uclass.c
> @@ -229,6 +229,9 @@ static int spi_child_post_bind(struct udevice *dev)
> /* Device DUAL/QUAD mode */
> value = dev_read_u32_default(dev, "spi-tx-bus-width", 1);
> switch (value) {
> + case 0:
> + mode |= SPI_NO_TX;
> + break;
> case 1:
> break;
> case 2:
> @@ -247,6 +250,9 @@ static int spi_child_post_bind(struct udevice *dev)
>
> value = dev_read_u32_default(dev, "spi-rx-bus-width", 1);
> switch (value) {
> + case 0:
> + mode |= SPI_NO_RX;
> + break;
> case 1:
> break;
> case 2:
> diff --git a/include/spi.h b/include/spi.h
> index 97096a775262..f477763bdc60 100644
> --- a/include/spi.h
> +++ b/include/spi.h
> @@ -34,6 +34,8 @@ struct spinand_info;
> #define SPI_RX_QUAD BIT(13) /* receive with 4 wires */
> #define SPI_TX_OCTAL BIT(14) /* transmit with 8 wires */
> #define SPI_RX_OCTAL BIT(15) /* receive with 8 wires */
> +#define SPI_NO_TX BIT(16) /* no transmit wire */
> +#define SPI_NO_RX BIT(17) /* no receive wire */
>
> /* Header byte that marks the start of the message */
> #define SPI_PREAMBLE_END_BYTE 0xec
So this is fine, but incomplete. We should really do:
[...]
struct dm_spi_slave_plat *plat = dev_get_parent_plat(dev);
if (din && (plat->mode & SPI_NO_RX))
return -EINVAL;
if (dout && (plat->mode & SPI_NO_TX))
return -EINVAL;
return ops->xfer(dev, bitlen, dout, din, flags);
in dm_spi_xfer(). To avoid calling xfer() with an invalid configuration.
This would then match the Linux kernel behavior (c.f. __spi_validate)
and avoid all SPI controller drivers having to implement logic to avoid
reading/writing on NO_RX/NO_TX devices.
It'd be nice to add tests to make sure this is handled properly (the
function returns -EINAL on invalid configuration).
Please send the spi-uclass.c and rk_spi.c in the same series (in
separate commits still, like you've done here), with a joined
cover-letter (the info you added to this patch and the Rockchip one is
good enough IMO).
Cheers,
Quentin