* [U-Boot] [PATCH] am335x: NAND, add BCH16 and 4k page size support
[not found] <1359376558-14035-1-git-send-email-jordyvanwolferen@gmail.com>
@ 2013-01-28 12:55 ` Jordy van Wolferen
0 siblings, 0 replies; 4+ messages in thread
From: Jordy van Wolferen @ 2013-01-28 12:55 UTC (permalink / raw)
To: u-boot
Please ignore this.
This enables BCH16 by default, which shouldn't happen. I'll will fix this
and send again
On Mon, Jan 28, 2013 at 1:35 PM, Jordy van Wolferen <
jordyvanwolferen@gmail.com> wrote:
> ---
> 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 | 154
> +++++++++++++++++----------
> include/linux/mtd/mtd-abi.h | 2 +-
> 4 files changed, 150 insertions(+), 57 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h
> b/arch/arm/include/asm/arch-am33xx/cpu.h
> index 16e8a80..0a1f1ff 100644
> --- a/arch/arm/include/asm/arch-am33xx/cpu.h
> +++ b/arch/arm/include/asm/arch-am33xx/cpu.h
> @@ -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 */
> diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> index 572f9d0..534fa6e 100644
> --- a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> +++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> @@ -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,\
> + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
> 50, 51,\
> + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
> 62, 63,\
> + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
> 74, 75,\
> + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
> 86, 87,\
> + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
> 98, 99,\
> + 100, 101, 102, 103, 104, 105, 106, 107,
> 108, 109,\
> + 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,\
> + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
> 38, 39,\
> + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
> 50, 51,\
> + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
> 62, 63,\
> + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
> 74, 75,\
> + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
> 86, 87,\
> + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
> 98, 99,\
> + 100, 101, 102, 103, 104, 105, 106, 107,
> 108, 109,\
> + 110, 111, 112, 113, 114, 115, 116, 117,
> 118, 119,\
> + 120, 121, 122, 123, 124, 125, 126, 127,
> 128, 129,\
> + 130, 131, 132, 133, 134, 135, 136, 137,
> 138, 139,\
> + 140, 141, 142, 143, 144, 145, 146, 147,
> 148, 149,\
> + 150, 151, 152, 153, 154, 155, 156, 157,
> 158, 159,\
> + 160, 161, 162, 163, 164, 165, 166, 167,
> 168, 169,\
> + 170, 171, 172, 173, 174, 175, 176, 177,
> 178, 179,\
> + 180, 181, 182, 183, 184, 185, 186, 187,
> 188, 189,\
> + 190, 191, 192, 193, 194, 195, 196, 197,
> 198, 199,\
> + 200, 201, 202, 203, 204, 205, 206, 207,
> 208, 209},\
> + .oobfree = {\
> + {.offset = 210,\
> + .length = 14 } } \
> +}
> #endif /* __ASM_ARCH_OMAP_GPMC_H */
> diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
> index cee394e..5cdacc2 100644
> --- a/drivers/mtd/nand/omap_gpmc.c
> +++ b/drivers/mtd/nand/omap_gpmc.c
> @@ -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)
> @@ -170,19 +170,19 @@ static int __maybe_unused omap_correct_data(struct
> mtd_info *mtd, uint8_t *dat,
> }
>
> /*
> - * omap_calculate_ecc - Generate non-inverted ECC bytes.
> + * omap_calculate_ecc - Generate non-inverted ECC bytes.
> *
> - * Using noninverted ECC can be considered ugly since writing a blank
> - * page ie. padding will clear the ECC bytes. This is no problem as
> - * long nobody is trying to write data on the seemingly unused page.
> - * Reading an erased page will produce an ECC mismatch between
> - * generated and read ECC bytes that has to be dealt with separately.
> - * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
> - * is used, the result of read will be 0x0 while the ECC offsets of the
> - * spare area will be 0xFF which will result in an ECC mismatch.
> - * @mtd: MTD structure
> - * @dat: unused
> - * @ecc_code: ecc_code buffer
> + * Using noninverted ECC can be considered ugly since writing a blank
> + * page ie. padding will clear the ECC bytes. This is no problem as
> + * long nobody is trying to write data on the seemingly unused page.
> + * Reading an erased page will produce an ECC mismatch between
> + * generated and read ECC bytes that has to be dealt with separately.
> + * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within
> GPMC
> + * is used, the result of read will be 0x0 while the ECC offsets of
> the
> + * spare area will be 0xFF which will result in an ECC mismatch.
> + * @mtd: MTD structure
> + * @dat: unused
> + * @ecc_code: ecc_code buffer
> */
> static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
> const uint8_t *dat, uint8_t *ecc_code)
> @@ -207,8 +207,8 @@ static int __maybe_unused omap_calculate_ecc(struct
> mtd_info *mtd,
>
> /*
> * omap_enable_ecc - This function enables the hardware ecc functionality
> - * @mtd: MTD device structure
> - * @mode: Read/Write mode
> + * @mtd: MTD device structure
> + * @mode: Read/Write mode
> */
> static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd,
> int32_t mode)
> {
> @@ -258,12 +258,12 @@ 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_4K_HW_BCH16_ECC_LAYOUT;
>
> static struct nand_bch_priv bch_priv = {
> .mode = NAND_ECC_HW_BCH,
> - .type = ECC_BCH8,
> - .nibbles = ECC_BCH8_NIBBLES
> + .type = ECC_BCH16,
> + .nibbles = ECC_BCH16_NIBBLES
> };
>
> /*
> @@ -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;
> ptr++;
> @@ -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;
> + 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];
> + }
> +
> + data = readl(ptr);
> + ptr--;
> +
> + if(i > 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 {
> + 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];
> + }
> +
> + 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) {
> case ECC_BCH4:
> @@ -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 */
> + syndrome[26] = 0;
> + syndrome[27] = 0;
> +
> break;
>
> case ECC_BCH8:
> @@ -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];
> + }
> }
>
> /*
> - * omap_calculate_ecc_bch - Read BCH ECC result
> + * omap_calculate_ecc_bch - Read BCH ECC result
> *
> - * @mtd: MTD structure
> - * @dat: unused
> - * @ecc_code: ecc_code buffer
> + * @mtd: MTD structure
> + * @dat: unused
> + * @ecc_code: ecc_code buffer
> */
> static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t
> *dat,
> uint8_t *ecc_code)
> @@ -368,7 +421,9 @@ static int omap_calculate_ecc_bch(struct mtd_info
> *mtd, const uint8_t *dat,
>
> if (bch->type == ECC_BCH8)
> omap_read_bch8_result(mtd, big_endian, ecc_code);
> - else /* BCH4 and BCH16 currently not supported */
> + else if(bch->type == ECC_BCH16)
> + omap_read_bch16_result(mtd, big_endian, ecc_code);
> + else /* BCH4 currently not supported */
> ret = -1;
>
> /*
> @@ -434,7 +489,7 @@ static int omap_correct_data_bch(struct mtd_info *mtd,
> uint8_t *dat,
> struct nand_bch_priv *bch = chip->priv;
> uint8_t syndrome[28];
> uint32_t error_count = 0;
> - uint32_t error_loc[8];
> + uint32_t error_loc[16];
> uint32_t i, ecc_flag;
>
> ecc_flag = 0;
> @@ -470,7 +525,7 @@ static int omap_correct_data_bch(struct mtd_info *mtd,
> uint8_t *dat,
> /*
> * omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
> * GPMC controller
> - * @mtd: MTD device structure
> + * @mtd: MTD device structure
> * @mode: Read/Write mode
> */
> static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
> @@ -525,8 +580,8 @@ static void omap_hwecc_init_bch(struct nand_chip
> *chip, int32_t mode)
>
> /*
> * omap_enable_ecc_bch- This function enables the bch h/w ecc
> functionality
> - * @mtd: MTD device structure
> - * @mode: Read/Write mode
> + * @mtd: MTD device structure
> + * @mode: Read/Write mode
> *
> */
> static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
> @@ -611,12 +666,13 @@ static int omap_read_page_bch(struct mtd_info *mtd,
> struct nand_chip *chip,
> */
> void 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 devices available\n");
> return;
> }
> @@ -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;
> - 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 {
> nand->ecc.mode = NAND_ECC_SOFT;
> /* Use mtd default settings */
> @@ -671,6 +714,7 @@ void omap_nand_switch_ecc(int32_t hardware)
> nand_scan_tail(mtd);
>
> nand->options &= ~NAND_OWN_BUFFERS;
> +#endif
> }
> #endif /* CONFIG_SPL_BUILD */
>
> @@ -684,10 +728,10 @@ void omap_nand_switch_ecc(int32_t hardware)
> * - ecc.hwctl: function to enable (reset) hardware ecc generator
> * - ecc.mode: mode of ecc, see defines
> * - chip_delay: chip dependent delay for transfering data from array to
> - * read regs (tR)
> + * read regs (tR)
> * - options: various chip options. They can partly be set to inform
> - * nand_scan about special functionality. See the defines for further
> - * explanation
> + * nand_scan about special functionality. See the defines for further
> + * explanation
> */
> int board_nand_init(struct nand_chip *nand)
> {
> @@ -742,7 +786,7 @@ int board_nand_init(struct nand_chip *nand)
> /* Default ECC mode */
> #ifdef CONFIG_AM33XX
> nand->ecc.mode = NAND_ECC_HW;
> - nand->ecc.layout = &hw_bch8_nand_oob;
> + nand->ecc.layout = &nand_ecclayout;
> nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
> nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
> nand->ecc.hwctl = omap_enable_ecc_bch;
> diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
> index 8bdd231..6979a2a 100644
> --- a/include/linux/mtd/mtd-abi.h
> +++ b/include/linux/mtd/mtd-abi.h
> @@ -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
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] am335x: NAND: add BCH16 and 4k page size support
@ 2013-01-28 13:35 Jordy van Wolferen
2013-01-29 19:54 ` Scott Wood
0 siblings, 1 reply; 4+ messages in thread
From: Jordy van Wolferen @ 2013-01-28 13:35 UTC (permalink / raw)
To: u-boot
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(-)
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index 16e8a80..0a1f1ff 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -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 */
diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
index 572f9d0..534fa6e 100644
--- a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
+++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
@@ -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,\
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,\
+ 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,\
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
+ 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,\
+ 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,\
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129,\
+ 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,\
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,\
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,\
+ 160, 161, 162, 163, 164, 165, 166, 167, 168, 169,\
+ 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,\
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189,\
+ 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,\
+ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209},\
+ .oobfree = {\
+ {.offset = 210,\
+ .length = 14 } } \
+}
#endif /* __ASM_ARCH_OMAP_GPMC_H */
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index cee394e..3c42a54 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -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)
@@ -170,19 +170,19 @@ static int __maybe_unused omap_correct_data(struct mtd_info *mtd, uint8_t *dat,
}
/*
- * omap_calculate_ecc - Generate non-inverted ECC bytes.
+ * omap_calculate_ecc - Generate non-inverted ECC bytes.
*
- * Using noninverted ECC can be considered ugly since writing a blank
- * page ie. padding will clear the ECC bytes. This is no problem as
- * long nobody is trying to write data on the seemingly unused page.
- * Reading an erased page will produce an ECC mismatch between
- * generated and read ECC bytes that has to be dealt with separately.
- * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
- * is used, the result of read will be 0x0 while the ECC offsets of the
- * spare area will be 0xFF which will result in an ECC mismatch.
- * @mtd: MTD structure
- * @dat: unused
- * @ecc_code: ecc_code buffer
+ * Using noninverted ECC can be considered ugly since writing a blank
+ * page ie. padding will clear the ECC bytes. This is no problem as
+ * long nobody is trying to write data on the seemingly unused page.
+ * Reading an erased page will produce an ECC mismatch between
+ * generated and read ECC bytes that has to be dealt with separately.
+ * E.g. if page is 0xFF (fresh erased), and if HW ECC engine within GPMC
+ * is used, the result of read will be 0x0 while the ECC offsets of the
+ * spare area will be 0xFF which will result in an ECC mismatch.
+ * @mtd: MTD structure
+ * @dat: unused
+ * @ecc_code: ecc_code buffer
*/
static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
const uint8_t *dat, uint8_t *ecc_code)
@@ -207,8 +207,8 @@ static int __maybe_unused omap_calculate_ecc(struct mtd_info *mtd,
/*
* omap_enable_ecc - This function enables the hardware ecc functionality
- * @mtd: MTD device structure
- * @mode: Read/Write mode
+ * @mtd: MTD device structure
+ * @mode: Read/Write mode
*/
static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
{
@@ -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;
static struct nand_bch_priv bch_priv = {
.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;
ptr++;
@@ -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;
+ 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];
+ }
+
+ data = readl(ptr);
+ ptr--;
+
+ if(i > 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 {
+ 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];
+ }
+
+ 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) {
case ECC_BCH4:
@@ -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 */
+ syndrome[26] = 0;
+ syndrome[27] = 0;
+
break;
case ECC_BCH8:
@@ -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];
+ }
}
/*
- * omap_calculate_ecc_bch - Read BCH ECC result
+ * omap_calculate_ecc_bch - Read BCH ECC result
*
- * @mtd: MTD structure
- * @dat: unused
- * @ecc_code: ecc_code buffer
+ * @mtd: MTD structure
+ * @dat: unused
+ * @ecc_code: ecc_code buffer
*/
static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
uint8_t *ecc_code)
@@ -368,7 +421,9 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
if (bch->type == ECC_BCH8)
omap_read_bch8_result(mtd, big_endian, ecc_code);
- else /* BCH4 and BCH16 currently not supported */
+ else if(bch->type == ECC_BCH16)
+ omap_read_bch16_result(mtd, big_endian, ecc_code);
+ else /* BCH4 currently not supported */
ret = -1;
/*
@@ -434,7 +489,7 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
struct nand_bch_priv *bch = chip->priv;
uint8_t syndrome[28];
uint32_t error_count = 0;
- uint32_t error_loc[8];
+ uint32_t error_loc[16];
uint32_t i, ecc_flag;
ecc_flag = 0;
@@ -470,7 +525,7 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
/*
* omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
* GPMC controller
- * @mtd: MTD device structure
+ * @mtd: MTD device structure
* @mode: Read/Write mode
*/
static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
@@ -525,8 +580,8 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
/*
* omap_enable_ecc_bch- This function enables the bch h/w ecc functionality
- * @mtd: MTD device structure
- * @mode: Read/Write mode
+ * @mtd: MTD device structure
+ * @mode: Read/Write mode
*
*/
static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
@@ -611,12 +666,13 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
*/
void 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 devices available\n");
return;
}
@@ -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;
- 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 {
nand->ecc.mode = NAND_ECC_SOFT;
/* Use mtd default settings */
@@ -671,6 +714,7 @@ void omap_nand_switch_ecc(int32_t hardware)
nand_scan_tail(mtd);
nand->options &= ~NAND_OWN_BUFFERS;
+#endif
}
#endif /* CONFIG_SPL_BUILD */
@@ -684,10 +728,10 @@ void omap_nand_switch_ecc(int32_t hardware)
* - ecc.hwctl: function to enable (reset) hardware ecc generator
* - ecc.mode: mode of ecc, see defines
* - chip_delay: chip dependent delay for transfering data from array to
- * read regs (tR)
+ * read regs (tR)
* - options: various chip options. They can partly be set to inform
- * nand_scan about special functionality. See the defines for further
- * explanation
+ * nand_scan about special functionality. See the defines for further
+ * explanation
*/
int board_nand_init(struct nand_chip *nand)
{
@@ -742,7 +786,7 @@ int board_nand_init(struct nand_chip *nand)
/* Default ECC mode */
#ifdef CONFIG_AM33XX
nand->ecc.mode = NAND_ECC_HW;
- nand->ecc.layout = &hw_bch8_nand_oob;
+ nand->ecc.layout = &nand_ecclayout;
nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
nand->ecc.hwctl = omap_enable_ecc_bch;
diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
index 8bdd231..6979a2a 100644
--- a/include/linux/mtd/mtd-abi.h
+++ b/include/linux/mtd/mtd-abi.h
@@ -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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] am335x: NAND: add BCH16 and 4k page size support
2013-01-28 13:35 [U-Boot] [PATCH] am335x: NAND: add BCH16 and 4k page size support Jordy van Wolferen
@ 2013-01-29 19:54 ` Scott Wood
2013-01-29 20:01 ` Tom Rini
0 siblings, 1 reply; 4+ messages in thread
From: Scott Wood @ 2013-01-29 19:54 UTC (permalink / raw)
To: u-boot
On 01/28/2013 07:35:40 AM, Jordy van Wolferen wrote:
> 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?
> 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(-)
>
> diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h
> b/arch/arm/include/asm/arch-am33xx/cpu.h
> index 16e8a80..0a1f1ff 100644
> --- a/arch/arm/include/asm/arch-am33xx/cpu.h
> +++ b/arch/arm/include/asm/arch-am33xx/cpu.h
> @@ -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 */
> diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> index 572f9d0..534fa6e 100644
> --- a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> +++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
> @@ -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,\
> + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
> 50, 51,\
> + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
> 62, 63,\
> + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
> 74, 75,\
> + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
> 86, 87,\
> + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
> 98, 99,\
> + 100, 101, 102, 103, 104, 105, 106, 107,
> 108, 109,\
> + 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,\
> + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
> 38, 39,\
> + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
> 50, 51,\
> + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
> 62, 63,\
> + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
> 74, 75,\
> + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
> 86, 87,\
> + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
> 98, 99,\
> + 100, 101, 102, 103, 104, 105, 106, 107,
> 108, 109,\
> + 110, 111, 112, 113, 114, 115, 116, 117,
> 118, 119,\
> + 120, 121, 122, 123, 124, 125, 126, 127,
> 128, 129,\
> + 130, 131, 132, 133, 134, 135, 136, 137,
> 138, 139,\
> + 140, 141, 142, 143, 144, 145, 146, 147,
> 148, 149,\
> + 150, 151, 152, 153, 154, 155, 156, 157,
> 158, 159,\
> + 160, 161, 162, 163, 164, 165, 166, 167,
> 168, 169,\
> + 170, 171, 172, 173, 174, 175, 176, 177,
> 178, 179,\
> + 180, 181, 182, 183, 184, 185, 186, 187,
> 188, 189,\
> + 190, 191, 192, 193, 194, 195, 196, 197,
> 198, 199,\
> + 200, 201, 202, 203, 204, 205, 206, 207,
> 208, 209},\
You have too many tabs here -- be sure your editor is set for
8-character tabs.
> + .oobfree = {\
> + {.offset = 210,\
> + .length = 14 } } \
> +}
> #endif /* __ASM_ARCH_OMAP_GPMC_H */
> diff --git a/drivers/mtd/nand/omap_gpmc.c
> b/drivers/mtd/nand/omap_gpmc.c
> index cee394e..3c42a54 100644
> --- a/drivers/mtd/nand/omap_gpmc.c
> +++ b/drivers/mtd/nand/omap_gpmc.c
> @@ -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.
> @@ -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).
> static struct nand_bch_priv bch_priv = {
> .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;
> ptr++;
> @@ -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;
> + 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.
> +
> + data = readl(ptr);
> + ptr--;
> +
> + if(i > 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 {
> + 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];
> + }
> +
> + 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) {
> case ECC_BCH4:
> @@ -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/
> @@ -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).
> void 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 devices
> available\n");
> return;
> }
Please never have the continuation line of a conditional lined up with
the body of the construct.
> @@ -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;
> - 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.
> diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h
> index 8bdd231..6979a2a 100644
> --- a/include/linux/mtd/mtd-abi.h
> +++ b/include/linux/mtd/mtd-abi.h
> @@ -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
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] am335x: NAND: add BCH16 and 4k page size support
2013-01-29 19:54 ` Scott Wood
@ 2013-01-29 20:01 ` Tom Rini
0 siblings, 0 replies; 4+ messages in thread
From: Tom Rini @ 2013-01-29 20:01 UTC (permalink / raw)
To: u-boot
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 01/29/2013 02:54 PM, Scott Wood wrote:
> On 01/28/2013 07:35:40 AM, Jordy van Wolferen wrote:
>> 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).
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).
> 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]
>> diff --git a/include/linux/mtd/mtd-abi.h
>> b/include/linux/mtd/mtd-abi.h index 8bdd231..6979a2a 100644 ---
>> a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h
>> @@ -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.
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-----
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-01-29 20:01 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-28 13:35 [U-Boot] [PATCH] am335x: NAND: add BCH16 and 4k page size support Jordy van Wolferen
2013-01-29 19:54 ` Scott Wood
2013-01-29 20:01 ` Tom Rini
[not found] <1359376558-14035-1-git-send-email-jordyvanwolferen@gmail.com>
2013-01-28 12:55 ` [U-Boot] [PATCH] am335x: NAND, " Jordy van Wolferen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox