We have just ported Linux to a custom board, using the TI8168. We previously had linux working on the EVM board.

On boot linux hangs, it turns out that this is in drivers/mtd/nand/nand_base.c: nand_command(), specifically the NAND_CMD_RESET function which was called from nand_base.c: nand_get_flash_type().

So on init, we start by reseting the device, then issue a status command and try and read the result:

if (chip->dev_ready)
chip->cmd_ctrl(mtd, NAND_CMD_STATUS,
while (!(chip->read_byte(mtd) & NAND_STATUS_READY));

It is in this while loop that we get stuck.

I have found that in drivers/mtd/nand/omap2.c: omap_nand_probe() the line: 

 info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE);

This is setting up the address to read from (used by the nand_read_byte16() function (which is pointed at by the read_byte() function pointer). It is using the chip select memory region , rather than the NAND_DAT register.
The TRM states: 
"Reading data from the GPMC_NAND_DATA_i location or from any
location in the associated chip-select memory region activates an
asynchronous read access."

So this should be fine. If I change the line to:

 info->nand.IO_ADDR_R = (void * __iomem)((int)gpmc_base + 0x84);

Note that 0x84 is the offset of NAND_DAT register.

Now it boots fine. Although I have to add another hack so that it uses the chip select memory region when using the prefetch engine for actual reads.

I also tried using the chip select memory region instead of the NAND_DAT register in u-boot with a directly mapped MMU enabled, and that failed in the same way. However linux did appear to work on the EVM board, and I have compared the nand drivers and they are not significantly different.

Does anyone have any idea why this is failing or what we have done wrong in setting up this board?

Andrew Parlane