NAND flash and U-boot

Hello, all.

I’ve been hitting my head against a problem, and before I start a support case with a silicon vendor.

I am trying to get U-boot to recognize (and load Linux from) a NAND flash device that’s mounted on a little prototype cape. The NAND chip (Micron MT29F8G08ABABA) is connected in the usual way, and lives on nCS0. The cape also contains a SPI flash, and some switches to select the boot mode. The cape’s plugged into a BeagleBone Black Wireless.

I am using U-boot from Git, with patches per eewiki. Twiddling some configuration settings gave me an MLO and u-boot.img that I was able to program into the SPI flash; that boots fine (with BOOTSEL2 grounded, which sets SPI as the first boot source), and is not the problem I’m running into.

I then enabled NAND drivers. There appears to be a slight bug in board/ti/am335x/mux.c, around line 386 in the Git version of U-boot: the line that says:

#if defined(CONFIG_NAND) && defined(CONFIG_EMMC_BOOT)

should say

#if defined(CONFIG_NAND) && !defined(CONFIG_EMMC_BOOT)

as it’s not actually possible to use both NAND and EMMC — they share pins.

Once I make this change, I can see that the pinmux registers are set up correctly, and so is the GPMC for chip select 0. However, U-boot doesn’t see the flash — it returns “0 MiB” as the detected flash size.

Adding assorted printfs()s through the code suggests where the problem is: in nand_flash_detect_onfi (drivers/mtd/nand_base.c), there’s a READ ID command that’s issued to the chip. This *should* return the bytes ‘O’, ’N’, ‘F’, and ‘I’, in that order. What I’m getting back is the correct bytes, but in the wrong order: I get back ‘F’, ’N’, ‘O’, and ‘I’. I thought that this might be a mis-configuration of the memory interface, with a 32-bit read getting rearranged by the GPMC or something.

However, I also have a small bare-metal (StarterWare) program which reads the flash information, including the READ ID command, and the READ PARAMETER PAGE command. I *know* that this uses byte reads, as I can disassemble the code, and I see actual “ldrb” instructions being issued to read data from the GPMC. Reading the ID with this code still results in the out-of-order signature. The weird thing is, the parameter page reads back just fine!

In an attempt to figure what’s happening on the wire, I hooked a logic analyzer up to the NAND signals. Looking at the READ ID cycle, I can see that the data being driven by the NAND chip matches the out-of-order bytes that I read back, rather than what the data sheet claims they should be.

Am I going crazy? Unless I am misreading the flash data sheet, the bytes should come out in the specified order; the ONFI spec says the same thing. So, is this a silicon bug in the NAND? This seems unlikely — Micron’s made millions of these things, and this seems like pretty key functionality. But I am out of ideas.

-- Luke