diff options
| -rw-r--r-- | common/cmd_doc.c | 4 | ||||
| -rw-r--r-- | doc/README.nand | 107 | ||||
| -rw-r--r-- | drivers/mtd/nand_legacy/nand_legacy.c | 3 | ||||
| -rw-r--r-- | onenand_ipl/onenand_boot.c | 2 | ||||
| -rw-r--r-- | onenand_ipl/onenand_ipl.h | 8 | ||||
| -rw-r--r-- | onenand_ipl/onenand_read.c | 58 | 
6 files changed, 63 insertions, 119 deletions
| diff --git a/common/cmd_doc.c b/common/cmd_doc.c index e2d4a42d1..3385c6736 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -14,6 +14,10 @@  #include <linux/mtd/nftl.h>  #include <linux/mtd/doc2000.h> +#error This code is broken and will be removed outright in the next release. +#error If you need diskonchip support, please update the Linux driver in +#error drivers/mtd/nand/diskonchip.c to work with u-boot. +  /*   * ! BROKEN !   * diff --git a/doc/README.nand b/doc/README.nand index fc62f92e0..bb722892d 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -98,83 +98,10 @@ Configuration Options:     CONFIG_SYS_MAX_NAND_DEVICE        The maximum number of NAND devices you want to support. -NAND Interface: +   CONFIG_SYS_NAND_MAX_CHIPS +      The maximum number of NAND chips per device to be supported. -   #define NAND_WAIT_READY(nand) -      Wait until the NAND flash is ready. Typically this would be a -      loop waiting for the READY/BUSY line from the flash to indicate it -      it is ready. - -   #define WRITE_NAND_COMMAND(d, adr) -      Write the command byte `d' to the flash at `adr' with the -      CLE (command latch enable) line true. If your board uses writes to -      different addresses to control CLE and ALE, you can modify `adr' -      to be the appropriate address here. If your board uses I/O registers -      to control them, it is probably better to let NAND_CTL_SETCLE() -      and company do it. - -   #define WRITE_NAND_ADDRESS(d, adr) -      Write the address byte `d' to the flash at `adr' with the -      ALE (address latch enable) line true. If your board uses writes to -      different addresses to control CLE and ALE, you can modify `adr' -      to be the appropriate address here. If your board uses I/O registers -      to control them, it is probably better to let NAND_CTL_SETALE() -      and company do it. - -   #define WRITE_NAND(d, adr) -      Write the data byte `d' to the flash at `adr' with the -      ALE and CLE lines false. If your board uses writes to -      different addresses to control CLE and ALE, you can modify `adr' -      to be the appropriate address here. If your board uses I/O registers -      to control them, it is probably better to let NAND_CTL_CLRALE() -      and company do it. - -   #define READ_NAND(adr) -      Read a data byte from the flash at `adr' with the -      ALE and CLE lines false. If your board uses reads from -      different addresses to control CLE and ALE, you can modify `adr' -      to be the appropriate address here. If your board uses I/O registers -      to control them, it is probably better to let NAND_CTL_CLRALE() -      and company do it. - -   #define NAND_DISABLE_CE(nand) -      Set CE (Chip Enable) low to enable the NAND flash. - -   #define NAND_ENABLE_CE(nand) -      Set CE (Chip Enable) high to disable the NAND flash. - -   #define NAND_CTL_CLRALE(nandptr) -      Set ALE (address latch enable) low. If ALE control is handled by -      WRITE_NAND_ADDRESS() this can be empty. - -   #define NAND_CTL_SETALE(nandptr) -      Set ALE (address latch enable) high. If ALE control is handled by -      WRITE_NAND_ADDRESS() this can be empty. - -   #define NAND_CTL_CLRCLE(nandptr) -      Set CLE (command latch enable) low. If CLE control is handled by -      WRITE_NAND_ADDRESS() this can be empty. - -   #define NAND_CTL_SETCLE(nandptr) -      Set CLE (command latch enable) high. If CLE control is handled by -      WRITE_NAND_ADDRESS() this can be empty. - -More Definitions: - -   These definitions are needed in the board configuration for now, but -   may really belong in a header file. -   TODO: Figure which ones are truly configuration settings and rename -	 them to CONFIG_SYS_NAND_... and move the rest somewhere appropriate. - -   #define SECTORSIZE 512 -   #define ADDR_COLUMN 1 -   #define ADDR_PAGE 2 -   #define ADDR_COLUMN_PAGE 3 -   #define NAND_ChipID_UNKNOWN 0x00 -   #define NAND_MAX_FLOORS 1 -   #define CONFIG_SYS_NAND_MAX_CHIPS 1 - -   #define CONFIG_SYS_DAVINCI_BROKEN_ECC +   CONFIG_SYS_DAVINCI_BROKEN_ECC        Versions of U-Boot <= 1.3.3 and Montavista Linux kernels        generated bogus ECCs on large-page NAND. Both large and small page        NAND ECCs were incompatible with the Linux davinci git tree (since @@ -186,27 +113,17 @@ More Definitions:  NOTE:  ===== -We now use a complete rewrite of the NAND code based on what is in -2.6.12 Linux kernel. - -The old NAND handling code has been re-factored and is now confined -to only board-specific files and - unfortunately - to the DoC code -(see below). A new configuration variable has been introduced: -CONFIG_NAND_LEGACY, which has to be defined in the board config file if -that board uses legacy code. - -The necessary changes have been made to all affected boards, and no -build breakage has been introduced, except for NETTA and NETTA_ISDN -targets from MAKEALL. This is due to the fact that these two boards -use JFFS, which has been adopted to use the new NAND, and at the same -time use NAND in legacy mode. The breakage will disappear when the -board-specific code is changed to the new NAND. +The current NAND implementation is based on what is in recent +Linux kernels.  The old legacy implementation has been disabled, +and will be removed soon. -As mentioned above, the legacy code is still used by the DoC subsystem. -The consequence of this is that the legacy NAND can't be removed  from -the tree until the DoC is ported to use the new NAND support (or boards -with DoC will break). +If you have board code which used CONFIG_NAND_LEGACY, you'll need +to convert to the current NAND interface for it to continue to work. +The Disk On Chip driver is currently broken and has been for some time. +There is a driver in drivers/mtd/nand, taken from Linux, that works with +the current NAND system but has not yet been adapted to the u-boot +environment.  Additional improvements to the NAND subsystem by Guido Classen, 10-10-2006 diff --git a/drivers/mtd/nand_legacy/nand_legacy.c b/drivers/mtd/nand_legacy/nand_legacy.c index 441780ac2..d9ae9c78b 100644 --- a/drivers/mtd/nand_legacy/nand_legacy.c +++ b/drivers/mtd/nand_legacy/nand_legacy.c @@ -18,6 +18,9 @@  #include <linux/mtd/nand_ids.h>  #include <jffs2/jffs2.h> +#error Legacy NAND is deprecated.  Please convert to the current NAND interface. +#error This code will be removed outright in the next release. +  #ifdef CONFIG_OMAP1510  void archflashwp(void *archdata, int wp);  #endif diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c index 86428cc05..63995ce50 100644 --- a/onenand_ipl/onenand_boot.c +++ b/onenand_ipl/onenand_boot.c @@ -36,7 +36,7 @@ void start_oneboot(void)  	buf = (uchar *) CONFIG_SYS_LOAD_ADDR; -	onenand_read_block0(buf); +	onenand_read_block(buf);  	((init_fnc_t *)CONFIG_SYS_LOAD_ADDR)(); diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h index 57e54f5cb..412572a08 100644 --- a/onenand_ipl/onenand_ipl.h +++ b/onenand_ipl/onenand_ipl.h @@ -23,15 +23,13 @@  #include <linux/mtd/onenand_regs.h> -#define onenand_readw(a)        readw(a) -#define onenand_writew(v, a)    writew(v, a) +#define onenand_readw(a)        readw(THIS_ONENAND(a)) +#define onenand_writew(v, a)    writew(v, THIS_ONENAND(a))  #define THIS_ONENAND(a)         (CONFIG_SYS_ONENAND_BASE + (a))  #define READ_INTERRUPT()                                                \  	onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT)) -#define ONENAND_PAGE_SIZE                       2048 - -extern int onenand_read_block0(unsigned char *buf); +extern int onenand_read_block(unsigned char *buf);  #endif diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c index 6d04943ba..d1a842dd6 100644 --- a/onenand_ipl/onenand_read.c +++ b/onenand_ipl/onenand_read.c @@ -49,20 +49,20 @@ static inline int onenand_read_page(ulong block, ulong page,  #endif  	onenand_writew(onenand_block_address(block), -		THIS_ONENAND(ONENAND_REG_START_ADDRESS1)); +			ONENAND_REG_START_ADDRESS1);  	onenand_writew(onenand_bufferram_address(block), -		THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); +			ONENAND_REG_START_ADDRESS2);  	onenand_writew(onenand_sector_address(page), -		THIS_ONENAND(ONENAND_REG_START_ADDRESS8)); +			ONENAND_REG_START_ADDRESS8);  	onenand_writew(onenand_buffer_address(), -		THIS_ONENAND(ONENAND_REG_START_BUFFER)); +			ONENAND_REG_START_BUFFER); -	onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT)); +	onenand_writew(ONENAND_INT_CLEAR, ONENAND_REG_INTERRUPT); -	onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND)); +	onenand_writew(ONENAND_CMD_READ, ONENAND_REG_COMMAND);  #ifndef __HAVE_ARCH_MEMCPY32  	p = (unsigned long *) buf; @@ -72,6 +72,10 @@ static inline int onenand_read_page(ulong block, ulong page,  	while (!(READ_INTERRUPT() & ONENAND_INT_READ))  		continue; +	/* Check for invalid block mark */ +	if (page < 2 && (onenand_readw(ONENAND_SPARERAM) != 0xffff)) +		return 1; +  #ifdef __HAVE_ARCH_MEMCPY32  	/* 32 bytes boundary memory copy */  	memcpy32(buf, base, pagesize); @@ -89,25 +93,43 @@ static inline int onenand_read_page(ulong block, ulong page,  #define ONENAND_PAGES_PER_BLOCK		64  /** - * onenand_read_block - Read a block data to buf + * onenand_read_block - Read CONFIG_SYS_MONITOR_LEN from begining + *                      of OneNAND, skipping bad blocks   * @return 0 on success   */ -int onenand_read_block0(unsigned char *buf) +int onenand_read_block(unsigned char *buf)  { -	int page, offset = 0; -	int pagesize = ONENAND_PAGE_SIZE; +	int block; +	int page = ONENAND_START_PAGE, offset = 0; +	int pagesize = 0, erase_shift = 0; +	int erasesize = 0, nblocks = 0; + +	if (onenand_readw(ONENAND_REG_TECHNOLOGY)) { +		pagesize = 4096; /* MLC OneNAND has 4KiB pagesize */ +		erase_shift = 18; +	} else { +		pagesize = 2048; +		erase_shift = 17; +	} -	/* MLC OneNAND has 4KiB page size */ -	if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY))) -		pagesize <<= 1; +	erasesize = ONENAND_PAGES_PER_BLOCK * pagesize; +	nblocks = (CONFIG_SYS_MONITOR_LEN + erasesize - 1) >> erase_shift;  	/* NOTE: you must read page from page 1 of block 0 */  	/* read the block page by page*/ -	for (page = ONENAND_START_PAGE; -	    page < ONENAND_PAGES_PER_BLOCK; page++) { - -		onenand_read_page(0, page, buf + offset, pagesize); -		offset += pagesize; +	for (block = 0; block < nblocks; block++) { +		for (; page < ONENAND_PAGES_PER_BLOCK; page++) { +			if (onenand_read_page(block, page, buf + offset, +						pagesize)) { +				/* This block is bad. Skip it +				 * and read next block */ +				offset -= page * pagesize; +				nblocks++; +				break; +			} +			offset += pagesize; +		} +		page = 0;  	}  	return 0; |