
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.devel@googlemail.com Cc: Tom Rini trini@ti.com Cc: Thomas Weber thomas.weber.linux@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;