U-Boot SPI DM framework issues

Hi,
while trying to debug some nasty SPI flash issue on sunxi, I came across some oddities in the SPI DM framework, and wanted to check some things, since I am not sure whether I miss things here:
- When I do a simple "sf probe" call, I see *two* calls to the .claim_bus callback: the first one from: drivers/mtd/spi/sf_probe.c:spi_flash_probe_slave(), which is expected, but then also, shortly afterwards, a second call from: drivers/spi/spi-mem.c:spi_mem_exec_op(). After the probe operation finished, I see the corresponding two spi_release_bus() calls. Seeing *two* claim calls in that nested way looks rather odd, and the name *claim* sounds like it should be only one slave device/driver being able to, well, claim the bus. From digging through the code it looks like we call spi_mem_exec_op() only from *inside* drivers that already claimed the bus, so shall we drop the call inside spi_mem_exec_op()? Allowing those nested calls has some consequences for the implementation of .claim_bus in the controller drivers, as it does not sound indicated to enabled/disable hardware in there. Enabling clock gates *again* might not be harmful per se, but if the first .release_bus call already disables clocks and resets, this might cause problems.
- In many controller drivers I see the .of_to_plat implementation checking for a "spi-max-frequency" property in the *controller's* DT node, mostly with a fallback value, and using that frequency as an upper bus frequency limit for the whole controller operation. But looking at the official DT bindings, this property is supposed to be a *slave device* property, and indeed checking a few dozen .dts file I see it only being used in *child* nodes of SPI controllers, never in controller nodes. There is some proper usage in drivers/spi/spi-uclass.c:spi_slave_of_to_plat(), but to me it looks like the bus node code is wrong and should be removed, from the other invocation in spi-uclass.c and all the controller drivers. For sunxi (and probably others) this has the consequence of limiting the whole bus to some "default" frequency limit, which is rather low: #define SUN4I_SPI_DEFAULT_RATE 1000000 plat->max_hz = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", SUN4I_SPI_DEFAULT_RATE); So we never go beyond this 1 MHz, even though the SPI flash chips explicitly advertise 40MHz or more in their child nodes.
Please let me know if I am missing something here! If not, I am happy to send some patches aiming at fixing those things.
Cheers, Andre

Hi Andre,
On Mon, 11 Jul 2022 at 09:52, Andre Przywara andre.przywara@arm.com wrote:
Hi,
while trying to debug some nasty SPI flash issue on sunxi, I came across some oddities in the SPI DM framework, and wanted to check some things, since I am not sure whether I miss things here:
When I do a simple "sf probe" call, I see *two* calls to the .claim_bus callback: the first one from: drivers/mtd/spi/sf_probe.c:spi_flash_probe_slave(), which is expected, but then also, shortly afterwards, a second call from: drivers/spi/spi-mem.c:spi_mem_exec_op(). After the probe operation finished, I see the corresponding two spi_release_bus() calls. Seeing *two* claim calls in that nested way looks rather odd, and the name *claim* sounds like it should be only one slave device/driver being able to, well, claim the bus. From digging through the code it looks like we call spi_mem_exec_op() only from *inside* drivers that already claimed the bus, so shall we drop the call inside spi_mem_exec_op()? Allowing those nested calls has some consequences for the implementation of .claim_bus in the controller drivers, as it does not sound indicated to enabled/disable hardware in there. Enabling clock gates *again* might not be harmful per se, but if the first .release_bus call already disables clocks and resets, this might cause problems.
In many controller drivers I see the .of_to_plat implementation checking for a "spi-max-frequency" property in the *controller's* DT node, mostly with a fallback value, and using that frequency as an upper bus frequency limit for the whole controller operation. But looking at the official DT bindings, this property is supposed to be a *slave device* property, and indeed checking a few dozen .dts file I see it only being used in *child* nodes of SPI controllers, never in controller nodes. There is some proper usage in drivers/spi/spi-uclass.c:spi_slave_of_to_plat(), but to me it looks like the bus node code is wrong and should be removed, from the other invocation in spi-uclass.c and all the controller drivers. For sunxi (and probably others) this has the consequence of limiting the whole bus to some "default" frequency limit, which is rather low: #define SUN4I_SPI_DEFAULT_RATE 1000000 plat->max_hz = fdtdec_get_int(gd->fdt_blob, node, "spi-max-frequency", SUN4I_SPI_DEFAULT_RATE); So we never go beyond this 1 MHz, even though the SPI flash chips explicitly advertise 40MHz or more in their child nodes.
Please let me know if I am missing something here! If not, I am happy to send some patches aiming at fixing those things.
This all sounds right to me and patches are welcome.
Re the first issue, I suspect something went haywire with the spimem conversion.
For the second, the binding predates Linux (I think?) so it would be good to tidy this up.
Regards, Simon
participants (2)
-
Andre Przywara
-
Simon Glass