From: qianfan Zhao <qianfangui...@163.com>

Add splash_mmc_read_raw for loading splash from mmc's raw partition.

Signed-off-by: qianfan Zhao <qianfangui...@163.com>
---
 common/splash_source.c | 90 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/common/splash_source.c b/common/splash_source.c
index d05670f5ee..28ec405bcf 100644
--- a/common/splash_source.c
+++ b/common/splash_source.c
@@ -20,6 +20,7 @@
 #include <spi_flash.h>
 #include <splash.h>
 #include <usb.h>
+#include <memalign.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -64,6 +65,93 @@ static int splash_nand_read_raw(u32 bmp_load_addr, int 
offset, size_t read_size)
 }
 #endif
 
+#ifdef CONFIG_MMC
+static size_t blk_dread_size(struct blk_desc *desc, lbaint_t start,
+                            u32 load_addr, size_t read_size)
+{
+       ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, desc->blksz);
+       size_t n, sz_read = 0;
+
+       while (sz_read < read_size) {
+               if (blk_dread(desc, start, 1, tmpbuf) < 0)
+                       break;
+
+               n = min(read_size - sz_read, (size_t)desc->blksz);
+               memcpy((void *)load_addr, tmpbuf, n);
+               load_addr += n;
+               sz_read += n;
+               start++;
+       }
+
+       return sz_read;
+}
+
+static struct blk_desc *mmc_blk_get_dev(const char *name)
+{
+       struct blk_desc *dev_desc = NULL;
+
+       if (strncmp(name, "mmc", 3) == 0 && strlen(name) > 3) {
+               int mmc_dev;
+               char *endp;
+
+               mmc_dev = (int)simple_strtol(name + 3, &endp, 10);
+               if (*endp == '\0')
+                       dev_desc = blk_get_dev("mmc", mmc_dev);
+       }
+
+       return dev_desc;
+}
+
+static int splash_mmc_read_raw(u32 bmp_load_addr, struct splash_location *loc,
+                              size_t read_size)
+{
+       struct blk_desc *dev_desc = mmc_blk_get_dev(loc->name);
+       lbaint_t offset;
+       size_t sz;
+
+       if (!dev_desc) {
+               printf("mmc device %s not found\n", loc->name);
+               return -ENODEV;
+       }
+
+       if (loc->devpart) {
+               struct disk_partition partition;
+               int ret;
+
+               ret = part_get_info_by_name(dev_desc, loc->devpart, &partition);
+               if (ret < 0) {
+                       printf("%s: partition %s not found\n",
+                              loc->name, loc->devpart);
+                       return ret;
+               } else if (partition.size * partition.blksz < read_size) {
+                       printf("%s: partition %s size less that requested\n",
+                              loc->name, loc->devpart);
+                       return -E2BIG;
+               }
+
+               offset = partition.start;
+       } else {
+               offset = loc->offset;
+       }
+
+       sz = blk_dread_size(dev_desc, offset, bmp_load_addr, read_size);
+       if (sz != read_size) {
+               printf("%s: got %zu but expected %zu\n",
+                      loc->name, sz, read_size);
+               return -EIO;
+       }
+
+       return 0;
+}
+#else
+static int splash_mmc_read_raw(u32 bmp_load_addr, struct splash_location *loc,
+                              size_t read_size)
+{
+       debug("%s: mmc support not available\n", __func__);
+       return -ENOSYS;
+}
+#endif
+
 static int splash_storage_read_raw(struct splash_location *location,
                               u32 bmp_load_addr, size_t read_size)
 {
@@ -78,6 +166,8 @@ static int splash_storage_read_raw(struct splash_location 
*location,
                return splash_nand_read_raw(bmp_load_addr, offset, read_size);
        case SPLASH_STORAGE_SF:
                return splash_sf_read_raw(bmp_load_addr, offset, read_size);
+       case SPLASH_STORAGE_MMC:
+               return splash_mmc_read_raw(bmp_load_addr, location, read_size);
        default:
                printf("Unknown splash location\n");
        }
-- 
2.25.1

Reply via email to