Issue with spi-uclass.c and mxc_spi.c when DM_SPI_FLASH is enabled
koute102030 at gmail.com
Tue Feb 1 13:31:27 CET 2022
Recently I've been working on the upgrade of an old u-boot to u-boot2020,
and I encountered an issue when I enabled DM_SPI and DM_SPI_FLASH ! My
board (based on IMX6) uses a NOR flash SPI to store the u-boot environment
and the SPI interface is initialized early in boot.
Using the mxc_spi.c as a SPI driver for my IMX6 soc, after I enabled the
two configs above I got a data abort !
after thorough analysis and backtracking, i found the origin of the data
abort (access to invalid memory region) which is in the function below from
NXPs driver mxc_spi.c:
static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs)
struct udevice *dev = mxcs->dev;
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
u32 cs = slave_plat->cs;
if (mxcs->gpio > 0)
In this function the logic in activating the cs (chip select) is by getting
the pin from the platdata of the device's parent and enabling it, as any DM
driver would do.
However, This function expects that the cs number from platdata
(slave_plat->cs in above code) corresponds to the position of the gpio
tuple in the "cs-gpios" property from the FDT (e.g. tuple position in :
cs-gpios = <&gpio1 0 0>, <0>, <&gpio1 1 0>, <&gpio1 2 0>;) and not the
actual number of the cs gpio pin. But the issue is that what it gets from
the platdata is the latter i.e. the cs gpio pin number ! And in my case the
actual number of the cs gpio pin is 120 (GPIO4_IO24) which results in
accessing the mxcs->cs_gpios knowing that the size of the table is
only 4 ! which in turn leads to a data abort !
I'm mentioning that this issue is related also to spi_uclass.c, because,
from what I could understand by reading the source code, the platdata for
the device is not initialized properly ! the function
spi-uclass.c/spi_slave_ofdata_to_platdata() responsible for initializing
correctly the platdata from the values in the FDT, is never called !
because the "node" udevice property is null for the device, and node=null
is set when binding the device to the driver via the function
device_bind_driver() and never filled afterwards.
I would like to know if there is an issue about this in either drivers, or
I'm missing something in the code ?
Any help is greatly appreciated !
More information about the U-Boot