Hi Igor,

On 2026-10-27T05:57:26, Igor Velkov via B4 Relay
<[email protected]> wrote:
> cmd: sf: Probe a flash at the requested speed
>
> 'sf probe <bus>:<cs> <speed>' ignores the speed for a flash that has a
> device tree node: the probe, and with it the JEDEC ID read, runs at
> spi-max-frequency, and the requested speed reaches the controller only
> after it.
>
> On ROCK Pi 4A the device tree sets spi-max-frequency = <108000000> and
> the flash does not answer at the resulting clock, at any requested
> speed:
>
>   => sf probe 1:0 1000000
>   jedec_spi_nor flash@0: unrecognized JEDEC id bytes: ff, ff, ff
>
> Before the probe, set the requested speed in the platform data of the
> device, as _spi_get_bus_and_cs() already does for a device it binds
> without a device tree node, and restore the saved value right after it,
> so the platform data ends up unchanged. slave->mode keeps the device
> tree value. A speed above spi-max-frequency is honoured, as it already
> is after the probe. Only sf probe with an explicit speed changes: sf
> [...]
>
>  cmd/sf.c     | 11 +++++++++++
>  test/dm/sf.c | 29 +++++++++++++++++++++++++++++
>  2 files changed, 40 insertions(+)

> diff --git a/cmd/sf.c b/cmd/sf.c
> @@ -146,7 +146,18 @@ static int do_spi_flash_probe(int argc, char *const 
> argv[])
> +             struct dm_spi_slave_plat *plat = NULL;
> +             uint saved_max_hz = 0;
> +
> +             /* Probe at the requested speed: the flash reads its ID there */
> +             if (!ret && speed) {
> +                     plat = dev_get_parent_plat(new);
> +                     saved_max_hz = plat->max_hz;
> +                     plat->max_hz = speed;
> +             }
>               flash = spi_flash_probe(bus, cs, speed, mode);
> +             if (plat)
> +                     plat->max_hz = saved_max_hz;

This works, but the command now reaches into the SPI uclass's
per-child platform data, which spi_slave_of_to_plat() normally owns.
It also relies on spi_child_pre_probe() copying plat->max_hz into
slave->max_hz, so please can you move this into a helper in
spi-uclass.c, or a variant of spi_flash_probe(), so the command
doesn't depend on those internals? Other callers can keep their
current behaviour.

The mode has the same problem: _spi_get_bus_and_cs() sends the
requested mode to the controller, but the next dm_spi_claim_bus()
restores slave->mode, so 'sf probe 1:0 1000000 3' quietly ignores the
3 for a DT flash. It would be worth handling the mode in the same way,
or at least saying in the commit message why it is left alone. What do
you think?

Regards,
Simon

Reply via email to