I'm trying to use a new u-boot (v2016.01) with an old Linux kernel (3.0.15). That means there is no device tree. Everything seems to work well except of the NAND driver - the NAND device is not detected by the kernel, resulting in the following log in dmesg:
FSL NFC MTD nand Driver 1.0
No NAND device found.
mxc_nand: NAND Flash not found !
Anyway, in u-boot, the NAND device is detected and I can read/write it as required:
NAND: 256 MiB
MMC: FSL_SDHC: 0
*** Warning - bad CRC, using default environment
---
With an old u-boot (v2011.12), the device is detected by the kernel normally:
FSL NFC MTD nand Driver 1.0
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xda (Micron NAND 256MiB 3,3V 8-bit)
Bad block table not found for chip 0
Bad block table not found for chip 0
Scanning device for bad blocks
Bad eraseblock 4 at 0x000000080000
Bad eraseblock 5 at 0x0000000a0000
3 cmdlinepart partitions found on MTD device NAND
Creating 3 MTD partitions on "NAND":
0x000000000000-0x000000100000 : "mtd_uboot"
0x000000100000-0x000000600000 : "mtd_kernel"
0x000000600000-0x000010000000 : "mtd_rootfs"
In u-boot, the log contains also some bad block info:
NAND: 256 MiB
MMC: FSL_SDHC: 0
Bad block table not found for chip 0
Bad block table not found for chip 0
Bad block table written to 0x00000ffe0000, version 0x01
Bad block table written to 0x00000ffc0000, version 0x01
*** Warning - bad CRC, using default environment
---
Now the question is what is the difference in initialization of NAND in the new u-boot that causes Linux (and only Linux) to not detect the device. I can see the driver has changed significantly but perhaps it's not difficult to make the things work, I might be missing something... Perhaps timesyssupport might help...?
Solved! Go to Solution.
Thanks for your explanation, Stefan. The nfc_select_chip has empty body in Linux 3.0 for Vybrid. That driver is the same as in u-boot v2011.12. Hence the standard configuration u-boot v2011.12 + Linux 3.0 works because the chip select is never touched. My point was whether the select_chip implementation in u-boot v2016.01 might be faulty. Now I see the problem is rather in Linux 3.0. Anyway, if the kernel cannot be fixed, removing the chip select functionality from u-boot v2016.01 does a good job, too.
can you help to comment here?
Alright, I found the problem. The chip select in drivers/mtd/nand/vf610_nfc.c breaks it:
/*
* This function supports Vybrid only (MPC5125 would have full RB and four CS)
*/
static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip)
{
#ifdef CONFIG_VF610
u32 tmp = vf610_nfc_read(mtd, NFC_ROW_ADDR);
tmp &= ~(ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK);
if (chip >= 0) {
tmp |= 1 << ROW_ADDR_CHIP_SEL_RB_SHIFT;
tmp |= (1 << chip) << ROW_ADDR_CHIP_SEL_SHIFT;
}
vf610_nfc_write(mtd, NFC_ROW_ADDR, tmp);
#endif
}
When I disable the code inside this function, everything works fine - NAND in both u-boot and Linux.
A side question remains why the code does not work. According to git blame, falstaff is the author of this file. May I ask for a comment?
The function sets the chip select in register the NFC_RAR register. I guess when you uncomment the code, it is just the reset value (which is RB0/CS0 being set) which works fine.
Now I think what happens is that the MTD stack calls that function with -1 after flash operations (which leads to a clear of ROW_ADDR_CHIP_SEL_RB_MASK | ROW_ADDR_CHIP_SEL_MASK, see code above). So U-Boot might leave the NFC IP with those flags cleared. So if the NFC driver in Linux 3.0 does not explicitly sets them again, I guess the driver ends up talking to no chip... IMHO, the Linux 3.0 NFC driver should implement select_chip accordingly too...
Thanks for your explanation, Stefan. The nfc_select_chip has empty body in Linux 3.0 for Vybrid. That driver is the same as in u-boot v2011.12. Hence the standard configuration u-boot v2011.12 + Linux 3.0 works because the chip select is never touched. My point was whether the select_chip implementation in u-boot v2016.01 might be faulty. Now I see the problem is rather in Linux 3.0. Anyway, if the kernel cannot be fixed, removing the chip select functionality from u-boot v2016.01 does a good job, too.
timesyssupport can you help to review this case?