NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.
DM365 Nand ECC layout
Issue[edit]
When UBL/U-boot is updated from nandwrite of U-boot/Linux, The EVM fails to boot because of ECC failure. The issue described on this wiki applies to all Davinci devices DA830/DA850 and OMAPL13x devices.
Reason[edit]
The ECC layout maintained by Davinci Nand driver of U-boot/Linux doesnot comply with the ECC layout maintained by RBL/UBL.
Resolution[edit]
The ECC layout of Davinci Nand driver in U-boot and Linux is modified. The Nand driver in Linux is provided with an option of passing the desired ECC layout through Platform data. Patches for the same are below.
ECC layout[edit]
The following tables depicts the mismatch in ECC layouts maintained U-boot/Linux with repect RBL/UBL.
01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | |
---|---|---|---|---|---|---|---|---|
01 | ||||||||
02 | ||||||||
03 | ||||||||
04 | ||||||||
05 | ||||||||
06 | ||||||||
07 | ||||||||
08 |
01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | |
---|---|---|---|---|---|---|---|---|
01 | ||||||||
02 | ||||||||
03 | ||||||||
04 | ||||||||
05 | ||||||||
06 | ||||||||
07 | ||||||||
08 |
Patches to fix the issue[edit]
Below patch on DaVinci nand driver of U-boot modifies the ECC layout so as to match the ECC layout maintained UBL.
<syntaxhighlight lang="c"> diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 4ca738e..4ba12ce 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -278,5 +278,13 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = { #if defined(CONFIG_SYS_NAND_PAGE_2K) .eccbytes = 40,
+ .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + }, + .oobfree = {{2, 4}, {16, 6}, {32, 6}, {48, 6}}, +#if 0
.eccpos = { 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
@@ -288,6 +296,7 @@ static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = {
.oobfree = { {.offset = 2, .length = 22, }, },
+#endif
#elif defined(CONFIG_SYS_NAND_PAGE_4K) .eccbytes = 80, .eccpos = {
</syntaxhighlight>
NOTE
Above patch is based on v2010.03-rc1 release of community U-boot. If your driver is based on some other releases, consider above patch as reference to modify ECC layout to match with ECC layout of RBL/UBL.
Below patch on Linux DaVinci Nand driver provides an option to pass desired(RBL/UBL compliant) ECC layout via platform data.
<syntaxhighlight lang="c"> diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 5d3946e..4bce9db 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -89,5 +89,17 @@ static struct mtd_partition davinci_nand_partitions[] = {
/* two blocks with bad block table (and mirror) at the end */ };
+static struct nand_ecclayout dm365_evm_nand_ecclayout = { + .eccbytes = 40, + .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + }, + .oobfree = {{2, 4}, {16, 6}, {32, 6}, {48, 6} }, +}; +
static struct davinci_nand_pdata davinci_nand_data = { .mask_chipsel = BIT(14), .parts = davinci_nand_partitions,
@@ -96,6 +108,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
.ecc_mode = NAND_ECC_HW, .options = NAND_USE_FLASH_BBT, .ecc_bits = 4,
+ .ecclayout = &dm365_evm_nand_ecclayout,
};
static struct resource davinci_nand_resources[] = {
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h index b2ad809..7c6be2b 100644 --- a/arch/arm/mach-davinci/include/mach/nand.h +++ b/arch/arm/mach-davinci/include/mach/nand.h @@ -83,6 +83,9 @@ struct davinci_nand_pdata { /* platform_data */
/* Main and mirror bbt descriptor overrides */ struct nand_bbt_descr *bbt_td; struct nand_bbt_descr *bbt_md;
+ + /*Nand ECC layout*/ + struct nand_ecclayout *ecclayout;
};
#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 06ee8c8..4e4ed73 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -762,7 +762,10 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
goto syndrome_done; } if (chunks == 4) {
- info->ecclayout = hwecc4_2048; + if (pdata->ecclayout != NULL) + info->ecclayout = *(pdata->ecclayout); + else + info->ecclayout = hwecc4_2048;
info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST; goto syndrome_done; }
</syntaxhighlight>
NOTE
The Above patch is based community kernel release v2.6.33. If your driver is based on some other releases, consider above patch as reference to modify ECC layout to match with ECC layout of RBL/UBL.
Verification[edit]
The above Linux Nand driver patch can be verified as below:
- Dump the first 'len' bytes of U-boot header info in to 'file' from start U-boot partition(/dev/mtdX)
- Erase whole flash
- First write the U-boot header from the saved 'file' at the starting of U-boot partition
- Write the U-boot binary after 'len' bytes from start of partition
- Restart EVM
target$nanddump -o -l len -f <file> /dev/mtdX
target$flash_eraseall /dev/mtdX
target$nandwrite /dev/mtdX <file>
target$nandwrite -p -s len /dev/mtdX U-boot.bin
target$reboot
EVM should start booting the updated U-boot.