[U-Boot] [PATCH] Fix OneNAND ipl to read 256KB
Kyungmin Park
kmpark at infradead.org
Thu Mar 5 00:55:36 CET 2009
On Thu, Mar 5, 2009 at 12:09 AM, Rohit Hagargundgi <h.rohit at samsung.com> wrote:
> Hi,
>
> Here is the updated patch.
>
> Thanks,
> Rohit
>
> Signed-off-by: Rohit Hagargundgi <h.rohit at samsung.com>
> ---
> include/configs/apollon.h | 1 +
> onenand_ipl/onenand_read.c | 27 ++++++++++++++++++++-------
> 2 files changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/include/configs/apollon.h b/include/configs/apollon.h
> index dff47fc..2e8198f 100644
> --- a/include/configs/apollon.h
> +++ b/include/configs/apollon.h
> @@ -254,6 +254,7 @@
>
> /* OneNAND boot, OneNAND has CS0, NOR boot ONeNAND has CS2 */
> #define CONFIG_SYS_ONENAND_BASE 0x00000000
> +#define CONFIG_SYS_MONITOR_LEN SZ_256K /* U-Boot image size */
> #define CONFIG_ENV_IS_IN_ONENAND 1
> #define CONFIG_ENV_ADDR 0x00020000
>
> diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c
> index 6d04943..6782eac 100644
> --- a/onenand_ipl/onenand_read.c
> +++ b/onenand_ipl/onenand_read.c
> @@ -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(THIS_ONENAND(ONENAND_SPARERAM)) != 0xffff))
> + return 1;
> +
No need to check invalid block. Note that block 0 is always good
block. no exception.
Now you assume block 1 can be invalid block. If true just skip it.
when update bootloader at u-boot or kernel.
there's bad block at block 1. it will skip write. it means bootloader
are located at block 0 and block 2.
> #ifdef __HAVE_ARCH_MEMCPY32
> /* 32 bytes boundary memory copy */
> memcpy32(buf, base, pagesize);
> @@ -94,20 +98,29 @@ static inline int onenand_read_page(ulong block, ulong page,
> */
> int onenand_read_block0(unsigned char *buf)
> {
> - int page, offset = 0;
> + int block = 0, page, offset = 0;
> int pagesize = ONENAND_PAGE_SIZE;
> + int nblocks = CONFIG_SYS_MONITOR_LEN / (ONENAND_PAGES_PER_BLOCK * ONENAND_PAGE_SIZE);
>
> /* MLC OneNAND has 4KiB page size */
> - if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY)))
> + if (onenand_readw(THIS_ONENAND(ONENAND_REG_TECHNOLOGY))) {
> pagesize <<= 1;
> + nblocks = (nblocks + 1) >> 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(0, page, buf + offset, pagesize);
> - offset += pagesize;
> + page = ONENAND_START_PAGE;
> + for (; 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 */
> + nblocks++;
> + break;
> + }
> + offset += pagesize;
> + }
> + page = 0;
> }
>
> return 0;
NAK, please use previous one as I sent.
In Flex-OneNAND block 0 has 256KiB. need to handle at here how many
blocks are needed.
I also want to use CONFIG_ONENAND_END_BLOCK since we don't know which
OneNAND or Flex-OneNAND are attached to apollon board.
Thank you,
Kyungmin Park
More information about the U-Boot
mailing list