diff options
39 files changed, 532 insertions, 220 deletions
| diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile index 966fcab71..5566310d9 100644 --- a/arch/arm/cpu/armv7/am33xx/Makefile +++ b/arch/arm/cpu/armv7/am33xx/Makefile @@ -19,4 +19,3 @@ obj-y	+= ddr.o  obj-y	+= emif4.o  obj-y	+= board.o  obj-y	+= mux.o -obj-$(CONFIG_NAND_OMAP_GPMC)	+= elm.o diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c index b6eb46678..56c9e7dbc 100644 --- a/arch/arm/cpu/armv7/am33xx/mem.c +++ b/arch/arm/cpu/armv7/am33xx/mem.c @@ -22,17 +22,6 @@  struct gpmc *gpmc_cfg; -#if defined(CONFIG_CMD_NAND) -static const u32 gpmc_m_nand[GPMC_MAX_REG] = { -	M_NAND_GPMC_CONFIG1, -	M_NAND_GPMC_CONFIG2, -	M_NAND_GPMC_CONFIG3, -	M_NAND_GPMC_CONFIG4, -	M_NAND_GPMC_CONFIG5, -	M_NAND_GPMC_CONFIG6, 0 -}; -#endif -  void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,  			u32 size) @@ -61,11 +50,34 @@ void gpmc_init(void)  {  	/* putting a blanket check on GPMC based on ZeBu for now */  	gpmc_cfg = (struct gpmc *)GPMC_BASE; - -#ifdef CONFIG_CMD_NAND -	const u32 *gpmc_config = NULL; -	u32 base = 0; +#if defined(CONFIG_NOR) +/* configure GPMC for NOR */ +	const u32 gpmc_regs[GPMC_MAX_REG] = {	STNOR_GPMC_CONFIG1, +						STNOR_GPMC_CONFIG2, +						STNOR_GPMC_CONFIG3, +						STNOR_GPMC_CONFIG4, +						STNOR_GPMC_CONFIG5, +						STNOR_GPMC_CONFIG6, +						STNOR_GPMC_CONFIG7 +						}; +	u32 size = GPMC_SIZE_16M; +	u32 base = CONFIG_SYS_FLASH_BASE; +#elif defined(CONFIG_NAND) +/* configure GPMC for NAND */ +	const u32  gpmc_regs[GPMC_MAX_REG] = {	M_NAND_GPMC_CONFIG1, +						M_NAND_GPMC_CONFIG2, +						M_NAND_GPMC_CONFIG3, +						M_NAND_GPMC_CONFIG4, +						M_NAND_GPMC_CONFIG5, +						M_NAND_GPMC_CONFIG6, +						0 +						}; +	u32 size = GPMC_SIZE_256M; +	u32 base = CONFIG_SYS_NAND_BASE; +#else +	const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };  	u32 size = 0; +	u32 base = 0;  #endif  	/* global settings */  	writel(0x00000008, &gpmc_cfg->sysconfig); @@ -81,12 +93,6 @@ void gpmc_init(void)  	 */  	writel(0, &gpmc_cfg->cs[0].config7);  	sdelay(1000); - -#ifdef CONFIG_CMD_NAND -	gpmc_config = gpmc_m_nand; - -	base = PISMO1_NAND_BASE; -	size = PISMO1_NAND_SIZE; -	enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size); -#endif +	/* enable chip-select specific configurations */ +	enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);  } diff --git a/arch/arm/include/asm/arch-am33xx/mem.h b/arch/arm/include/asm/arch-am33xx/mem.h index 983ea28dc..e7e8c58b0 100644 --- a/arch/arm/include/asm/arch-am33xx/mem.h +++ b/arch/arm/include/asm/arch-am33xx/mem.h @@ -68,9 +68,4 @@  #define PISMO2_NAND_CS0		7  #define PISMO2_NAND_CS1		8 -/* make it readable for the gpmc_init */ -#define PISMO1_NOR_BASE	FLASH_BASE -#define PISMO1_NAND_BASE	CONFIG_SYS_NAND_BASE -#define PISMO1_NAND_SIZE	GPMC_SIZE_256M -  #endif /* endif _MEM_H_ */ diff --git a/arch/arm/include/asm/arch-am33xx/elm.h b/arch/arm/include/asm/omap_elm.h index 45454eaf0..45454eaf0 100644 --- a/arch/arm/include/asm/arch-am33xx/elm.h +++ b/arch/arm/include/asm/omap_elm.h diff --git a/arch/arm/include/asm/omap_gpmc.h b/arch/arm/include/asm/omap_gpmc.h index dd40cb6c1..d4143ecd8 100644 --- a/arch/arm/include/asm/omap_gpmc.h +++ b/arch/arm/include/asm/omap_gpmc.h @@ -68,4 +68,20 @@  }  #endif +enum omap_ecc { +	/* 1-bit  ECC calculation by Software, Error detection by Software */ +	OMAP_ECC_HAM1_CODE_SW = 1, /* avoid un-initialized int can be 0x0 */ +	/* 1-bit  ECC calculation by GPMC, Error detection by Software */ +	/* ECC layout compatible to legacy ROMCODE. */ +	OMAP_ECC_HAM1_CODE_HW, +	/* 4-bit  ECC calculation by GPMC, Error detection by Software */ +	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW, +	/* 4-bit  ECC calculation by GPMC, Error detection by ELM */ +	OMAP_ECC_BCH4_CODE_HW, +	/* 8-bit  ECC calculation by GPMC, Error detection by Software */ +	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW, +	/* 8-bit  ECC calculation by GPMC, Error detection by ELM */ +	OMAP_ECC_BCH8_CODE_HW, +}; +  #endif /* __ASM_OMAP_GPMC_H */ diff --git a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c index 2d0fb433b..64a52258a 100644 --- a/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c +++ b/arch/powerpc/cpu/mpc8xxx/fsl_ifc.c @@ -34,6 +34,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR0_EXT  	set_ifc_cspr_ext(IFC_CS0, CONFIG_SYS_CSPR0_EXT);  #endif +#ifdef CONFIG_SYS_CSOR0_EXT +	set_ifc_csor_ext(IFC_CS0, CONFIG_SYS_CSOR0_EXT); +#endif  	set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0);  	set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0);  	set_ifc_csor(IFC_CS0, CONFIG_SYS_CSOR0); @@ -43,6 +46,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR1_EXT  	set_ifc_cspr_ext(IFC_CS1, CONFIG_SYS_CSPR1_EXT);  #endif +#ifdef CONFIG_SYS_CSOR1_EXT +	set_ifc_csor_ext(IFC_CS1, CONFIG_SYS_CSOR1_EXT); +#endif  #if defined(CONFIG_SYS_CSPR1) && defined(CONFIG_SYS_CSOR1)  	set_ifc_ftim(IFC_CS1, IFC_FTIM0, CONFIG_SYS_CS1_FTIM0);  	set_ifc_ftim(IFC_CS1, IFC_FTIM1, CONFIG_SYS_CS1_FTIM1); @@ -57,6 +63,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR2_EXT  	set_ifc_cspr_ext(IFC_CS2, CONFIG_SYS_CSPR2_EXT);  #endif +#ifdef CONFIG_SYS_CSOR2_EXT +	set_ifc_csor_ext(IFC_CS2, CONFIG_SYS_CSOR2_EXT); +#endif  #if defined(CONFIG_SYS_CSPR2) && defined(CONFIG_SYS_CSOR2)  	set_ifc_ftim(IFC_CS2, IFC_FTIM0, CONFIG_SYS_CS2_FTIM0);  	set_ifc_ftim(IFC_CS2, IFC_FTIM1, CONFIG_SYS_CS2_FTIM1); @@ -71,6 +80,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR3_EXT  	set_ifc_cspr_ext(IFC_CS3, CONFIG_SYS_CSPR3_EXT);  #endif +#ifdef CONFIG_SYS_CSOR3_EXT +	set_ifc_csor_ext(IFC_CS3, CONFIG_SYS_CSOR3_EXT); +#endif  #if defined(CONFIG_SYS_CSPR3) && defined(CONFIG_SYS_CSOR3)  	set_ifc_ftim(IFC_CS3, IFC_FTIM0, CONFIG_SYS_CS3_FTIM0);  	set_ifc_ftim(IFC_CS3, IFC_FTIM1, CONFIG_SYS_CS3_FTIM1); @@ -85,6 +97,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR4_EXT  	set_ifc_cspr_ext(IFC_CS4, CONFIG_SYS_CSPR4_EXT);  #endif +#ifdef CONFIG_SYS_CSOR4_EXT +	set_ifc_csor_ext(IFC_CS4, CONFIG_SYS_CSOR4_EXT); +#endif  #if defined(CONFIG_SYS_CSPR4) && defined(CONFIG_SYS_CSOR4)  	set_ifc_ftim(IFC_CS4, IFC_FTIM0, CONFIG_SYS_CS4_FTIM0);  	set_ifc_ftim(IFC_CS4, IFC_FTIM1, CONFIG_SYS_CS4_FTIM1); @@ -99,6 +114,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR5_EXT  	set_ifc_cspr_ext(IFC_CS5, CONFIG_SYS_CSPR5_EXT);  #endif +#ifdef CONFIG_SYS_CSOR5_EXT +	set_ifc_csor_ext(IFC_CS5, CONFIG_SYS_CSOR5_EXT); +#endif  #if defined(CONFIG_SYS_CSPR5) && defined(CONFIG_SYS_CSOR5)  	set_ifc_ftim(IFC_CS5, IFC_FTIM0, CONFIG_SYS_CS5_FTIM0);  	set_ifc_ftim(IFC_CS5, IFC_FTIM1, CONFIG_SYS_CS5_FTIM1); @@ -113,6 +131,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR6_EXT  	set_ifc_cspr_ext(IFC_CS6, CONFIG_SYS_CSPR6_EXT);  #endif +#ifdef CONFIG_SYS_CSOR6_EXT +	set_ifc_csor_ext(IFC_CS6, CONFIG_SYS_CSOR6_EXT); +#endif  #if defined(CONFIG_SYS_CSPR6) && defined(CONFIG_SYS_CSOR6)  	set_ifc_ftim(IFC_CS6, IFC_FTIM0, CONFIG_SYS_CS6_FTIM0);  	set_ifc_ftim(IFC_CS6, IFC_FTIM1, CONFIG_SYS_CS6_FTIM1); @@ -127,6 +148,9 @@ void init_early_memctl_regs(void)  #ifdef CONFIG_SYS_CSPR7_EXT  	set_ifc_cspr_ext(IFC_CS7, CONFIG_SYS_CSPR7_EXT);  #endif +#ifdef CONFIG_SYS_CSOR7_EXT +	set_ifc_csor_ext(IFC_CS7, CONFIG_SYS_CSOR7_EXT); +#endif  #if defined(CONFIG_SYS_CSPR7) && defined(CONFIG_SYS_CSOR7)  	set_ifc_ftim(IFC_CS7, IFC_FTIM0, CONFIG_SYS_CS7_FTIM0);  	set_ifc_ftim(IFC_CS7, IFC_FTIM1, CONFIG_SYS_CS7_FTIM1); diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index a945e4b2d..182b1a633 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -77,6 +77,7 @@  #define CSOR_NAND_PGS_512		0x00000000  #define CSOR_NAND_PGS_2K		0x00080000  #define CSOR_NAND_PGS_4K		0x00100000 +#define CSOR_NAND_PGS_8K		0x00180000  /* Spare region Size */  #define CSOR_NAND_SPRZ_MASK		0x0000E000  #define CSOR_NAND_SPRZ_SHIFT		13 @@ -86,6 +87,7 @@  #define CSOR_NAND_SPRZ_210		0x00006000  #define CSOR_NAND_SPRZ_218		0x00008000  #define CSOR_NAND_SPRZ_224		0x0000A000 +#define CSOR_NAND_SPRZ_CSOR_EXT	0x0000C000  /* Pages Per Block */  #define CSOR_NAND_PB_MASK		0x00000700  #define CSOR_NAND_PB_SHIFT		8 diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c index b0965ef21..83fd63f54 100644 --- a/board/atmel/sama5d3xek/sama5d3xek.c +++ b/board/atmel/sama5d3xek/sama5d3xek.c @@ -131,7 +131,8 @@ static void sama5d3xek_lcd_hw_init(void)  void lcd_show_board_info(void)  { -	ulong dram_size, nand_size; +	ulong dram_size; +	uint64_t nand_size;  	int i;  	char temp[32]; @@ -150,7 +151,7 @@ void lcd_show_board_info(void)  	for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)  		nand_size += nand_info[i].size;  #endif -	lcd_printf("%ld MB SDRAM, %ld MB NAND\n", +	lcd_printf("%ld MB SDRAM, %lld MB NAND\n",  		   dram_size >> 20, nand_size >> 20);  }  #endif /* CONFIG_LCD_INFO */ diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 8edd21b11..db225ce1d 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -481,26 +481,14 @@ void sdram_init(void)   */  int board_init(void)  { -#ifdef CONFIG_NOR -	const u32 gpmc_nor[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1, -		STNOR_GPMC_CONFIG2, STNOR_GPMC_CONFIG3, STNOR_GPMC_CONFIG4, -		STNOR_GPMC_CONFIG5, STNOR_GPMC_CONFIG6, STNOR_GPMC_CONFIG7 }; -#endif -  #if defined(CONFIG_HW_WATCHDOG)  	hw_watchdog_init();  #endif  	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; - +#if defined(CONFIG_NOR) || defined(CONFIG_NAND)  	gpmc_init(); - -#ifdef CONFIG_NOR -	/* Reconfigure CS0 for NOR instead of NAND. */ -	enable_gpmc_cs_config(gpmc_nor, &gpmc_cfg->cs[0], -			      CONFIG_SYS_FLASH_BASE, GPMC_SIZE_16M);  #endif -  	return 0;  } diff --git a/doc/README.nand b/doc/README.nand index 913e9b50b..b91f1985d 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -104,6 +104,16 @@ Configuration Options:     CONFIG_SYS_MAX_NAND_DEVICE        The maximum number of NAND devices you want to support. +   CONFIG_SYS_NAND_MAX_ECCPOS +      If specified, overrides the maximum number of ECC bytes +      supported.  Useful for reducing image size, especially with SPL. +      This must be at least 48 if nand_base.c is used. + +   CONFIG_SYS_NAND_MAX_OOBFREE +      If specified, overrides the maximum number of free OOB regions +      supported.  Useful for reducing image size, especially with SPL. +      This must be at least 2 if nand_base.c is used. +     CONFIG_SYS_NAND_MAX_CHIPS        The maximum number of NAND chips per device to be supported. @@ -169,6 +179,59 @@ Configuration Options:        Please convert your driver even if you don't need the extra        flexibility, so that one day we can eliminate the old mechanism. + +   CONFIG_SYS_NAND_ONFI_DETECTION +	Enables detection of ONFI compliant devices during probe. +	And fetching device parameters flashed on device, by parsing +	ONFI parameter page. + +   CONFIG_BCH +	Enables software based BCH ECC algorithm present in lib/bch.c +	This is used by SoC platforms which do not have built-in ELM +	hardware engine required for BCH ECC correction. + + +Platform specific options +========================= +   CONFIG_NAND_OMAP_GPMC +	Enables omap_gpmc.c driver for OMAPx and AMxxxx platforms. +	GPMC controller is used for parallel NAND flash devices, and can +	do ECC calculation (not ECC error detection) for HAM1, BCH4, BCH8 +	and BCH16 ECC algorithms. + +   CONFIG_NAND_OMAP_ELM +	Enables omap_elm.c driver for OMAPx and AMxxxx platforms. +	ELM controller is used for ECC error detection (not ECC calculation) +	of BCH4, BCH8 and BCH16 ECC algorithms. +	Some legacy platforms like OMAP3xx do not have in-built ELM h/w engine, +	thus such SoC platforms need to depend on software library for ECC error +	detection. However ECC calculation on such plaforms would still be +	done by GPMC controller. + +   CONFIG_NAND_OMAP_ECCSCHEME +	On OMAP platforms, this CONFIG specifies NAND ECC scheme. +	It can take following values: +	OMAP_ECC_HAM1_CODE_SW +		1-bit Hamming code using software lib. +		(for legacy devices only) +	OMAP_ECC_HAM1_CODE_HW +		1-bit Hamming code using GPMC hardware. +		(for legacy devices only) +	OMAP_ECC_BCH4_CODE_HW_DETECTION_SW +		4-bit BCH code (unsupported) +	OMAP_ECC_BCH4_CODE_HW +		4-bit BCH code (unsupported) +	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW +		8-bit BCH code with +		- ecc calculation using GPMC hardware engine, +		- error detection using software library. +		- requires CONFIG_BCH to enable software BCH library +		(For legacy device which do not have ELM h/w engine) +	OMAP_ECC_BCH8_CODE_HW +		8-bit BCH code with +		- ecc calculation using GPMC hardware engine, +		- error detection using ELM hardware engine. +  NOTE:  ===== diff --git a/doc/README.omap3 b/doc/README.omap3 index 1fbe79db3..a62c35740 100644 --- a/doc/README.omap3 +++ b/doc/README.omap3 @@ -161,8 +161,7 @@ BCH8  To enable hardware assisted BCH8 (8-bit BCH [Bose, Chaudhuri, Hocquenghem]) on  OMAP3 devices we can use the BCH library in lib/bch.c. To do so add CONFIG_BCH -to enable the library and CONFIG_NAND_OMAP_BCH8 to to enable hardware assisted -syndrom generation to your board config. +and set CONFIG_NAND_OMAP_ECCSCHEME=5 (refer README.nand) for selecting BCH8_SW.  The NAND OOB layout is the same as in linux kernel, if the linux kernel BCH8  implementation for OMAP3 works for you so the u-boot version should also.  When you require the SPL to read with BCH8 there are two more configs to diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index eb1eafaf0..e145cd184 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o  obj-$(CONFIG_NAND_SPEAR) += spr_nand.o  obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o  obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o +obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o  obj-$(CONFIG_NAND_PLAT) += nand_plat.o  obj-$(CONFIG_NAND_DOCG4) += docg4.o diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index da83f06e4..16b7df0f7 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -412,7 +412,7 @@ static int pmecc_err_location(struct mtd_info *mtd)  	}  	if (!timeout) { -		printk(KERN_ERR "atmel_nand : Timeout to calculate PMECC error location\n"); +		dev_err(host->dev, "atmel_nand : Timeout to calculate PMECC error location\n");  		return -1;  	} @@ -452,7 +452,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,  			*(buf + byte_pos) ^= (1 << bit_pos);  			pos = sector_num * host->pmecc_sector_size + byte_pos; -			printk(KERN_INFO "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", +			dev_dbg(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",  				pos, bit_pos, err_byte, *(buf + byte_pos));  		} else {  			/* Bit flip in OOB area */ @@ -462,7 +462,7 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,  			ecc[tmp] ^= (1 << bit_pos);  			pos = tmp + nand_chip->ecc.layout->eccpos[0]; -			printk(KERN_INFO "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n", +			dev_dbg(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",  				pos, bit_pos, err_byte, ecc[tmp]);  		} @@ -500,7 +500,7 @@ normal_check:  			err_nbr = pmecc_err_location(mtd);  			if (err_nbr == -1) { -				printk(KERN_ERR "PMECC: Too many errors\n"); +				dev_err(host->dev, "PMECC: Too many errors\n");  				mtd->ecc_stats.failed++;  				return -EIO;  			} else { @@ -544,7 +544,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,  	}  	if (!timeout) { -		printk(KERN_ERR "atmel_nand : Timeout to read PMECC page\n"); +		dev_err(host->dev, "atmel_nand : Timeout to read PMECC page\n");  		return -1;  	} @@ -584,7 +584,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,  	}  	if (!timeout) { -		printk(KERN_ERR "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n"); +		dev_err(host->dev, "atmel_nand : Timeout to read PMECC status, fail to write PMECC in oob\n");  		goto out;  	} @@ -827,6 +827,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,  	switch (mtd->writesize) {  	case 2048:  	case 4096: +	case 8192:  		host->pmecc_degree = (sector_size == 512) ?  			PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14;  		host->pmecc_cw_len = (1 << host->pmecc_degree) - 1; @@ -840,8 +841,15 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,  		nand->ecc.steps = 1;  		nand->ecc.bytes = host->pmecc_bytes_per_sector *  				       host->pmecc_sector_number; + +		if (nand->ecc.bytes > MTD_MAX_ECCPOS_ENTRIES_LARGE) { +			dev_err(host->dev, "too large eccpos entries. max support ecc.bytes is %d\n", +					MTD_MAX_ECCPOS_ENTRIES_LARGE); +			return -EINVAL; +		} +  		if (nand->ecc.bytes > mtd->oobsize - 2) { -			printk(KERN_ERR "No room for ECC bytes\n"); +			dev_err(host->dev, "No room for ECC bytes\n");  			return -EINVAL;  		}  		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo, @@ -852,7 +860,7 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,  	case 512:  	case 1024:  		/* TODO */ -		printk(KERN_ERR "Unsupported page size for PMECC, use Software ECC\n"); +		dev_err(host->dev, "Unsupported page size for PMECC, use Software ECC\n");  	default:  		/* page size not handled by HW ECC */  		/* switching back to soft ECC */ @@ -1035,7 +1043,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,  		/* it doesn't seems to be a freshly  		 * erased block.  		 * We can't correct so many errors */ -		printk(KERN_WARNING "atmel_nand : multiple errors detected." +		dev_warn(host->dev, "atmel_nand : multiple errors detected."  				" Unable to correct.\n");  		return -EIO;  	} @@ -1045,12 +1053,12 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,  		/* there's nothing much to do here.  		 * the bit error is on the ECC itself.  		 */ -		printk(KERN_WARNING "atmel_nand : one bit error on ECC code." +		dev_warn(host->dev, "atmel_nand : one bit error on ECC code."  				" Nothing to correct\n");  		return 0;  	} -	printk(KERN_WARNING "atmel_nand : one bit error on data." +	dev_warn(host->dev, "atmel_nand : one bit error on data."  			" (word offset in the page :"  			" 0x%x bit offset : 0x%x)\n",  			ecc_word, ecc_bit); @@ -1062,7 +1070,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat,  		/* 8 bits words */  		dat[ecc_word] ^= (1 << ecc_bit);  	} -	printk(KERN_WARNING "atmel_nand : error corrected\n"); +	dev_warn(host->dev, "atmel_nand : error corrected\n");  	return 1;  } @@ -1178,7 +1186,11 @@ int atmel_nand_chip_init(int devnum, ulong base_addr)  	mtd->priv = nand;  	nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr; +#ifdef CONFIG_NAND_ECC_BCH +	nand->ecc.mode = NAND_ECC_SOFT_BCH; +#else  	nand->ecc.mode = NAND_ECC_SOFT; +#endif  #ifdef CONFIG_SYS_NAND_DBW_16  	nand->options = NAND_BUSWIDTH_16;  #endif @@ -1186,7 +1198,7 @@ int atmel_nand_chip_init(int devnum, ulong base_addr)  #ifdef CONFIG_SYS_NAND_READY_PIN  	nand->dev_ready = at91_nand_ready;  #endif -	nand->chip_delay = 20; +	nand->chip_delay = 75;  	ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);  	if (ret) @@ -1214,6 +1226,6 @@ void board_nand_init(void)  	int i;  	for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)  		if (atmel_nand_chip_init(i, base_addr[i])) -			printk(KERN_ERR "atmel_nand: Fail to initialize #%d chip", +			dev_err(host->dev, "atmel_nand: Fail to initialize #%d chip",  				i);  } diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 98a09c064..49b63af85 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c @@ -125,6 +125,69 @@ static struct nand_ecclayout oob_4096_ecc8 = {  	.oobfree = { {2, 6}, {136, 82} },  }; +/* 8192-byte page size with 4-bit ECC */ +static struct nand_ecclayout oob_8192_ecc4 = { +	.eccbytes = 128, +	.eccpos = { +		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, +	}, +	.oobfree = { {2, 6}, {136, 208} }, +}; + +/* 8192-byte page size with 8-bit ECC -- requires 218-byte OOB */ +static struct nand_ecclayout oob_8192_ecc8 = { +	.eccbytes = 256, +	.eccpos = { +		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, 210, 211, 212, 213, 214, 215, +		216, 217, 218, 219, 220, 221, 222, 223, +		224, 225, 226, 227, 228, 229, 230, 231, +		232, 233, 234, 235, 236, 237, 238, 239, +		240, 241, 242, 243, 244, 245, 246, 247, +		248, 249, 250, 251, 252, 253, 254, 255, +		256, 257, 258, 259, 260, 261, 262, 263, +	}, +	.oobfree = { {2, 6}, {264, 80} }, +};  /*   * Generic flash bbt descriptors @@ -428,20 +491,27 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,  		if (mtd->writesize > 512) {  			nand_fcr0 =  				(NAND_CMD_SEQIN << IFC_NAND_FCR0_CMD0_SHIFT) | -				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD1_SHIFT); +				(NAND_CMD_STATUS << IFC_NAND_FCR0_CMD1_SHIFT) | +				(NAND_CMD_PAGEPROG << IFC_NAND_FCR0_CMD2_SHIFT);  			out_be32(&ifc->ifc_nand.nand_fir0,  				 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) |  				 (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) |  				 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) |  				 (IFC_FIR_OP_WBCD  << IFC_NAND_FIR0_OP3_SHIFT) | -				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR0_OP4_SHIFT)); -			out_be32(&ifc->ifc_nand.nand_fir1, 0); +				 (IFC_FIR_OP_CMD2 << IFC_NAND_FIR0_OP4_SHIFT)); +			out_be32(&ifc->ifc_nand.nand_fir1, +				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT) | +				 (IFC_FIR_OP_RDSTAT << +					IFC_NAND_FIR1_OP6_SHIFT) | +				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP7_SHIFT));  		} else {  			nand_fcr0 = ((NAND_CMD_PAGEPROG <<  					IFC_NAND_FCR0_CMD1_SHIFT) |  				    (NAND_CMD_SEQIN << -					IFC_NAND_FCR0_CMD2_SHIFT)); +					IFC_NAND_FCR0_CMD2_SHIFT) | +				    (NAND_CMD_STATUS << +					IFC_NAND_FCR0_CMD3_SHIFT));  			out_be32(&ifc->ifc_nand.nand_fir0,  				 (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | @@ -450,7 +520,11 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,  				 (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP3_SHIFT) |  				 (IFC_FIR_OP_WBCD << IFC_NAND_FIR0_OP4_SHIFT));  			out_be32(&ifc->ifc_nand.nand_fir1, -				 (IFC_FIR_OP_CW1 << IFC_NAND_FIR1_OP5_SHIFT)); +				 (IFC_FIR_OP_CMD1 << IFC_NAND_FIR1_OP5_SHIFT) | +				 (IFC_FIR_OP_CW3 << IFC_NAND_FIR1_OP6_SHIFT) | +				 (IFC_FIR_OP_RDSTAT << +					IFC_NAND_FIR1_OP7_SHIFT) | +				 (IFC_FIR_OP_NOP << IFC_NAND_FIR1_OP8_SHIFT));  			if (column >= mtd->writesize)  				nand_fcr0 |= @@ -902,6 +976,21 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)  		priv->bufnum_mask = 1;  		break; +	case CSOR_NAND_PGS_8K: +		if ((csor & CSOR_NAND_ECC_MODE_MASK) == +		    CSOR_NAND_ECC_MODE_4) { +			layout = &oob_8192_ecc4; +			nand->ecc.strength = 4; +		} else { +			layout = &oob_8192_ecc8; +			nand->ecc.strength = 8; +			nand->ecc.bytes = 16; +		} + +		priv->bufnum_mask = 0; +		break; + +  	default:  		printf("ifc nand: bad csor %#x: bad page size\n", csor);  		return -ENODEV; diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c index d4622653f..9fa5ccbc5 100644 --- a/drivers/mtd/nand/fsl_ifc_spl.c +++ b/drivers/mtd/nand/fsl_ifc_spl.c @@ -112,10 +112,13 @@ static void nand_load(unsigned int offs, int uboot_size, uchar *dst)  	port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8; -	if (csor & CSOR_NAND_PGS_4K) { +	if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_8K) { +		page_size = 8192; +		bufnum_mask = 0x0; +	} else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_4K) {  		page_size = 4096;  		bufnum_mask = 0x1; -	} else if (csor & CSOR_NAND_PGS_2K) { +	} else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_2K) {  		page_size = 2048;  		bufnum_mask = 0x3;  	} else { diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/drivers/mtd/nand/omap_elm.c index 8f1d6afdd..2aa7807f3 100644 --- a/arch/arm/cpu/armv7/am33xx/elm.c +++ b/drivers/mtd/nand/omap_elm.c @@ -18,7 +18,7 @@  #include <asm/errno.h>  #include <asm/arch/cpu.h>  #include <asm/omap_gpmc.h> -#include <asm/arch/elm.h> +#include <asm/omap_elm.h>  #define ELM_DEFAULT_POLY (0) @@ -127,7 +127,7 @@ int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,  	for (i = 0; i < *error_count; i++) {  		error_locations[i] = -			readl(&elm_cfg->error_location[poly].error_location_x[i]); +		     readl(&elm_cfg->error_location[poly].error_location_x[i]);  	}  	return 0; @@ -175,7 +175,7 @@ void elm_reset(void)  {  	/* initiate reset */  	writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET), -				&elm_cfg->sysconfig); +			&elm_cfg->sysconfig);  	/* wait for reset complete and normal operation */  	while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) != diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index ec1787f22..5e7e6b337 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -15,15 +15,13 @@  #include <linux/bch.h>  #include <linux/compiler.h>  #include <nand.h> -#ifdef CONFIG_AM33XX -#include <asm/arch/elm.h> -#endif +#include <asm/omap_elm.h> + +#define BADBLOCK_MARKER_LENGTH	2 +#define SECTOR_BYTES		512  static uint8_t cs; -static __maybe_unused struct nand_ecclayout hw_nand_oob = -	GPMC_NAND_HW_ECC_LAYOUT; -static __maybe_unused struct nand_ecclayout hw_bch8_nand_oob = -	GPMC_NAND_HW_BCH8_ECC_LAYOUT; +static __maybe_unused struct nand_ecclayout omap_ecclayout;  /*   * omap_nand_hwcontrol - Set the address pointers corretly for the @@ -233,6 +231,7 @@ struct nand_bch_priv {  	uint8_t type;  	uint8_t nibbles;  	struct bch_control *control; +	enum omap_ecc ecc_scheme;  };  /* bch types */ @@ -274,17 +273,15 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)  {  	uint32_t val;  	uint32_t dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1; -#ifdef CONFIG_AM33XX  	uint32_t unused_length = 0; -#endif  	uint32_t wr_mode = BCH_WRAPMODE_6;  	struct nand_bch_priv *bch = chip->priv;  	/* Clear the ecc result registers, select ecc reg as 1 */  	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control); -#ifdef CONFIG_AM33XX -	wr_mode = BCH_WRAPMODE_1; +	if (bch->ecc_scheme == OMAP_ECC_BCH8_CODE_HW) { +		wr_mode = BCH_WRAPMODE_1;  	switch (bch->nibbles) {  	case ECC_BCH4_NIBBLES: @@ -320,7 +317,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)  		val |= (unused_length << 22);  		break;  	} -#else +	} else {  	/*  	 * This ecc_size_config setting is for BCH sw library.  	 * @@ -333,7 +330,7 @@ static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)  	 *  size1 = 32 (skip 32 nibbles = 16 bytes per sector in spare area)  	 */  	val = (32 << 22) | (0 << 12); -#endif +	}  	/* ecc size configuration */  	writel(val, &gpmc_cfg->ecc_size_config); @@ -376,9 +373,9 @@ static void __maybe_unused omap_ecc_disable(struct mtd_info *mtd)  }  /* - * BCH8 support (needs ELM and thus AM33xx-only) + * BCH support using ELM module   */ -#ifdef CONFIG_AM33XX +#ifdef CONFIG_NAND_OMAP_ELM  /*   * omap_read_bch8_result - Read BCH result for BCH8 level   * @@ -631,20 +628,20 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,  	}  	return 0;  } -#endif /* CONFIG_AM33XX */ +#endif /* CONFIG_NAND_OMAP_ELM */  /*   * OMAP3 BCH8 support (with BCH library)   */ -#ifdef CONFIG_NAND_OMAP_BCH8 +#ifdef CONFIG_BCH  /* - *  omap_calculate_ecc_bch - Read BCH ECC result + *  omap_calculate_ecc_bch_sw - Read BCH ECC result   *   *  @mtd:	MTD device structure   *  @dat:	The pointer to data on which ecc is computed (unused here)   *  @ecc:	The ECC output buffer   */ -static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat, +static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd, const uint8_t *dat,  				uint8_t *ecc)  {  	int ret = 0; @@ -689,13 +686,13 @@ static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,  }  /** - * omap_correct_data_bch - Decode received data and correct errors + * omap_correct_data_bch_sw - Decode received data and correct errors   * @mtd: MTD device structure   * @data: page data   * @read_ecc: ecc read from nand flash   * @calc_ecc: ecc read from HW ECC registers   */ -static int omap_correct_data_bch(struct mtd_info *mtd, u_char *data, +static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,  				 u_char *read_ecc, u_char *calc_ecc)  {  	int i, count; @@ -752,7 +749,150 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)  		chip_priv->control = NULL;  	}  } -#endif /* CONFIG_NAND_OMAP_BCH8 */ +#endif /* CONFIG_BCH */ + +/** + * omap_select_ecc_scheme - configures driver for particular ecc-scheme + * @nand: NAND chip device structure + * @ecc_scheme: ecc scheme to configure + * @pagesize: number of main-area bytes per page of NAND device + * @oobsize: number of OOB/spare bytes per page of NAND device + */ +static int omap_select_ecc_scheme(struct nand_chip *nand, +	enum omap_ecc ecc_scheme, unsigned int pagesize, unsigned int oobsize) { +	struct nand_bch_priv	*bch		= nand->priv; +	struct nand_ecclayout	*ecclayout	= nand->ecc.layout; +	int eccsteps = pagesize / SECTOR_BYTES; +	int i; + +	switch (ecc_scheme) { +	case OMAP_ECC_HAM1_CODE_SW: +		debug("nand: selected OMAP_ECC_HAM1_CODE_SW\n"); +		/* For this ecc-scheme, ecc.bytes, ecc.layout, ... are +		 * initialized in nand_scan_tail(), so just set ecc.mode */ +		bch_priv.control	= NULL; +		bch_priv.type		= 0; +		nand->ecc.mode		= NAND_ECC_SOFT; +		nand->ecc.layout	= NULL; +		nand->ecc.size		= pagesize; +		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_SW; +		break; + +	case OMAP_ECC_HAM1_CODE_HW: +		debug("nand: selected OMAP_ECC_HAM1_CODE_HW\n"); +		/* check ecc-scheme requirements before updating ecc info */ +		if ((3 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) { +			printf("nand: error: insufficient OOB: require=%d\n", ( +				(3 * eccsteps) + BADBLOCK_MARKER_LENGTH)); +			return -EINVAL; +		} +		bch_priv.control	= NULL; +		bch_priv.type		= 0; +		/* populate ecc specific fields */ +		nand->ecc.mode		= NAND_ECC_HW; +		nand->ecc.strength	= 1; +		nand->ecc.size		= SECTOR_BYTES; +		nand->ecc.bytes		= 3; +		nand->ecc.hwctl		= omap_enable_hwecc; +		nand->ecc.correct	= omap_correct_data; +		nand->ecc.calculate	= omap_calculate_ecc; +		/* define ecc-layout */ +		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps; +		for (i = 0; i < ecclayout->eccbytes; i++) +			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH; +		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH; +		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes - +						BADBLOCK_MARKER_LENGTH; +		bch->ecc_scheme		= OMAP_ECC_HAM1_CODE_HW; +		break; + +	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: +#ifdef CONFIG_BCH +		debug("nand: selected OMAP_ECC_BCH8_CODE_HW_DETECTION_SW\n"); +		/* check ecc-scheme requirements before updating ecc info */ +		if ((13 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) { +			printf("nand: error: insufficient OOB: require=%d\n", ( +				(13 * eccsteps) + BADBLOCK_MARKER_LENGTH)); +			return -EINVAL; +		} +		/* check if BCH S/W library can be used for error detection */ +		bch_priv.control = init_bch(13, 8, 0x201b); +		if (!bch_priv.control) { +			printf("nand: error: could not init_bch()\n"); +			return -ENODEV; +		} +		bch_priv.type = ECC_BCH8; +		/* populate ecc specific fields */ +		nand->ecc.mode		= NAND_ECC_HW; +		nand->ecc.strength	= 8; +		nand->ecc.size		= SECTOR_BYTES; +		nand->ecc.bytes		= 13; +		nand->ecc.hwctl		= omap_enable_ecc_bch; +		nand->ecc.correct	= omap_correct_data_bch_sw; +		nand->ecc.calculate	= omap_calculate_ecc_bch_sw; +		/* define ecc-layout */ +		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps; +		ecclayout->eccpos[0]	= BADBLOCK_MARKER_LENGTH; +		for (i = 1; i < ecclayout->eccbytes; i++) { +			if (i % nand->ecc.bytes) +				ecclayout->eccpos[i] = +						ecclayout->eccpos[i - 1] + 1; +			else +				ecclayout->eccpos[i] = +						ecclayout->eccpos[i - 1] + 2; +		} +		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH; +		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes - +						BADBLOCK_MARKER_LENGTH; +		omap_hwecc_init_bch(nand, NAND_ECC_READ); +		bch->ecc_scheme		= OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; +		break; +#else +		printf("nand: error: CONFIG_BCH required for ECC\n"); +		return -EINVAL; +#endif + +	case OMAP_ECC_BCH8_CODE_HW: +#ifdef CONFIG_NAND_OMAP_ELM +		debug("nand: selected OMAP_ECC_BCH8_CODE_HW\n"); +		/* check ecc-scheme requirements before updating ecc info */ +		if ((14 * eccsteps) + BADBLOCK_MARKER_LENGTH > oobsize) { +			printf("nand: error: insufficient OOB: require=%d\n", ( +				(14 * eccsteps) + BADBLOCK_MARKER_LENGTH)); +			return -EINVAL; +		} +		/* intialize ELM for ECC error detection */ +		elm_init(); +		bch_priv.type		= ECC_BCH8; +		/* populate ecc specific fields */ +		nand->ecc.mode		= NAND_ECC_HW; +		nand->ecc.strength	= 8; +		nand->ecc.size		= SECTOR_BYTES; +		nand->ecc.bytes		= 14; +		nand->ecc.hwctl		= omap_enable_ecc_bch; +		nand->ecc.correct	= omap_correct_data_bch; +		nand->ecc.calculate	= omap_calculate_ecc_bch; +		nand->ecc.read_page	= omap_read_page_bch; +		/* define ecc-layout */ +		ecclayout->eccbytes	= nand->ecc.bytes * eccsteps; +		for (i = 0; i < ecclayout->eccbytes; i++) +			ecclayout->eccpos[i] = i + BADBLOCK_MARKER_LENGTH; +		ecclayout->oobfree[0].offset = i + BADBLOCK_MARKER_LENGTH; +		ecclayout->oobfree[0].length = oobsize - ecclayout->eccbytes - +						BADBLOCK_MARKER_LENGTH; +		bch->ecc_scheme		= OMAP_ECC_BCH8_CODE_HW; +		break; +#else +		printf("nand: error: CONFIG_NAND_OMAP_ELM required for ECC\n"); +		return -EINVAL; +#endif + +	default: +		debug("nand: error: ecc scheme not enabled or supported\n"); +		return -EINVAL; +	} +	return 0; +}  #ifndef CONFIG_SPL_BUILD  /* @@ -763,77 +903,45 @@ static void __maybe_unused omap_free_bch(struct mtd_info *mtd)   * @eccstrength		- the number of bits that could be corrected   *			  (1 - hamming, 4 - BCH4, 8 - BCH8, 16 - BCH16)   */ -void omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength) +int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)  {  	struct nand_chip *nand;  	struct mtd_info *mtd; +	int err = 0;  	if (nand_curr_device < 0 ||  	    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; +		printf("nand: error: no NAND devices found\n"); +		return -ENODEV;  	}  	mtd = &nand_info[nand_curr_device];  	nand = mtd->priv; -  	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; -	nand->ecc.write_oob = NULL; -	nand->ecc.hwctl = NULL; -	nand->ecc.correct = NULL; -	nand->ecc.calculate = NULL; -	nand->ecc.strength = eccstrength; -  	/* Setup the ecc configurations again */  	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"); -		} -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) -		else if (eccstrength == 8) { -			nand->ecc.mode = NAND_ECC_HW; -			nand->ecc.layout = &hw_bch8_nand_oob; -			nand->ecc.size = 512; -#ifdef CONFIG_AM33XX -			nand->ecc.bytes = 14; -			nand->ecc.read_page = omap_read_page_bch; -#else -			nand->ecc.bytes = 13; -#endif -			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"); +			err = omap_select_ecc_scheme(nand, +					OMAP_ECC_HAM1_CODE_HW, +					mtd->writesize, mtd->oobsize); +		} else if (eccstrength == 8) { +			err = omap_select_ecc_scheme(nand, +					OMAP_ECC_BCH8_CODE_HW, +					mtd->writesize, mtd->oobsize); +		} else { +			printf("nand: error: unsupported ECC scheme\n"); +			return -EINVAL;  		} -#endif  	} else { -		nand->ecc.mode = NAND_ECC_SOFT; -		/* Use mtd default settings */ -		nand->ecc.layout = NULL; -		nand->ecc.size = 0; -		printf("SW ECC selected\n"); +		err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW, +					mtd->writesize, mtd->oobsize);  	}  	/* Update NAND handling after ECC mode switch */ -	nand_scan_tail(mtd); - -	nand->options &= ~NAND_OWN_BUFFERS; +	if (!err) +		err = nand_scan_tail(mtd); +	return err;  }  #endif /* CONFIG_SPL_BUILD */ @@ -856,7 +964,7 @@ int board_nand_init(struct nand_chip *nand)  {  	int32_t gpmc_config = 0;  	cs = 0; - +	int err = 0;  	/*  	 * xloader/Uboot's gpmc configuration would have configured GPMC for  	 * nand type of memory. The following logic scans and latches on to the @@ -873,7 +981,7 @@ int board_nand_init(struct nand_chip *nand)  		cs++;  	}  	if (cs >= GPMC_MAX_CS) { -		printf("NAND: Unable to find NAND settings in " +		printf("nand: error: Unable to find NAND settings in "  			"GPMC Configuration - quitting\n");  		return -ENODEV;  	} @@ -885,64 +993,27 @@ int board_nand_init(struct nand_chip *nand)  	nand->IO_ADDR_R = (void __iomem *)&gpmc_cfg->cs[cs].nand_dat;  	nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd; - -	nand->cmd_ctrl = omap_nand_hwcontrol; -	nand->options = NAND_NO_PADDING | NAND_CACHEPRG; +	nand->priv	= &bch_priv; +	nand->cmd_ctrl	= omap_nand_hwcontrol; +	nand->options	|= NAND_NO_PADDING | NAND_CACHEPRG;  	/* If we are 16 bit dev, our gpmc config tells us that */  	if ((readl(&gpmc_cfg->cs[cs].config1) & 0x3000) == 0x1000)  		nand->options |= NAND_BUSWIDTH_16;  	nand->chip_delay = 100; +	nand->ecc.layout = &omap_ecclayout; -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) -#ifdef CONFIG_AM33XX -	/* AM33xx uses the ELM */ -	/* required in case of BCH */ -	elm_init(); -#else -	/* -	 * Whereas other OMAP based SoC do not have the ELM, they use the BCH -	 * SW library. -	 */ -	bch_priv.control = init_bch(13, 8, 0x201b /* hw polynominal */); -	if (!bch_priv.control) { -		puts("Could not init_bch()\n"); -		return -ENODEV; -	} -#endif -	/* BCH info that will be correct for SPL or overridden otherwise. */ -	nand->priv = &bch_priv; -#endif - -	/* Default ECC mode */ -#if defined(CONFIG_AM33XX) || defined(CONFIG_NAND_OMAP_BCH8) -	nand->ecc.mode = NAND_ECC_HW; -	nand->ecc.layout = &hw_bch8_nand_oob; -	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; -	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; -	nand->ecc.strength = 8; -	nand->ecc.hwctl = omap_enable_ecc_bch; -	nand->ecc.correct = omap_correct_data_bch; -	nand->ecc.calculate = omap_calculate_ecc_bch; -#ifdef CONFIG_AM33XX -	nand->ecc.read_page = omap_read_page_bch; -#endif -	omap_hwecc_init_bch(nand, NAND_ECC_READ); -#else -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC) -	nand->ecc.mode = NAND_ECC_SOFT; +	/* select ECC scheme */ +#if defined(CONFIG_NAND_OMAP_ECCSCHEME) +	err = omap_select_ecc_scheme(nand, CONFIG_NAND_OMAP_ECCSCHEME, +			CONFIG_SYS_NAND_PAGE_SIZE, CONFIG_SYS_NAND_OOBSIZE);  #else -	nand->ecc.mode = NAND_ECC_HW; -	nand->ecc.layout = &hw_nand_oob; -	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE; -	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES; -	nand->ecc.hwctl = omap_enable_hwecc; -	nand->ecc.correct = omap_correct_data; -	nand->ecc.calculate = omap_calculate_ecc; -	nand->ecc.strength = 1; -	omap_hwecc_init(nand); -#endif +	/* pagesize and oobsize are not required to configure sw ecc-scheme */ +	err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW, +			0, 0);  #endif +	if (err) +		return err;  #ifdef CONFIG_SPL_BUILD  	if (nand->options & NAND_BUSWIDTH_16) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 067f8ef18..979e4af7c 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -761,7 +761,8 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf,  	uint8_t *oob_buf = this->oob_buf;  	free = this->ecclayout->oobfree; -	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; +	     i++, free++) {  		if (readcol >= lastgap)  			readcol += free->offset - lastgap;  		if (readend >= lastgap) @@ -770,7 +771,8 @@ static int onenand_transfer_auto_oob(struct mtd_info *mtd, uint8_t *buf,  	}  	this->read_bufferram(mtd, 0, ONENAND_SPARERAM, oob_buf, 0, mtd->oobsize);  	free = this->ecclayout->oobfree; -	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; +	     i++, free++) {  		int free_end = free->offset + free->length;  		if (free->offset < readend && free_end > readcol) {  			int st = max_t(int,free->offset,readcol); @@ -1356,7 +1358,8 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,  	unsigned int i;  	free = this->ecclayout->oobfree; -	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; +	     i++, free++) {  		if (writecol >= lastgap)  			writecol += free->offset - lastgap;  		if (writeend >= lastgap) @@ -1364,7 +1367,8 @@ static int onenand_fill_auto_oob(struct mtd_info *mtd, u_char *oob_buf,  		lastgap = free->offset + free->length;  	}  	free = this->ecclayout->oobfree; -	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && free->length; i++, free++) { +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE && free->length; +	     i++, free++) {  		int free_end = free->offset + free->length;  		if (free->offset < writeend && free_end > writecol) {  			int st = max_t(int,free->offset,writecol); @@ -2750,7 +2754,8 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)  	 * the out of band area  	 */  	this->ecclayout->oobavail = 0; -	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES && + +	for (i = 0; i < MTD_MAX_OOBFREE_ENTRIES_LARGE &&  	    this->ecclayout->oobfree[i].length; i++)  		this->ecclayout->oobavail +=  			this->ecclayout->oobfree[i].length; diff --git a/include/configs/ASH405.h b/include/configs/ASH405.h index 9460be3b5..2f5340723 100644 --- a/include/configs/ASH405.h +++ b/include/configs/ASH405.h @@ -143,6 +143,8 @@  #define CONFIG_SYS_NAND_SKIP_BAD_DOT_I	1	/* ".i" read skips bad blocks   */  #define CONFIG_SYS_NAND_QUIET		1 +#define CONFIG_SYS_NAND_MAX_OOBFREE	2 +#define CONFIG_SYS_NAND_MAX_ECCPOS	56  /*-----------------------------------------------------------------------   * PCI stuff diff --git a/include/configs/C29XPCIE.h b/include/configs/C29XPCIE.h index 08156c531..bb1574537 100644 --- a/include/configs/C29XPCIE.h +++ b/include/configs/C29XPCIE.h @@ -191,13 +191,14 @@  				| CSPR_MSEL_NAND \  				| CSPR_V)  #define CONFIG_SYS_NAND_AMASK	IFC_AMASK(64*1024) +#define CONFIG_SYS_NAND_OOBSIZE	0x00000280	/* 640b */  #define CONFIG_SYS_NAND_CSOR	(CSOR_NAND_ECC_ENC_EN	/* ECC on encode */ \  				| CSOR_NAND_ECC_DEC_EN	/* ECC on decode */ \  				| CSOR_NAND_ECC_MODE_4	/* 4-bit ECC */ \ -				| CSOR_NAND_RAL_2	/* RAL = 2 Bytes */ \ -				| CSOR_NAND_PGS_2K	/* Page Size = 2k */ \ -				| CSOR_NAND_SPRZ_64	/* Spare size = 64 */ \ -				| CSOR_NAND_PB(64))	/* 64 Pages Per Block */ +				| CSOR_NAND_RAL_3	/* RAL = 3 Bytes */ \ +				| CSOR_NAND_PGS_8K	/* Page Size = 8K */ \ +				| CSOR_NAND_SPRZ_CSOR_EXT /*oob in csor_ext*/\ +				| CSOR_NAND_PB(128))	/*128 Pages Per Block*/  #define CONFIG_SYS_NAND_FTIM0	(FTIM0_NAND_TCCST(0x01) | \  				FTIM0_NAND_TWP(0x0c)   | \  				FTIM0_NAND_TWCHT(0x08) | \ @@ -224,6 +225,7 @@  #define CONFIG_SYS_CSPR1		CONFIG_SYS_NAND_CSPR  #define CONFIG_SYS_AMASK1		CONFIG_SYS_NAND_AMASK  #define CONFIG_SYS_CSOR1		CONFIG_SYS_NAND_CSOR +#define CONFIG_SYS_CSOR1_EXT		CONFIG_SYS_NAND_OOBSIZE  #define CONFIG_SYS_CS1_FTIM0		CONFIG_SYS_NAND_FTIM0  #define CONFIG_SYS_CS1_FTIM1		CONFIG_SYS_NAND_FTIM1  #define CONFIG_SYS_CS1_FTIM2		CONFIG_SYS_NAND_FTIM2 diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index c7511449e..9ad94021e 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -322,6 +322,8 @@  #define CONFIG_CMD_NAND		1  #define CONFIG_NAND_FSL_ELBC	1  #define CONFIG_SYS_NAND_BLOCK_SIZE    (128 * 1024) +#define CONFIG_SYS_NAND_MAX_OOBFREE	5 +#define CONFIG_SYS_NAND_MAX_ECCPOS	56  /* NAND boot: 4K NAND loader config */  #define CONFIG_SYS_NAND_SPL_SIZE	0x1000 diff --git a/include/configs/T4240QDS.h b/include/configs/T4240QDS.h index 3777ccb83..c96df54d9 100644 --- a/include/configs/T4240QDS.h +++ b/include/configs/T4240QDS.h @@ -229,6 +229,8 @@ unsigned long get_board_ddr_clk(void);  #define CONFIG_CMD_NAND  #define CONFIG_SYS_NAND_BLOCK_SIZE	(128 * 1024) +#define CONFIG_SYS_NAND_MAX_OOBFREE	2 +#define CONFIG_SYS_NAND_MAX_ECCPOS	256  #if defined(CONFIG_NAND)  #define CONFIG_SYS_CSPR0_EXT		CONFIG_SYS_NAND_CSPR_EXT diff --git a/include/configs/alpr.h b/include/configs/alpr.h index 2bf1986e3..61fdebac3 100644 --- a/include/configs/alpr.h +++ b/include/configs/alpr.h @@ -324,6 +324,8 @@  #define CONFIG_SYS_NAND_BASE_LIST	{ CONFIG_SYS_NAND_BASE + 0, CONFIG_SYS_NAND_BASE + 2,	\  				  CONFIG_SYS_NAND_BASE + 4, CONFIG_SYS_NAND_BASE + 6 }  #define CONFIG_SYS_NAND_QUIET_TEST	1	/* don't warn upon unknown NAND flash	*/ +#define CONFIG_SYS_NAND_MAX_OOBFREE	2 +#define CONFIG_SYS_NAND_MAX_ECCPOS	56  /*-----------------------------------------------------------------------   * External Bus Controller (EBC) Setup diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h index f35ed6fba..d75df9279 100644 --- a/include/configs/am335x_evm.h +++ b/include/configs/am335x_evm.h @@ -220,6 +220,8 @@  #define CONFIG_SPL_LDSCRIPT		"$(CPUDIR)/am33xx/u-boot-spl.lds"  #ifdef CONFIG_NAND +#define CONFIG_NAND_OMAP_GPMC +#define CONFIG_NAND_OMAP_ELM  #define CONFIG_SYS_NAND_5_ADDR_CYCLE  #define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \  					 CONFIG_SYS_NAND_PAGE_SIZE) @@ -237,7 +239,8 @@  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	14 - +#define CONFIG_SYS_NAND_ONFI_DETECTION +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000  #endif diff --git a/include/configs/am335x_igep0033.h b/include/configs/am335x_igep0033.h index 2c69d4e30..115d1b37c 100644 --- a/include/configs/am335x_igep0033.h +++ b/include/configs/am335x_igep0033.h @@ -187,6 +187,7 @@  /* NAND support */  #define CONFIG_NAND  #define CONFIG_NAND_OMAP_GPMC +#define CONFIG_NAND_OMAP_ELM  #define GPMC_NAND_ECC_LP_x16_LAYOUT	1  #define CONFIG_SYS_NAND_BASE		(0x08000000)	/* phys address CS0 */  #define CONFIG_SYS_MAX_NAND_DEVICE	1 @@ -263,6 +264,7 @@  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	14 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW  #define	CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE diff --git a/include/configs/am3517_crane.h b/include/configs/am3517_crane.h index 6fd3fb904..468fb43ea 100644 --- a/include/configs/am3517_crane.h +++ b/include/configs/am3517_crane.h @@ -340,6 +340,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/am3517_evm.h b/include/configs/am3517_evm.h index 7e9c55edf..a3473b51b 100644 --- a/include/configs/am3517_evm.h +++ b/include/configs/am3517_evm.h @@ -334,6 +334,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h index 474a5687a..4f43ba988 100644 --- a/include/configs/devkit8000.h +++ b/include/configs/devkit8000.h @@ -327,6 +327,7 @@  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_TEXT_BASE diff --git a/include/configs/mcx.h b/include/configs/mcx.h index a2f7cf711..dcd29ce7c 100644 --- a/include/configs/mcx.h +++ b/include/configs/mcx.h @@ -353,7 +353,6 @@  #define CONFIG_SPL_FRAMEWORK  #define CONFIG_SPL_BOARD_INIT  #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_SOFTECC  #define CONFIG_SPL_LIBCOMMON_SUPPORT  #define CONFIG_SPL_LIBDISK_SUPPORT @@ -395,6 +394,7 @@  					 56, 57, 58, 59, 60, 61, 62, 63}  #define CONFIG_SYS_NAND_ECCSIZE		256  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_SW  #define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_TEXT_BASE diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h index bba39d428..9eab1903f 100644 --- a/include/configs/omap3_beagle.h +++ b/include/configs/omap3_beagle.h @@ -431,6 +431,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h index 3ace8bb6e..b7638fb8a 100644 --- a/include/configs/omap3_evm.h +++ b/include/configs/omap3_evm.h @@ -107,6 +107,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/omap3_evm_quick_nand.h b/include/configs/omap3_evm_quick_nand.h index 9ecd70d55..4427e88b7 100644 --- a/include/configs/omap3_evm_quick_nand.h +++ b/include/configs/omap3_evm_quick_nand.h @@ -86,6 +86,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h index 75d7d70d2..71062a601 100644 --- a/include/configs/omap3_igep00x0.h +++ b/include/configs/omap3_igep00x0.h @@ -362,6 +362,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000  #endif diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h index 84b4aeee2..e0f026269 100644 --- a/include/configs/omap3_overo.h +++ b/include/configs/omap3_overo.h @@ -324,6 +324,7 @@  						10, 11, 12, 13}  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_HW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE  #define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000 diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h index 745e3bea5..f37653fea 100644 --- a/include/configs/siemens-am33x-common.h +++ b/include/configs/siemens-am33x-common.h @@ -195,6 +195,7 @@  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	14 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW  #define CONFIG_SYS_NAND_ECCSTEPS	4  #define	CONFIG_SYS_NAND_ECCTOTAL	(CONFIG_SYS_NAND_ECCBYTES * \ @@ -430,6 +431,7 @@  		"\0"  #define CONFIG_NAND_OMAP_GPMC +#define CONFIG_NAND_OMAP_ELM  #define GPMC_NAND_ECC_LP_x16_LAYOUT	1  #define CONFIG_SYS_NAND_BASE		(0x08000000)	/* physical address */  							/* to access nand at */ diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h index 6112c1b7a..439fc47eb 100644 --- a/include/configs/tam3517-common.h +++ b/include/configs/tam3517-common.h @@ -224,7 +224,6 @@  #define CONFIG_SPL_BOARD_INIT  #define CONFIG_SPL_CONSOLE  #define CONFIG_SPL_NAND_SIMPLE -#define CONFIG_SPL_NAND_SOFTECC  #define CONFIG_SPL_NAND_WORKSPACE	0x8f07f000 /* below BSS */  #define CONFIG_SPL_LIBCOMMON_SUPPORT @@ -261,6 +260,7 @@  					 56, 57, 58, 59, 60, 61, 62, 63}  #define CONFIG_SYS_NAND_ECCSIZE		256  #define CONFIG_SYS_NAND_ECCBYTES	3 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_HAM1_CODE_SW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h index afd870762..cc4001fcd 100644 --- a/include/configs/tricorder.h +++ b/include/configs/tricorder.h @@ -138,8 +138,9 @@  #define CONFIG_SYS_MAX_NAND_DEVICE	1		/* Max number of NAND */  							/* devices */ -#define CONFIG_NAND_OMAP_BCH8  #define CONFIG_BCH +#define CONFIG_SYS_NAND_MAX_OOBFREE	2 +#define CONFIG_SYS_NAND_MAX_ECCPOS	56  /* commands to include */  #include <config_cmd_default.h> @@ -374,6 +375,7 @@  #define CONFIG_SYS_NAND_ECCSIZE		512  #define CONFIG_SYS_NAND_ECCBYTES	13 +#define CONFIG_NAND_OMAP_ECCSCHEME	OMAP_ECC_BCH8_CODE_HW_DETECTION_SW  #define CONFIG_SYS_NAND_U_BOOT_START	CONFIG_SYS_TEXT_BASE diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 6f44abdc1..a65b68155 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -96,6 +96,29 @@ struct mtd_oob_ops {  	uint8_t		*oobbuf;  }; +#ifdef CONFIG_SYS_NAND_MAX_OOBFREE +#define MTD_MAX_OOBFREE_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_OOBFREE +#else +#define MTD_MAX_OOBFREE_ENTRIES_LARGE	32 +#endif + +#ifdef CONFIG_SYS_NAND_MAX_ECCPOS +#define MTD_MAX_ECCPOS_ENTRIES_LARGE	CONFIG_SYS_NAND_MAX_ECCPOS +#else +#define MTD_MAX_ECCPOS_ENTRIES_LARGE	640 +#endif + +/* + * ECC layout control structure. Exported to userspace for + * diagnosis and to allow creation of raw images + */ +struct nand_ecclayout { +	uint32_t eccbytes; +	uint32_t eccpos[MTD_MAX_ECCPOS_ENTRIES_LARGE]; +	uint32_t oobavail; +	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE]; +}; +  struct mtd_info {  	u_char type;  	u_int32_t flags; diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h index d51c1abd1..ac3c29876 100644 --- a/include/mtd/mtd-abi.h +++ b/include/mtd/mtd-abi.h @@ -155,18 +155,6 @@ struct nand_oobfree {  	uint32_t length;  }; -#define MTD_MAX_OOBFREE_ENTRIES	8 -/* - * ECC layout control structure. Exported to userspace for - * diagnosis and to allow creation of raw images - */ -struct nand_ecclayout { -	uint32_t eccbytes; -	uint32_t eccpos[128]; -	uint32_t oobavail; -	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; -}; -  /**   * struct mtd_ecc_stats - error correction stats   * |