diff options
author | Kyungmin Park <kmpark@infradead.org> | 2008-03-17 08:54:06 +0900 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2008-03-26 00:05:32 +0100 |
commit | 1bb707c39a0833e91d9f797dd862aaaaf4af264d (patch) | |
tree | 025e32303ffb6760c96aebbd769dac9c2a93ce46 /onenand_ipl/onenand_read.c | |
parent | c512389cc4a10253249271ff6c887c6dab1f0db2 (diff) | |
download | u-boot-imx-1bb707c39a0833e91d9f797dd862aaaaf4af264d.zip u-boot-imx-1bb707c39a0833e91d9f797dd862aaaaf4af264d.tar.gz u-boot-imx-1bb707c39a0833e91d9f797dd862aaaaf4af264d.tar.bz2 |
Add Flex-OneNAND booting support
Flex-OneNAND is a monolithic integrated circuit with a NAND Flash array
using a NOR Flash interface. This on-chip integration enables system designers
to reduce external system logic and use high-density NAND Flash
in applications that would otherwise have to use more NOR components.
Flex-OneNAND enables users to configure to partition it into SLC and MLC areas
in more flexible way. While MLC area of Flex-OneNAND can be used to store data
that require low reliability and high density, SLC area of Flex-OneNAND
to store data that need high reliability and high performance. Flex-OneNAND
can let users take advantage of storing these two different types of data
into one chip, which is making Flex-OneNAND more cost- and space-effective.
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'onenand_ipl/onenand_read.c')
-rw-r--r-- | onenand_ipl/onenand_read.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c index f553220..669b1ef 100644 --- a/onenand_ipl/onenand_read.c +++ b/onenand_ipl/onenand_read.c @@ -33,8 +33,13 @@ #define onenand_buffer_address() ((1 << 3) << 8) #define onenand_bufferram_address(block) (0) +#ifdef __HAVE_ARCH_MEMCPY32 +extern void *memcpy32(void *dest, void *src, int size); +#endif + /* read a page with ECC */ -static inline int onenand_read_page(ulong block, ulong page, u_char *buf) +static inline int onenand_read_page(ulong block, ulong page, + u_char * buf, int pagesize) { unsigned long *base; @@ -46,15 +51,15 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) onenand_writew(onenand_block_address(block), THIS_ONENAND(ONENAND_REG_START_ADDRESS1)); + onenand_writew(onenand_bufferram_address(block), + THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); + onenand_writew(onenand_sector_address(page), THIS_ONENAND(ONENAND_REG_START_ADDRESS8)); onenand_writew(onenand_buffer_address(), THIS_ONENAND(ONENAND_REG_START_BUFFER)); - onenand_writew(onenand_bufferram_address(block), - THIS_ONENAND(ONENAND_REG_START_ADDRESS2)); - onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT)); onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND)); @@ -69,9 +74,9 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) #ifdef __HAVE_ARCH_MEMCPY32 /* 32 bytes boundary memory copy */ - memcpy32(buf, base, ONENAND_PAGE_SIZE); + memcpy32(buf, base, pagesize); #else - for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) { + for (offset = 0; offset < (pagesize >> 2); offset++) { value = *(base + offset); *p++ = value; } @@ -87,18 +92,22 @@ static inline int onenand_read_page(ulong block, ulong page, u_char *buf) * onenand_read_block - Read a block data to buf * @return 0 on success */ -int onenand_read_block(unsigned char *buf, ulong block) +int onenand_read_block0(unsigned char *buf) { int page, offset = 0; + int pagesize = ONENAND_PAGE_SIZE; + + /* MLC OneNAND has 4KiB page size */ + if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY))) + pagesize <<= 1; /* 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(block, page, buf + offset); - - offset += ONENAND_PAGE_SIZE; + onenand_read_page(0, page, buf + offset, pagesize); + offset += pagesize; } return 0; |