diff mbox

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

Message ID 20170401151637.xazm4tzz6au2ne6t@lenoch
State Changes Requested
Delegated to: Tom Rini
Headers show

Commit Message

Ladislav Michl April 1, 2017, 3:16 p.m. UTC
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@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(-)

Comments

Pau Pajuelo April 6, 2017, 5:20 p.m. UTC | #1
Tested-by: Pau Pajuelo <ppajuel@gmail.com>

2017-04-01 17:16 GMT+02:00 Ladislav Michl <ladis@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@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
>
Tom Rini April 7, 2017, 5:28 p.m. UTC | #2
On Sat, Apr 01, 2017 at 05:16:37PM +0200, Ladislav Michl wrote:

> 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@linux-mips.org>
> Tested-by: Pau Pajuelo <ppajuel@gmail.com>
> ---
>  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(-)

This breaks a bunch of boards such as pxm2 at least.  Please give the
whole series a build on travis-ci before re-submitting, thanks!
diff mbox

Patch

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"