diff options
| -rw-r--r-- | arch/arm/cpu/armv7/omap3/board.c | 31 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-am33xx/sys_proto.h | 2 | ||||
| -rw-r--r-- | arch/arm/include/asm/arch-omap3/sys_proto.h | 2 | ||||
| -rw-r--r-- | 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 c6d9a425a..b72fadc25 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 0910a9451..c913b5f31 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 d60f2addb..dae131246 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 c7d499990..3468c7805 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; |