cancel
Showing results for 
Search instead for 
Did you mean: 

NAND Flash initialization hangs forever on custom board

AMurr.2282
Associate III

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:

https://pastebin.com/VgJG6rSF

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:

https://pastebin.com/pUJsdDzH

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?

3 REPLIES 3
Olivier GALLIEN
ST Employee

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

Olivier GALLIEN
In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.
AMurr.2282
Associate III

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.

AMurr.2282
Associate III

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:

https://www.st.com/content/ccc/resource/technical/document/application_note/group1/b7/b5/ca/8e/93/20/42/0e/DM00389996/files/DM00389996.pdf/jcr:content/translations/en.DM00389996.pdf

0690X00000As59GQAR.png

So a heads up: Make sure you enable this option:

0690X00000As59LQAR.png

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?