am335x: NAND: add BCH16 and 4k page size support
Subsystems (3)
PATCH 1/1 am335x: NAND: add BCH16 and 4k page size support
This is tested with a custom AM3359 (rev 2.0) board. NAND chip: MT29F16G08ABABAWP
This code allows me to boot from ROM code.
The ROM code forces BCH16 on NAND chips with a 4k page size.
BCH16 is not enabled by default.
--- arch/arm/include/asm/arch-am33xx/cpu.h | 8 +- arch/arm/include/asm/arch-am33xx/omap_gpmc.h | 43 ++++++++ drivers/mtd/nand/omap_gpmc.c | 150 +++++++++++++++++---------- include/linux/mtd/mtd-abi.h | 2 +- 4 files changed, 148 insertions(+), 55 deletions(-)
arch/arm/include/asm/arch-am33xx/cpu.h +7 -1
@@ -78,6 +78,10 @@ struct bch_res_0_3 {u32 bch_result_x[4 ]; }; +struct bch_res_4_6 { +u32 bch_result_x[3 ]; +}; +struct gpmc {u8 res1[0x10 ];u32 sysconfig;/* 0x10 */
@@ -107,7 +111,9 @@ struct gpmc {u8 res7[12 ];/* 0x224 */ u32 testmomde_ctrl;/* 0x230 */ u8 res8[12 ];/* 0x234 */ -struct bch_res_0_3 bch_result_0_3[2 ];/* 0x240 */ +struct bch_res_0_3 bch_result_0_3;/* 0x240 */ +u32 dummy[44 ];/* not used */ +struct bch_res_4_6 bch_result_4_6;/* 300 */ };/* Used for board specific gpmc initialization */
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +43 -0
47 lines not on this page · raw message
drivers/mtd/nand/omap_gpmc.c +97 -53
279 lines not on this page · raw message
include/linux/mtd/mtd-abi.h +1 -1
@@ -125,7 +125,7 @@ struct nand_oobfree {*/ struct nand_ecclayout {uint32_t eccbytes; -uint32_t eccpos[128 ]; +uint32_t eccpos[208 ];uint32_t oobavail;struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES ]; };
--
1.8.1.1
PATCH 1/1 am335x: NAND: add BCH16 and 4k page size support
Quoted 10 lines · Jordy van Wolferen
This is tested with a custom AM3359 (rev 2.0) board. NAND chip: MT29F16G08ABABAWP
This code allows me to boot from ROM code.
The ROM code forces BCH16 on NAND chips with a 4k page size.BCH16 is not enabled by default.
---
Missing Signed-off-by (please read the "Sign your work" section of Documentation/SubmittingPatches in Linux and be sure that you meet the conditions of the Developer's Certificate of Origin before adding your sign off).
Could you explain the patch in a bit more detail? You say it is "not enabled by default" -- what would be required to enable it?
Quoted 107 lines
arch/arm/include/asm/arch-am33xx/cpu.h | 8 +- arch/arm/include/asm/arch-am33xx/omap_gpmc.h | 43 ++++++++ drivers/mtd/nand/omap_gpmc.c | 150 +++++++++++++++++---------- include/linux/mtd/mtd-abi.h | 2 +- 4 files changed, 148 insertions(+), 55 deletions(-)arch/arm/include/asm/arch-am33xx/cpu.h +7
-1@@ -78,6 +78,10 @@ struct bch_res_0_3 {u32 bch_result_x[4 ]; }; +struct bch_res_4_6 { +u32 bch_result_x[3 ]; +}; +struct gpmc {u8 res1[0x10 ];u32 sysconfig;/* 0x10 */ @@ -107,7 +111,9 @@ struct gpmc {u8 res7[12 ];/* 0x224 */ u32 testmomde_ctrl;/* 0x230 */ u8 res8[12 ];/* 0x234 */ -struct bch_res_0_3 bch_result_0_3[2 ];/* 0x240 */ +struct bch_res_0_3 bch_result_0_3;/* 0x240 */ +u32 dummy[44 ];/* not used */ +struct bch_res_4_6 bch_result_4_6;/* 300 */ };/* Used for board specific gpmc initialization */ arch/arm/include/asm/arch-am33xx/omap_gpmc.h +6
-0@@ -117,4 +117,47 @@ {.offset = 106,\ .length = 8 } } \ } + +#define GPMC_NAND_4K_HW_BCH8_ECC_LAYOUT {\ + .eccbytes = 112,\ + .eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,26 ,27 ,\ + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,38, 39,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,50, 51,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,62, 63,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,74, 75,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,86, 87,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,98, 99,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 100, 101, 102, 103, 104, 105, 106, 107,108, 109,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +10
-0+ 110, 111, 112, 113},\ + .oobfree = {\ + {.offset = 114,\ + .length = 110 } } \ +} + +#define GPMC_NAND_4K_HW_BCH16_ECC_LAYOUT {\ + .eccbytes = 208,\ + .eccpos = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,26, 27,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,38, 39,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,50, 51,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,62, 63,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,74, 75,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,86, 87,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,98, 99,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 100, 101, 102, 103, 104, 105, 106, 107,108, 109,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 110, 111, 112, 113, 114, 115, 116, 117,118, 119,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 120, 121, 122, 123, 124, 125, 126, 127,128, 129,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 130, 131, 132, 133, 134, 135, 136, 137,138, 139,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 140, 141, 142, 143, 144, 145, 146, 147,148, 149,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 150, 151, 152, 153, 154, 155, 156, 157,158, 159,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 160, 161, 162, 163, 164, 165, 166, 167,168, 169,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 170, 171, 172, 173, 174, 175, 176, 177,178, 179,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 180, 181, 182, 183, 184, 185, 186, 187,188, 189,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 190, 191, 192, 193, 194, 195, 196, 197,198, 199,\
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +1
-0+ 200, 201, 202, 203, 204, 205, 206, 207,
Quoted 1 line
208, 209},\
You have too many tabs here -- be sure your editor is set for 8-character tabs.
Quoted 11 lines
arch/arm/include/asm/arch-am33xx/omap_gpmc.h +4
-0+ .oobfree = {\ + {.offset = 210,\ + .length = 14 } } \ +}#endif /* __ASM_ARCH_OMAP_GPMC_H */ drivers/mtd/nand/omap_gpmc.c +0
-0
drivers/mtd/nand/omap_gpmc.c int omap_spl_dev_ready(struct mtd_info *mtd) · line 83
Quoted 10 lines
drivers/mtd/nand/omap_gpmc.c +2
-2@@ -76,8 +76,8 @@ int omap_spl_dev_ready(struct mtd_info *mtd)/* * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in -* GPMC controller -* @mtd: MTD device structure +* GPMC controller +* @mtd: MTD device structure * */ static void __maybe_unused omap_hwecc_init (struct nand_chip *chip)
No unrelated whitespace changes, please.
drivers/mtd/nand/omap_gpmc.c struct nand_bch_priv { · line 263
Quoted 8 lines
drivers/mtd/nand/omap_gpmc.c +1
-1@@ -258,7 +258,7 @@ struct nand_bch_priv {#define ECC_BCH8_NIBBLES 26#define ECC_BCH16_NIBBLES 52 -static struct nand_ecclayout hw_bch8_nand_oob =GPMC_NAND_HW_BCH8_ECC_LAYOUT ; +static struct nand_ecclayout nand_ecclayout =GPMC_NAND_HW_BCH8_ECC_LAYOUT ;
Why the name change? It's still the bch8 layout.
If your intent is for this to be the configuration knob, U-Boot is not configured by making edits to random source files. It needs to be a proper config symbol (and documented).
Quoted 40 lines
drivers/mtd/nand/omap_gpmc.c +0
-0static struct nand_bch_priv bch_priv = {drivers/mtd/nand/omap_gpmc.c +4
-4.mode = NAND_ECC_HW_BCH,@@ -280,21 +280,21 @@ static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian, int8_t i = 0, j;if (big_endian) { - ptr = &gpmc_cfg->bch_result_0_3[0 ].bch_result_x[3 ]; + ptr = &gpmc_cfg->bch_result_0_3.bch_result_x[3 ]; ecc_code[i++] =readl (ptr) &0xFF ; ptr--;for (j =0 ; j <3 ; j++) { ecc_code[i++] = (readl (ptr) >>24 ) &0xFF ; ecc_code[i++] = (readl (ptr) >>16 ) &0xFF ; - ecc_code[i++] = (readl (ptr) >>8 ) &0xFF ; + ecc_code[i++] = (readl (ptr) >>8 ) &0xFF ; ecc_code[i++] =readl (ptr) &0xFF ; ptr--; } }else { - ptr = &gpmc_cfg->bch_result_0_3[0 ].bch_result_x[0 ]; + ptr = &gpmc_cfg->bch_result_0_3.bch_result_x[0 ];for (j =0 ; j <3 ; j++) { ecc_code[i++] =readl (ptr) &0xFF ; - ecc_code[i++] = (readl (ptr) >>8 ) &0xFF ; + ecc_code[i++] = (readl (ptr) >>8 ) &0xFF ; ecc_code[i++] = (readl (ptr) >>16 ) &0xFF ; ecc_code[i++] = (readl (ptr) >>24 ) &0xFF ;drivers/mtd/nand/omap_gpmc.c +5
-0ptr++;@@ -304,6 +304,53 @@ static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian, } } +static void omap_read_bch16_result(struct mtd_info *mtd, uint8_t big_endian, + uint8_t *ecc_code) +{ + uint32_t *ptr; +int8_t i =0 , j;
drivers/mtd/nand/omap_gpmc.c static void omap_read_bch8_result(struct · line 323
Quoted 10 lines
drivers/mtd/nand/omap_gpmc.c +9
-0+uint32_t data; + +if (big_endian) { + ptr = &gpmc_cfg->bch_result_4_6.bch_result_x[2 ]; + +for (j =0 ; j <7 ; j++) { +if (j ==3 ) { + ptr = &gpmc_cfg->bch_result_0_3.bch_result_x[3 ]; + }
Please put a space after "if". Don't use braces around a single line.
Quoted 5 lines
drivers/mtd/nand/omap_gpmc.c +5
-0+ + data =readl (ptr); + ptr--; + +if (i >0 ) {
drivers/mtd/nand/omap_gpmc.c static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian, · line 335
Quoted 10 lines
drivers/mtd/nand/omap_gpmc.c +10
-0+ ecc_code[i++] = (data >>24 ) &0xFF ; + ecc_code[i++] = (data >>16 ) &0xFF ; + } + ecc_code[i++] = (data >>8 ) &0xFF ; + ecc_code[i++] = data &0xFF ; + } + ecc_code[i++] =0 ; + ecc_code[i++] =0 ; + } +else {
} else {
Quoted 33 lines
drivers/mtd/nand/omap_gpmc.c +5
-0+ ptr = &gpmc_cfg->bch_result_0_3.bch_result_x[0 ]; + +for (j =0 ; j <7 ; j++) { +if (j ==4 ) { + ptr =&gpmc_cfg->bch_result_4_6.bch_result_x[0];
drivers/mtd/nand/omap_gpmc.c +14
-1+ } + + data =readl (ptr); + ptr++; + + ecc_code[i++] = data &0xFF ; + ecc_code[i++] = (data >>8 ) &0xFF ; + ecc_code[i++] = (data >>16 ) &0xFF ; + ecc_code[i++] = (data >>24 ) &0xFF ; + } + } +} +/* * omap_ecc_disable - Disable H/W ECC calculation * @@ -330,7 +377,7 @@ static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc, struct nand_chip *chip = mtd->priv;struct nand_bch_priv *bch = chip->priv;uint8_t n_bytes =0 ; -int8_t i, j; +int8_t i;switch (bch->type) {drivers/mtd/nand/omap_gpmc.c +0
-0case ECC_BCH4 :
drivers/mtd/nand/omap_gpmc.c static void omap_rotate_ecc_bch(struct mtd_info · line 391
Quoted 8 lines
drivers/mtd/nand/omap_gpmc.c +3
-1@@ -338,7 +385,12 @@ static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc, break;case ECC_BCH16 : - n_bytes =28 ; + n_bytes =26 ; + +/* Last 2 register of ELM need to be zero */
s/register/registers/
drivers/mtd/nand/omap_gpmc.c static void omap_rotate_ecc_bch(struct mtd_info · line 405
Quoted 10 lines
drivers/mtd/nand/omap_gpmc.c +3
-2@@ -347,16 +399,17 @@ static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc, break; } -for (i =0 , j = (n_bytes-1 ); i < n_bytes; i++, j--) - syndrome[i] = calc_ecc[j]; +for (i =0 ; i < n_bytes; i++) { + syndrome[i] = calc_ecc[(n_bytes-1 )-i]; + }
Please put spaces around binary operators such as '-' (and again, no braces around single lines).
Quoted 13 lines
drivers/mtd/nand/omap_gpmc.c +3
-2void omap_nand_switch_ecc (int32_t hardware) { +#ifndef CONFIG_AM33XX struct nand_chip *nand;struct mtd_info *mtd;if (nand_curr_device <0 || - nand_curr_device >=CONFIG_SYS_MAX_NAND_DEVICE || - !nand_info[nand_curr_device].name) { + nand_curr_device >=CONFIG_SYS_MAX_NAND_DEVICE || + !nand_info[nand_curr_device].name) { printf("Error: Can't switch ecc, no devicesavailable\n");
drivers/mtd/nand/omap_gpmc.c
Quoted 2 lines
drivers/mtd/nand/omap_gpmc.c +0
-0return ; }
Please never have the continuation line of a conditional lined up with the body of the construct.
Quoted 8 lines
drivers/mtd/nand/omap_gpmc.c +0
-4@@ -646,19 +702,6 @@ void omap_nand_switch_ecc(int32_t hardware) nand->ecc.calculate = omap_calculate_ecc;omap_hwecc_init (nand);printf ("HW ECC selected\n" ); -#ifdef CONFIG_AM33XX - }else if (hardware ==2 ) { - nand->ecc.mode =NAND_ECC_HW ; - nand->ecc.layout = &hw_bch8_nand_oob;
drivers/mtd/nand/omap_gpmc.c void omap_nand_switch_ecc(int32_t hardware) · line 705
Quoted 10 lines
drivers/mtd/nand/omap_gpmc.c +0
-9- nand->ecc.size =512 ; - nand->ecc.bytes =14 ; - nand->ecc.read_page = omap_read_page_bch; - nand->ecc.hwctl = omap_enable_ecc_bch; - nand->ecc.correct = omap_correct_data_bch; - nand->ecc.calculate = omap_calculate_ecc_bch; -omap_hwecc_init_bch (nand,NAND_ECC_READ ); -printf ("HW BCH8 selected\n" ); -#endif }else {
Explain.
include/linux/mtd/mtd-abi.h struct nand_oobfree { · line 131
Quoted 13 lines
include/linux/mtd/mtd-abi.h +1
-1@@ -125,7 +125,7 @@ struct nand_oobfree {*/ struct nand_ecclayout {uint32_t eccbytes; -uint32_t eccpos[128 ]; +uint32_t eccpos[208 ];uint32_t oobavail;struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES ]; };
Changes to generic code should ideally be separate patches.
-Scott
PATCH 1/1 am335x: NAND: add BCH16 and 4k page size support
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Quoted 10 lines · Scott Wood
Quoted 9 lines · Jordy van Wolferen
This is tested with a custom AM3359 (rev 2.0) board. NAND chip:
MT29F16G08ABABAWPThis code allows me to boot from ROM code. The ROM code forces BCH16 on NAND chips with a 4k page size.
BCH16 is not enabled by default.
Quoted 6 lines
Quoted 1 line
---
Missing Signed-off-by (please read the "Sign your work" section of
Documentation/SubmittingPatchesin Linux and be sure that you meet the conditions of the Developer's Certificate of Origin before adding your sign off).
Note that this also appears to be versus a TI SDK tree and not mainline (but migrating the code shouldn't be overly difficult now that NAND support is mainline).
Quoted 2 lines
Could you explain the patch in a bit more detail? You say it is "not enabled by default" -- what would be required to enable it?
It needs to be auto-detected and switched to, just like how the ROM does (which is to say when the ROM picks up BCH16 and wants it, we do too).
[snip]
Quoted 9 lines
Quoted 7 lines
(quoted diff) +0
-0
b/include/linux/mtd/mtd-abi.hindex 8bdd231..6979a2a 100644 ---a/include/linux/mtd/mtd-abi.h+++b/include/linux/mtd/mtd-abi.h(quoted diff) +0
-0@@ -125,7 +125,7 @@ struct nand_oobfree { */ struct
nand_ecclayout{uint32_teccbytes; -uint32_teccpos[128]; +uint32_teccpos[208];uint32_toobavail; structnand_oobfreeoobfree[MTD_MAX_OOBFREE_ENTRIES]; };Changes to generic code should ideally be separate patches.
True. And I wonder if the mtd re-sync covers this or not.
- --
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
iQIcBAEBAgAGBQJRCCquAAoJENk4IS6UOR1WcP4P+wUmTIMJlxEVP0JQseXL3fG1 gS0+KRYzFgceBkunfbgXcCGAqP2z3gcmyNEn0s/8dVkrN1F9MirUNz2VApqQwn0b lj8E/30e042EzM3sM/HyPO0S4yWBVf8GjYiRJMDb80gKOJelthrKNAjermIxqax6 dIHlSvV9pk6DYHTAmcgC7H3QLyHkwyZfSwii+ZRKm5hRPgpiQA2kI7klV8rEH8m7 x5d5c1Ry59hIrefmWWpJvrXhy9u8ipCzk37CCafyl3KbZJoOhZSHiXx73TebI1gP Sg1ONCvi8MkOZrMmC+iXqbKtrPYUGYApd7TonIoJg2yTlkIBevbTY4OLS/p81Btq HoJZ7PziCbeu4jZCVlS4Pz7OiIf5GyBbW1oJP/Uhz4tJAuSLJTrxHaiz7sUIZt3p zNr1ZrL7d5h6hlv3XBuERxRvAn2E4K+sSUJsS+C+8zi/rYMWfWxm5ncB4ygGqCNn QYvJSwWXK/yyFpq0NSbXZnHvBInwGcdrcQVJy3RftATxEW7B2EJKbLx8yJxcpoaU nDyN/NDYEeqZx3Vwf8q2YAv7S72vFP6Lwfy+bAbOeyc3emH6sYTE9iDt2EzTYuMM 3nDjgWZiNGDzJ7WzUv6ptDUIV9UQXxdwa7Ay4qc7aKbSx4t/LhjtIDXJYVh9Bbxq 3cYj8flqqYG9yQQn5xk/
=fOZt
-----END PGP SIGNATURE-----