NAND Flash initialization hangs forever on custom board
Hello community
Problem in short:
The boot process hangs when U-Boot tries to load the stm32_fmc2_nand driver. Serial output can be found here:
I have designed and built a custom board using the STM32MP153AAC. The peripherals share a lot in common with the STM32MP157C-DK2 dev board (serial is also connected to uart4, PMIC is also connected to i2c4) so I used the STM32MP157C-DK2.dts device tree source file as reference for a lot of the changes I made to my own device tree source file.
My top-level dts can be found here. It was auto-generated by CubeMX and then manually edited here and there:
You can see on line 525 the relevant FMC block. I copy/pasted most of it from stm32mp157c-dk2.dts
My build process for U-Boot is:
# Get correct U-Boot source with STM32MP patches
git clone https://github.com/STMicroelectronics/u-boot
git checkout v2018.11-stm32mp
# Name of my device tree source file (see above)
export export DEVICE_TREE=stm32mp153a-raichu-cubemx-mx-u-boot
export CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH=arm
# Configure & Build
make stm32mp15_trusted_defconfig
make -jI previously built a linux distribution using Yocto Project, which generated the following flash layout file (.tsv):
#Opt Id Name Type IP Offset Binary
- 0x01 fsbl1-boot Binary none 0x0 tf-a-stm32mp153a-raichu-cubemx-mx-trusted.stm32
- 0x03 ssbl-boot Binary none 0x0 u-boot-stm32mp153a-raichu-cubemx-mx-trusted.stm32
P 0x04 fsbl1 Binary(2) nand0 0x00000000 tf-a-stm32mp153a-raichu-cubemx-mx-trusted.stm32
P 0x06 ssbl Binary nand0 0x00200000 u-boot-stm32mp153a-raichu-cubemx-mx-trusted.stm32
P 0x07 ssbl2 Binary nand0 0x00400000 u-boot-stm32mp153a-raichu-cubemx-mx-trusted.stm32
P 0x21 ubifs System nand0 0x00600000 st-image-tkrt-openstlinux-tkrt-stm32mp1-raichu-cubemx_nand_4_256_multivolume.ubiI manually replaced the file u-boot-stm32mp153a-raichu-cubemx-mx-trusted.stm32 in Yocto's deploy directory with the file produced by compiling U-Boot above, u-boot.stm32.
I then downloaded the TF-A and U-Boot images to the target device using STM32CubeProgrammer. TF-A works fine, it then loads and executes U-Boot, which then hangs at NAND initialization.
I manually added some additional printf() calls in the U-Boot source code to try and figure out where it gets stuck. You can see in the serial output (https://pastebin.com/VgJG6rSF) that it gets stuck while probing the stm32_fmc2_nand driver.
Further digging and many printf's later, I have found the exact place where it stops. nand_base.c:573:
static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo)
{
register struct nand_chip *chip = mtd_to_nand(mtd);
u32 time_start;
u32 current_time;
timeo = (CONFIG_SYS_HZ * timeo) / 1000;
time_start = get_timer(0);
printf("time_start: %d, timeo: %d\n", time_start, timeo);
while ((current_time= get_timer(time_start)) < timeo) {
printf("current_time: %d\n", current_time);
if ((chip->read_byte(mtd) & NAND_STATUS_READY))
break;
printf("read_byte() didn't return NAND_STATUS_READY\n");
WATCHDOG_RESET();
}
};chip->read_byte(mtd) calls:
uint8_t nand_read_byte(struct mtd_info *mtd)
{
printf("nand_read_byte()\n");
struct nand_chip *chip = mtd_to_nand(mtd);
return readb(chip->IO_ADDR_R);
}readb(chip->IO_ADDR_R) essentially reads a byte from address chip->IO_ADDR_R, and chip->IO_ADDR_R is a NULL-pointer.
You can see in the serial output some printf() functions that print the values of chip->IO_ADDR_R and chip->IO_ADDR_W:
chip->chip_size: 0
chip->IO_ADDR_R: 0x0
chip->IO_ADDR_W: 0x0And this is where I'm currently stuck. The device tree source in stm32mp157c.dtsi (included by my dts) provides the correct addresses:
fmc: nand-controller@58002000 {
compatible = "st,stm32mp15-fmc2";
reg = <0x58002000 0x1000>,
<0x80000000 0x1000>,
<0x88010000 0x1000>,
<0x88020000 0x1000>,
<0x81000000 0x1000>,
<0x89010000 0x1000>,
<0x89020000 0x1000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&mdma1 20 0x10 0x12000A02 0x0 0x0 0>,
<&mdma1 20 0x10 0x12000A08 0x0 0x0 0>,
<&mdma1 21 0x10 0x12000A0A 0x0 0x0 0>;
dma-names = "tx", "rx", "ecc";
clocks = <&rcc FMC_K>;
resets = <&rcc FMC_R>;
status = "disabled";
};In my dts I have:
&fmc{
u-boot,dm-pre-reloc;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&fmc_pins_mx>;
pinctrl-1 = <&fmc_sleep_pins_mx>;
status = "okay";
/* USER CODE BEGIN fmc */
#address-cells = <1>;
#size-cells = <0>;
nand: nand@0 {
reg = <0>;
nand-on-flash-bbt;
/*nand-ecc-mode = "none";*/
#address-cells = <1>;
#size-cells = <1>;
};
/* USER CODE END fmc */
};This all looks fine to me. Can someone help me understand why the R/W addresses and chip sizes are all 0?
