From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pau Pajuelo Date: Thu, 6 Apr 2017 19:20:14 +0200 Subject: [U-Boot] [PATCH 3/7] mtd: nand: Consolidate nand spl loaders implementation In-Reply-To: <20170401151637.xazm4tzz6au2ne6t@lenoch> References: <20170401151326.4d3ijtffy744rwaz@lenoch> <20170401151637.xazm4tzz6au2ne6t@lenoch> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Tested-by: Pau Pajuelo 2017-04-01 17:16 GMT+02:00 Ladislav Michl : > > 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 > --- > 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 >