Hello Andreas, this patch fixes the reported BUG().
The output is now: -----8<--------- OMAP3 DevKit8000 # nandecc hw hamming 1-bit hamming HW ECC selected OMAP3 DevKit8000 # nandecc hw bch8 Unsupported HW ECC algorithm NAND_ECC_NONE selected by board driver. This is not recommended !! OMAP3 DevKit8000 # ----->8--------- Thomas On 04/05/2013 11:52 AM, Andreas Bießmann wrote: > With uppcoming BCH support on OMAP devices we need to decide between differnt > algorithms when switching the ECC engine. Currently we support 1-bit hammign > and 8-bit BCH on HW backend. > > In order to switch between differnet ECC algorithms we need to change the > interface of omap_nand_switch_ecc() also. > > Signed-off-by: Andreas Bießmann <andreas.de...@googlemail.com> > Cc: Tom Rini <tr...@ti.com> > Cc: Thomas Weber <thomas.weber.li...@googlemail.com> > --- > new in v2 > > since v2: > * use void omap_nand_switch_ecc(bool, uint32_t) > * print warning if unknown HW ecc strengs choosen > * fix alignment in help test > > since v3: > * reset ecc.mode to NAND_ECC_NONE to prevent a BUG() on wrong eccstrength > input to changed omap_nand_switch_ecc(); > With this change a user has the chance to switch back to another ECC mode > via nandecc command. > Many thanks to Thomas Weber for reporting this. > > arch/arm/cpu/armv7/omap3/board.c | 31 ++++++++++---- > arch/arm/include/asm/arch-am33xx/sys_proto.h | 2 +- > arch/arm/include/asm/arch-omap3/sys_proto.h | 2 +- > drivers/mtd/nand/omap_gpmc.c | 57 > ++++++++++++++------------ > 4 files changed, 56 insertions(+), 36 deletions(-) > > diff --git a/arch/arm/cpu/armv7/omap3/board.c > b/arch/arm/cpu/armv7/omap3/board.c > index c6d9a42..b72fadc 100644 > --- a/arch/arm/cpu/armv7/omap3/board.c > +++ b/arch/arm/cpu/armv7/omap3/board.c > @@ -328,14 +328,25 @@ void abort(void) > > *****************************************************************************/ > static int do_switch_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char * const > argv[]) > { > - if (argc != 2) > + if (argc < 2 || argc > 3) > goto usage; > - if (strncmp(argv[1], "hw", 2) == 0) > - omap_nand_switch_ecc(1); > - else if (strncmp(argv[1], "sw", 2) == 0) > - omap_nand_switch_ecc(0); > - else > + > + if (strncmp(argv[1], "hw", 2) == 0) { > + if (argc == 2) { > + omap_nand_switch_ecc(1, 1); > + } else { > + if (strncmp(argv[2], "hamming", 7) == 0) > + omap_nand_switch_ecc(1, 1); > + else if (strncmp(argv[2], "bch8", 4) == 0) > + omap_nand_switch_ecc(1, 8); > + else > + goto usage; > + } > + } else if (strncmp(argv[1], "sw", 2) == 0) { > + omap_nand_switch_ecc(0, 0); > + } else { > goto usage; > + } > > return 0; > > @@ -345,9 +356,13 @@ usage: > } > > U_BOOT_CMD( > - nandecc, 2, 1, do_switch_ecc, > + nandecc, 3, 1, do_switch_ecc, > "switch OMAP3 NAND ECC calculation algorithm", > - "[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc > algorithm" > + "hw [hamming|bch8] - Switch between NAND hardware 1-bit hamming and" > + " 8-bit BCH\n" > + " ecc calculation (second parameter may" > + " be omitted).\n" > + "nandecc sw - Switch to NAND software ecc algorithm." > ); > > #endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */ > diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h > b/arch/arm/include/asm/arch-am33xx/sys_proto.h > index 0910a94..c913b5f 100644 > --- a/arch/arm/include/asm/arch-am33xx/sys_proto.h > +++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h > @@ -39,5 +39,5 @@ struct gpmc_cs; > void gpmc_init(void); > void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 > base, > u32 size); > -void omap_nand_switch_ecc(int); > +void omap_nand_switch_ecc(uint32_t, uint32_t); > #endif > diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h > b/arch/arm/include/asm/arch-omap3/sys_proto.h > index d60f2ad..dae1312 100644 > --- a/arch/arm/include/asm/arch-omap3/sys_proto.h > +++ b/arch/arm/include/asm/arch-omap3/sys_proto.h > @@ -78,7 +78,7 @@ void sr32(void *, u32, u32, u32); > u32 wait_on_value(u32, u32, void *, u32); > void sdelay(unsigned long); > void make_cs1_contiguous(void); > -void omap_nand_switch_ecc(int); > +void omap_nand_switch_ecc(uint32_t, uint32_t); > void power_init_r(void); > void dieid_num_r(void); > void do_omap3_emu_romcode_call(u32 service_id, u32 parameters); > diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c > index c7d4999..3468c78 100644 > --- a/drivers/mtd/nand/omap_gpmc.c > +++ b/drivers/mtd/nand/omap_gpmc.c > @@ -604,13 +604,14 @@ static int omap_read_page_bch(struct mtd_info *mtd, > struct nand_chip *chip, > > #ifndef CONFIG_SPL_BUILD > /* > - * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc. > - * The default is to come up on s/w ecc > - * > - * @hardware - 1 -switch to h/w ecc, 0 - s/w ecc > + * omap_nand_switch_ecc - switch the ECC operation between different engines > + * (h/w and s/w) and different algorithms (hamming and BCHx) > * > + * @hardware - true if one of the HW engines should be used > + * @eccstrength - the number of bits that could be corrected > + * (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16) > */ > -void omap_nand_switch_ecc(int32_t hardware) > +void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength) > { > struct nand_chip *nand; > struct mtd_info *mtd; > @@ -628,6 +629,7 @@ void omap_nand_switch_ecc(int32_t hardware) > nand->options |= NAND_OWN_BUFFERS; > > /* Reset ecc interface */ > + nand->ecc.mode = NAND_ECC_NONE; > nand->ecc.read_page = NULL; > nand->ecc.write_page = NULL; > nand->ecc.read_oob = NULL; > @@ -637,28 +639,31 @@ void omap_nand_switch_ecc(int32_t hardware) > nand->ecc.calculate = NULL; > > /* Setup the ecc configurations again */ > - if (hardware == 1) { > - nand->ecc.mode = NAND_ECC_HW; > - nand->ecc.layout = &hw_nand_oob; > - nand->ecc.size = 512; > - nand->ecc.bytes = 3; > - nand->ecc.hwctl = omap_enable_hwecc; > - nand->ecc.correct = omap_correct_data; > - nand->ecc.calculate = omap_calculate_ecc; > - omap_hwecc_init(nand); > - printf("HW ECC selected\n"); > + if (hardware) { > + if (eccstrength == 1) { > + nand->ecc.mode = NAND_ECC_HW; > + nand->ecc.layout = &hw_nand_oob; > + nand->ecc.size = 512; > + nand->ecc.bytes = 3; > + nand->ecc.hwctl = omap_enable_hwecc; > + nand->ecc.correct = omap_correct_data; > + nand->ecc.calculate = omap_calculate_ecc; > + omap_hwecc_init(nand); > + printf("1-bit hamming 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"); > + else if (eccstrength == 8) { > + 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("8-bit BCH HW ECC selected\n"); > + } > #endif > } else { > nand->ecc.mode = NAND_ECC_SOFT; _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot