[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