Issue with mxc_spi.c when DM_SPI_FLASH is enabled. u-boot-imx v2020

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issue with mxc_spi.c when DM_SPI_FLASH is enabled. u-boot-imx v2020

733 Views
Abder
Contributor II
Hi everyone,

Recently I've been working on the upgrade of an old u-boot-imx to u-boot-imx v2020, 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)
{
#if CONFIG_IS_ENABLED(DM_SPI)
   struct udevice *dev = mxcs->dev;
   struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev);
   u32 cs = slave_plat->cs;
   if (!dm_gpio_is_valid(&mxcs->cs_gpios[cs]))
      return;
   dm_gpio_set_value(&mxcs->cs_gpios[cs], 1);
#else
   if (mxcs->gpio > 0)
      gpio_set_value(mxcs->gpio, mxcs->ss_pol);
#endif
}
 
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[120] knowing that the size of the table is only 4 ! which in turn leads to a data abort !

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 !
 
Thank you
--
Abder
Tags (1)
0 Kudos
3 Replies

708 Views
jimmychan
NXP TechSupport
NXP TechSupport

Which version of Yocto BSP are you using?

Do you set the pinmux setting for the gpio pin?

 

e.g. in this u-boot imx6qdl-sabresd.dtsi, there is cs-gpios setting under the node &ecspi1.

https://source.codeaurora.org/external/imx/uboot-imx/tree/arch/arm/dts/imx6qdl-sabresd.dtsi?h=imx_v2...

 

in this example, it use the gpio4_io09

cs-gpios = <&gpio4 9 0>;

 

And the pinmux setting of the gpio pin under pinctrl_ecspi1.

MX6QDL_PAD_KEY_ROW1__GPIO4_IO09           0x1b0b0

 

0 Kudos

703 Views
Abder
Contributor II

Hi Jimmychan,

am using Yocto dunfell for my build.

and the issue is not in the pin muxing for the cs pin, because that is correctly set in my DTB. In fact, if I replace mxcs->cs_gpios[cs] by mxcs->cs_gpios[0] in above code, everything works fine ! but that should be the value of the cs variable automatically... The slave_plat->cs should return the number 0 as am defining only one cs gpio in the DTB e.g. cs-gpios = <&gpio4 24 0>;.

Best regards
--
Abder

0 Kudos

678 Views
jimmychan
NXP TechSupport
NXP TechSupport

i.MX6Q SabreSD board and the u-boot version rel_imx_5.4.70_2.3.2. We don't meet the issue. It should not be a driver problem. Please double check the dts compare with the SabreSD board.

https://source.codeaurora.org/external/imx/uboot-imx/tree/arch/arm/dts/imx6q-sabresd.dts?h=rel_imx_5...

 

Log from i.MX6Q SabreSD board:

U-Boot 2020.04-dirty

CPU: i.MX6Q rev1.2 996 MHz (running at 792 MHz)
CPU: Extended Commercial temperature grade (-20C to 105C) at 44C
Reset cause: POR
Model: i.MX6 Quad SABRE Smart Device Board
Board: MX6-SabreSD
DRAM: 1 GiB
dev m25p80@0 spi_child_post_bind
spi_slave_ofdata_to_platdata cs 0

Normal Boot
Hit any key to stop autoboot: 0
=>
=> sf probe
spi_find_bus_and_cs: No bus 0
spi_find_chip_select: plat=4df6c480, cs=0
mxc_spi_cs_activate m25p80@0 cs 0
SF: Detected m25p32 with page size 256 Bytes, erase size 64 KiB, total 4 MiB
spi_get_bus_and_cs: bus=4df6c318, slave=4df75d08

0 Kudos