[PATCH v1] splash: splash_storage_read_raw: Add mmc support

qianfanguijin at 163.com qianfanguijin at 163.com
Tue Apr 26 03:38:48 CEST 2022


From: qianfan Zhao <qianfanguijin at 163.com>

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

Signed-off-by: qianfan Zhao <qianfanguijin at 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



More information about the U-Boot mailing list