2019-11-07 09:51 AM
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 -j
I 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.ubi
I 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: 0x0
And 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?
2019-11-08 08:31 AM
Hi @AMurr.2282
> You can see on line 525 the relevant FMC block. I copy/pasted most of it from stm32mp157c-dk2.dts.
I presume you mean stm32mp157c-ev1.dts since there is no nand device on dk2 right ?
Can you please share nand device reference on your design ? Is it 8 or 16 bits ?
Thx,
Olivier
2019-11-08 09:43 AM
Hi @Community member
Yes sorry, it was stm32mp157c-ev1.dts, not stm32mp157c-dk2.dts.
The exact nand device I'm using is MT29F4G08ABAEAH4-ITS:E TR. It has 8 bits.
2019-11-15 04:52 AM
Well, after much debugging and comparing DT source files with other boards, we have found the problem. And it was quite a silly problem.
The default pin config from CubeMX does not enable the internal pull-up resistor on the FMC_NWAIT pin. In the getting started guide section 10.1.10 it's hinted at:
So a heads up: Make sure you enable this option:
Or set bias-pull-up; in the DT source:
fmc_pins_mx: fmc_mx-0 {
u-boot,dm-pre-reloc;
pins1 {
u-boot,dm-pre-reloc;
pinmux = <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
<STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
<STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
<STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
<STM32_PINMUX('D', 11, AF12)>, /* FMC_CLE */
<STM32_PINMUX('D', 12, AF12)>, /* FMC_ALE */
<STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
<STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
<STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
<STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
<STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
<STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
<STM32_PINMUX('G', 9, AF12)>; /* FMC_NCE */
bias-disable;
drive-push-pull;
slew-rate = <1>;
};
pins2 {
u-boot,dm-pre-reloc;
pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
bias-pull-up;
};
};
Why the R/W addresses and chip counts are still 0 is unknown. Apparently that's ok?