Hi all,
We are running NXP's Linux 5.4.24_2.1.0 release on a custom i.MX6ULL board. We have an SPI-NOR flash device connected to ECSPI1 and use the #CS line as GPIO. From DTS point of view it looks like:
/* Recovery flash */
&ecspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
status = "okay";
cs-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;
flash@0 {
address-cells = <1>;
size-cells = <1>;
reg = <0>;
compatible = "jedec,spi-nor";
spi-max-frequency = <12500000>;
status = "okay";
partition@0x00000000 {
label = "recovery_boot";
reg = <0x00000000 0x00100000>;
};
partition@0x00100000 {
label = "recovery_fw";
reg = <0x00100000 0x00680000>;
};
partition@0x00780000 {
label = "factory_data";
reg = <0x00780000 0x00080000>;
};
};
};
pinctrl_ecspi1: ecspi1grp-1 {
fsl,pins = <
MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x10b0
MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x10b0 /* CS# */
MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x10b0
MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x10b0
>;
};
This does not work during boot, and we found out the CS pin is not being pulled low during a read of the flash chip. After a lot of digging is seems the kernel is trying to drive the GPIO, but it just doesn't do anything.
We dug around in the GPIO driver (gpio-mmio.c) to find what it is actually trying to do, but it seems the GPIO driver is in some sort of limbo state at the moment the SPI driver is trying to toggle the CS GPIO. When it tries to set the i.MX6ULL GPIO registers, the value written to the registers is not actually going into these registers. We tested this by setting the GPIO_GDIR register to 0x00000000 (all input) for the used bank from U-Boot, boot Linux and check the register value again (via /dev/mem). As you can see with my added debug prints, after kernel boot, the SPI driver should have set the GDIR register (offset 0x04) to 0x04000000:
But after reading the register after boot using /dev/mem, it didn't actually set the register:
We have no idea why this happens. We did find it to be heavily influenced by the order of initialization of the SPI devices. The SPI subsystem is setup in a way that when an SPI controller is registered, the SPI devices connected to this controller (in this case the spi-nor device) are immediately initialized during the SPI controller probe. When we delay the device register until the controller probe has been finished, everything is fine, CS works and the NOR flash device is working fine. We tested this by compiling both spi-imx.c and spi-nor.c as modules and inserting them after boot. we found:
insmod spi-nor.ko && insmod spi-imx.ko
results in the same failure as shown above.
insmod spi-imx.ko && insmod spi-nor.ko
works fine, as the spi device is registered and initialized _after_ the spi_imx probe is fully completed.
We have no idea what is going on or how to fix this behavior. Has anyone seen this before? How did you fix it?
Some additional notes and research we already did:
Thanks for the help!
Hello,
Have you find a workaround ?
I'm in the same case with my iMX6ULL board.
Kind regards