[U-Boot] [PATCH 3/7] mtd: nand: Consolidate nand spl loaders implementation

Pau Pajuelo ppajuelo at iseebcn.com
Thu Apr 6 17:20:14 UTC 2017


Tested-by: Pau Pajuelo <ppajuel at gmail.com>

2017-04-01 17:16 GMT+02:00 Ladislav Michl <ladis at linux-mips.org>:
>
> nand_spl_load_image implementation was copied over into three
> different drivers and now with nand_spl_read_block used for
> ubispl situation gets even worse. For now use least intrusive
> solution and #include the same implementation to nand drivers.
>
> Signed-off-by: Ladislav Michl <ladis at linux-mips.org>
> ---
>  drivers/mtd/nand/am335x_spl_bch.c   |  49 +----------------
>  drivers/mtd/nand/atmel_nand.c       |  30 +---------
>  drivers/mtd/nand/nand_spl_loaders.c | 106 ++++++++++++++++++++++++++++++++++++
>  drivers/mtd/nand/nand_spl_simple.c  |  98 +--------------------------------
>  4 files changed, 112 insertions(+), 171 deletions(-)
>
> diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
> index a8a7a66a18..c433caa365 100644
> --- a/drivers/mtd/nand/am335x_spl_bch.c
> +++ b/drivers/mtd/nand/am335x_spl_bch.c
> @@ -170,53 +170,6 @@ static int nand_read_page(int block, int page, void *dst)
>         return 0;
>  }
>
> -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
> -{
> -       unsigned int block, lastblock;
> -       unsigned int page, page_offset;
> -
> -       /*
> -        * offs has to be aligned to a page address!
> -        */
> -       block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
> -       page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE;
> -
> -       while (block <= lastblock) {
> -               if (!nand_is_bad_block(block)) {
> -                       /*
> -                        * Skip bad blocks
> -                        */
> -                       while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
> -                               nand_read_page(block, page, dst);
> -                               /*
> -                                * When offs is not aligned to page address the
> -                                * extra offset is copied to dst as well. Copy
> -                                * the image such that its first byte will be
> -                                * at the dst.
> -                                */
> -                               if (unlikely(page_offset)) {
> -                                       memmove(dst, dst + page_offset,
> -                                               CONFIG_SYS_NAND_PAGE_SIZE);
> -                                       dst = (void *)((int)dst - page_offset);
> -                                       page_offset = 0;
> -                               }
> -                               dst += CONFIG_SYS_NAND_PAGE_SIZE;
> -                               page++;
> -                       }
> -
> -                       page = 0;
> -               } else {
> -                       lastblock++;
> -               }
> -
> -               block++;
> -       }
> -
> -       return 0;
> -}
> -
>  /* nand_init() - initialize data to make nand usable by SPL */
>  void nand_init(void)
>  {
> @@ -241,3 +194,5 @@ void nand_deselect(void)
>         if (nand_chip.select_chip)
>                 nand_chip.select_chip(mtd, -1);
>  }
> +
> +#include "nand_spl_loaders.c"
> diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
> index 8669432deb..00c8bc5f12 100644
> --- a/drivers/mtd/nand/atmel_nand.c
> +++ b/drivers/mtd/nand/atmel_nand.c
> @@ -1379,34 +1379,6 @@ static int nand_read_page(int block, int page, void *dst)
>  }
>  #endif /* CONFIG_SPL_NAND_ECC */
>
> -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
> -{
> -       unsigned int block, lastblock;
> -       unsigned int page;
> -
> -       block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
> -
> -       while (block <= lastblock) {
> -               if (!nand_is_bad_block(block)) {
> -                       while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
> -                               nand_read_page(block, page, dst);
> -                               dst += CONFIG_SYS_NAND_PAGE_SIZE;
> -                               page++;
> -                       }
> -
> -                       page = 0;
> -               } else {
> -                       lastblock++;
> -               }
> -
> -               block++;
> -       }
> -
> -       return 0;
> -}
> -
>  int at91_nand_wait_ready(struct mtd_info *mtd)
>  {
>         struct nand_chip *this = mtd_to_nand(mtd);
> @@ -1473,6 +1445,8 @@ void nand_deselect(void)
>                 nand_chip.select_chip(mtd, -1);
>  }
>
> +#include "nand_spl_loaders.c"
> +
>  #else
>
>  #ifndef CONFIG_SYS_NAND_BASE_LIST
> diff --git a/drivers/mtd/nand/nand_spl_loaders.c b/drivers/mtd/nand/nand_spl_loaders.c
> new file mode 100644
> index 0000000000..2a4b104954
> --- /dev/null
> +++ b/drivers/mtd/nand/nand_spl_loaders.c
> @@ -0,0 +1,106 @@
> +#ifdef CONFIG_SPL_NAND_LOAD
> +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
> +{
> +       unsigned int block, lastblock;
> +       unsigned int page, page_offset;
> +
> +       /* offs has to be aligned to a page address! */
> +       block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
> +       lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
> +       page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
> +       page_offset = offs % CONFIG_SYS_NAND_PAGE_SIZE;
> +
> +       while (block <= lastblock) {
> +               if (!nand_is_bad_block(block)) {
> +                       /* Skip bad blocks */
> +                       while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
> +                               nand_read_page(block, page, dst);
> +                               /*
> +                                * When offs is not aligned to page address the
> +                                * extra offset is copied to dst as well. Copy
> +                                * the image such that its first byte will be
> +                                * at the dst.
> +                                */
> +                               if (unlikely(page_offset)) {
> +                                       memmove(dst, dst + page_offset,
> +                                               CONFIG_SYS_NAND_PAGE_SIZE);
> +                                       dst = (void *)((int)dst - page_offset);
> +                                       page_offset = 0;
> +                               }
> +                               dst += CONFIG_SYS_NAND_PAGE_SIZE;
> +                               page++;
> +                       }
> +
> +                       page = 0;
> +               } else {
> +                       lastblock++;
> +               }
> +
> +               block++;
> +       }
> +
> +       return 0;
> +}
> +#endif
> +
> +#ifdef CONFIG_SPL_UBI
> +/*
> + * Temporary storage for non NAND page aligned and non NAND page sized
> + * reads. Note: This does not support runtime detected FLASH yet, but
> + * that should be reasonably easy to fix by making the buffer large
> + * enough :)
> + */
> +static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
> +
> +/**
> + * nand_spl_read_block - Read data from physical eraseblock into a buffer
> + * @block:     Number of the physical eraseblock
> + * @offset:    Data offset from the start of @peb
> + * @len:       Data size to read
> + * @dst:       Address of the destination buffer
> + *
> + * This could be further optimized if we'd have a subpage read
> + * function in the simple code. On NAND which allows subpage reads
> + * this would spare quite some time to readout e.g. the VID header of
> + * UBI.
> + *
> + * Notes:
> + *     @offset + @len are not allowed to be larger than a physical
> + *     erase block. No sanity check done for simplicity reasons.
> + *
> + * To support runtime detected flash this needs to be extended by
> + * information about the actual flash geometry, but thats beyond the
> + * scope of this effort and for most applications where fast boot is
> + * required it is not an issue anyway.
> + */
> +int nand_spl_read_block(int block, int offset, int len, void *dst)
> +{
> +       int page, read;
> +
> +       /* Calculate the page number */
> +       page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
> +
> +       /* Offset to the start of a flash page */
> +       offset = offset % CONFIG_SYS_NAND_PAGE_SIZE;
> +
> +       while (len) {
> +               /*
> +                * Non page aligned reads go to the scratch buffer.
> +                * Page aligned reads go directly to the destination.
> +                */
> +               if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) {
> +                       nand_read_page(block, page, scratch_buf);
> +                       read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset);
> +                       memcpy(dst, scratch_buf + offset, read);
> +                       offset = 0;
> +               } else {
> +                       nand_read_page(block, page, dst);
> +                       read = CONFIG_SYS_NAND_PAGE_SIZE;
> +               }
> +               page++;
> +               len -= read;
> +               dst += read;
> +       }
> +       return 0;
> +}
> +#endif
> diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
> index 55f48d3a14..56e86d1760 100644
> --- a/drivers/mtd/nand/nand_spl_simple.c
> +++ b/drivers/mtd/nand/nand_spl_simple.c
> @@ -209,102 +209,6 @@ static int nand_read_page(int block, int page, void *dst)
>  }
>  #endif
>
> -#ifdef CONFIG_SPL_UBI
> -/*
> - * Temporary storage for non NAND page aligned and non NAND page sized
> - * reads. Note: This does not support runtime detected FLASH yet, but
> - * that should be reasonably easy to fix by making the buffer large
> - * enough :)
> - */
> -static u8 scratch_buf[CONFIG_SYS_NAND_PAGE_SIZE];
> -
> -/**
> - * nand_spl_read_block - Read data from physical eraseblock into a buffer
> - * @block:     Number of the physical eraseblock
> - * @offset:    Data offset from the start of @peb
> - * @len:       Data size to read
> - * @dst:       Address of the destination buffer
> - *
> - * This could be further optimized if we'd have a subpage read
> - * function in the simple code. On NAND which allows subpage reads
> - * this would spare quite some time to readout e.g. the VID header of
> - * UBI.
> - *
> - * Notes:
> - *     @offset + @len are not allowed to be larger than a physical
> - *     erase block. No sanity check done for simplicity reasons.
> - *
> - * To support runtime detected flash this needs to be extended by
> - * information about the actual flash geometry, but thats beyond the
> - * scope of this effort and for most applications where fast boot is
> - * required it is not an issue anyway.
> - */
> -int nand_spl_read_block(int block, int offset, int len, void *dst)
> -{
> -       int page, read;
> -
> -       /* Calculate the page number */
> -       page = offset / CONFIG_SYS_NAND_PAGE_SIZE;
> -
> -       /* Offset to the start of a flash page */
> -       offset = offset % CONFIG_SYS_NAND_PAGE_SIZE;
> -
> -       while (len) {
> -               /*
> -                * Non page aligned reads go to the scratch buffer.
> -                * Page aligned reads go directly to the destination.
> -                */
> -               if (offset || len < CONFIG_SYS_NAND_PAGE_SIZE) {
> -                       nand_read_page(block, page, scratch_buf);
> -                       read = min(len, CONFIG_SYS_NAND_PAGE_SIZE - offset);
> -                       memcpy(dst, scratch_buf + offset, read);
> -                       offset = 0;
> -               } else {
> -                       nand_read_page(block, page, dst);
> -                       read = CONFIG_SYS_NAND_PAGE_SIZE;
> -               }
> -               page++;
> -               len -= read;
> -               dst += read;
> -       }
> -       return 0;
> -}
> -#endif
> -
> -int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
> -{
> -       unsigned int block, lastblock;
> -       unsigned int page;
> -
> -       /*
> -        * offs has to be aligned to a page address!
> -        */
> -       block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
> -       page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
> -
> -       while (block <= lastblock) {
> -               if (!nand_is_bad_block(block)) {
> -                       /*
> -                        * Skip bad blocks
> -                        */
> -                       while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
> -                               nand_read_page(block, page, dst);
> -                               dst += CONFIG_SYS_NAND_PAGE_SIZE;
> -                               page++;
> -                       }
> -
> -                       page = 0;
> -               } else {
> -                       lastblock++;
> -               }
> -
> -               block++;
> -       }
> -
> -       return 0;
> -}
> -
>  /* nand_init() - initialize data to make nand usable by SPL */
>  void nand_init(void)
>  {
> @@ -333,3 +237,5 @@ void nand_deselect(void)
>         if (nand_chip.select_chip)
>                 nand_chip.select_chip(mtd, -1);
>  }
> +
> +#include "nand_spl_loaders.c"
> --
> 2.11.0
>


More information about the U-Boot mailing list