@@ -8,10 +8,17 @@ static u8 *scratch_buf;
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
{
+ unsigned int read_this_time = CONFIG_SYS_NAND_PAGE_SIZE;
+ unsigned int size_left = size;
unsigned int block, lastblock;
unsigned int page, page_offset;
- /* offs has to be aligned to a page address! */
+ if (!scratch_buf)
+ scratch_buf = malloc(CONFIG_SYS_NAND_PAGE_SIZE);
+
+ if (!scratch_buf)
+ return -ENOMEM;
+
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;
@@ -20,8 +27,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
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);
+ while (page < CONFIG_SYS_NAND_PAGE_COUNT &&
+ size_left > 0) {
+ if (size_left < CONFIG_SYS_NAND_PAGE_SIZE) {
+ nand_read_page(block, page,
+ scratch_buf);
+ memcpy(dst, scratch_buf, size_left);
+ read_this_time = size_left;
+ } else {
+ nand_read_page(block, page, dst);
+ }
/*
* When offs is not aligned to page address the
* extra offset is copied to dst as well. Copy
@@ -34,7 +49,8 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
dst = (void *)(dst - page_offset);
page_offset = 0;
}
- dst += CONFIG_SYS_NAND_PAGE_SIZE;
+ dst += read_this_time;
+ size_left -= read_this_time;
page++;
}