Skip to main content
AMurr.2282
Associate III
November 7, 2019
Question

NAND Flash initialization hangs forever on custom board

  • November 7, 2019
  • 3 replies
  • 1511 views

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?

This topic has been closed for replies.

3 replies

Olivier GALLIEN
Technical Moderator
November 8, 2019

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
November 8, 2019

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
November 15, 2019

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?