]> Git Repo - J-u-boot.git/blobdiff - common/splash_source.c
Kconfig: j721s2: Change K3_MCU_SCRATCHPAD_BASE to non firewalled region
[J-u-boot.git] / common / splash_source.c
index e0defdebd6ae7a24cfd5cb345020b047d1465d07..a260137619806e3a0dd1ec41cb5bf8749be96b36 100644 (file)
@@ -1,23 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
  *
  * Authors: Igor Grinberg <[email protected]>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <bmp_layout.h>
+#include <command.h>
+#include <env.h>
 #include <errno.h>
 #include <fs.h>
 #include <fdt_support.h>
 #include <image.h>
+#include <log.h>
 #include <nand.h>
 #include <sata.h>
 #include <spi.h>
 #include <spi_flash.h>
 #include <splash.h>
 #include <usb.h>
+#include <virtio.h>
+#include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -34,7 +38,7 @@ static int splash_sf_read_raw(u32 bmp_load_addr, int offset, size_t read_size)
                        return -ENODEV;
        }
 
-       return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr);
+       return spi_flash_read(sf, offset, read_size, (void *)(uintptr_t)bmp_load_addr);
 }
 #else
 static int splash_sf_read_raw(u32 bmp_load_addr, int offset, size_t read_size)
@@ -61,6 +65,30 @@ static int splash_nand_read_raw(u32 bmp_load_addr, int offset, size_t read_size)
 }
 #endif
 
+static int splash_mmc_read_raw(u32 bmp_load_addr, struct splash_location *location,
+                              size_t read_size)
+{
+       struct disk_partition partition;
+       struct blk_desc *desc;
+       lbaint_t blkcnt;
+       int ret, n;
+
+       if (!IS_ENABLED(CONFIG_CMD_MMC)) {
+               debug("%s: mmc support not available\n", __func__);
+               return -ENOSYS;
+       }
+
+       ret = part_get_info_by_dev_and_name_or_num("mmc", location->devpart, &desc,
+                                                  &partition, 1);
+       if (ret < 0)
+               return ret;
+
+       blkcnt = DIV_ROUND_UP(read_size, partition.blksz);
+       n = blk_dread(desc, partition.start, blkcnt, (void *)(uintptr_t)bmp_load_addr);
+
+       return (n == blkcnt) ? 0 : -EIO;
+}
+
 static int splash_storage_read_raw(struct splash_location *location,
                               u32 bmp_load_addr, size_t read_size)
 {
@@ -71,6 +99,8 @@ static int splash_storage_read_raw(struct splash_location *location,
 
        offset = location->offset;
        switch (location->storage) {
+       case SPLASH_STORAGE_MMC:
+               return splash_mmc_read_raw(bmp_load_addr, location, read_size);
        case SPLASH_STORAGE_NAND:
                return splash_nand_read_raw(bmp_load_addr, offset, read_size);
        case SPLASH_STORAGE_SF:
@@ -95,7 +125,7 @@ static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr)
        if (res < 0)
                return res;
 
-       bmp_hdr = (struct bmp_header *)bmp_load_addr;
+       bmp_hdr = (struct bmp_header *)(uintptr_t)bmp_load_addr;
        bmp_size = le32_to_cpu(bmp_hdr->file_size);
 
        if (bmp_load_addr + bmp_size >= gd->start_addr_sp)
@@ -176,6 +206,16 @@ static inline int splash_init_sata(void)
 }
 #endif
 
+static int splash_init_virtio(void)
+{
+       if (!IS_ENABLED(CONFIG_VIRTIO)) {
+               printf("Cannot load splash image: no virtio support\n");
+               return -ENOSYS;
+       } else {
+               return virtio_init();
+       }
+}
+
 #ifdef CONFIG_CMD_UBIFS
 static int splash_mount_ubifs(struct splash_location *location)
 {
@@ -230,6 +270,9 @@ static int splash_load_fs(struct splash_location *location, u32 bmp_load_addr)
        if (location->storage == SPLASH_STORAGE_SATA)
                res = splash_init_sata();
 
+       if (location->storage == SPLASH_STORAGE_VIRTIO)
+               res = splash_init_virtio();
+
        if (location->ubivol != NULL)
                res = splash_mount_ubifs(location);
 
@@ -304,19 +347,23 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr)
 {
        int res;
        int node_offset;
-       int splash_offset;
-       int splash_size;
-       struct image_header *img_header;
+       const char *splash_file;
+       const void *internal_splash_data;
+       size_t internal_splash_size;
+       int external_splash_addr;
+       int external_splash_size;
+       bool is_splash_external = false;
+       struct legacy_img_hdr *img_header;
        const u32 *fit_header;
        u32 fit_size;
-       const size_t header_size = sizeof(struct image_header);
+       const size_t header_size = sizeof(struct legacy_img_hdr);
 
        /* Read in image header */
        res = splash_storage_read_raw(location, bmp_load_addr, header_size);
        if (res < 0)
                return res;
 
-       img_header = (struct image_header *)bmp_load_addr;
+       img_header = (struct legacy_img_hdr *)bmp_load_addr;
        if (image_get_magic(img_header) != FDT_MAGIC) {
                printf("Could not find FDT magic\n");
                return -EINVAL;
@@ -330,42 +377,57 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr)
        if (res < 0)
                return res;
 
-       res = fit_check_format(fit_header);
-       if (!res) {
+       res = fit_check_format(fit_header, IMAGE_SIZE_INVAL);
+       if (res) {
                debug("Could not find valid FIT image\n");
-               return -EINVAL;
+               return res;
        }
 
-       node_offset = fit_image_get_node(fit_header, location->name);
+       /* Get the splash image node */
+       splash_file = env_get("splashfile");
+       if (!splash_file)
+               splash_file = SPLASH_SOURCE_DEFAULT_FILE_NAME;
+
+       node_offset = fit_image_get_node(fit_header, splash_file);
        if (node_offset < 0) {
                debug("Could not find splash image '%s' in FIT\n",
-                     location->name);
+                     splash_file);
                return -ENOENT;
        }
 
-       res = fit_image_get_data_offset(fit_header, node_offset,
-                                       &splash_offset);
-       if (res < 0) {
-               printf("Failed to load splash image (err=%d)\n", res);
-               return res;
+       /* Extract the splash data from FIT */
+       /* 1. Test if splash is in FIT internal data. */
+       if (!fit_image_get_data(fit_header, node_offset, &internal_splash_data, &internal_splash_size))
+               memmove((void *)bmp_load_addr, internal_splash_data, internal_splash_size);
+       /* 2. Test if splash is in FIT external data with fixed position. */
+       else if (!fit_image_get_data_position(fit_header, node_offset, &external_splash_addr))
+               is_splash_external = true;
+       /* 3. Test if splash is in FIT external data with offset. */
+       else if (!fit_image_get_data_offset(fit_header, node_offset, &external_splash_addr)) {
+               /* Align data offset to 4-byte boundary */
+               fit_size = ALIGN(fdt_totalsize(fit_header), 4);
+               /* External splash offset means the offset by end of FIT header */
+               external_splash_addr += location->offset + fit_size;
+               is_splash_external = true;
+       } else {
+               printf("Failed to get splash image from FIT\n");
+               return -ENODATA;
        }
 
-       res = fit_image_get_data_size(fit_header, node_offset, &splash_size);
-       if (res < 0) {
-               printf("Failed to load splash image (err=%d)\n", res);
-               return res;
+       if (is_splash_external) {
+               res = fit_image_get_data_size(fit_header, node_offset, &external_splash_size);
+               if (res < 0) {
+                       printf("Failed to get size of splash image (err=%d)\n", res);
+                       return res;
+               }
+
+               /* Read in the splash data */
+               location->offset = external_splash_addr;
+               res = splash_storage_read_raw(location, bmp_load_addr, external_splash_size);
+               if (res < 0)
+                       return res;
        }
 
-       /* Align data offset to 4-byte boundrary */
-       fit_size = fdt_totalsize(fit_header);
-       fit_size = (fit_size + 3) & ~3;
-
-       /* Read in the splash data */
-       location->offset = (location->offset + fit_size + splash_offset);
-       res = splash_storage_read_raw(location, bmp_load_addr , splash_size);
-       if (res < 0)
-               return res;
-
        return 0;
 }
 #endif /* CONFIG_FIT */
@@ -386,13 +448,14 @@ int splash_source_load(struct splash_location *locations, uint size)
 {
        struct splash_location *splash_location;
        char *env_splashimage_value;
+       char *devpart;
        u32 bmp_load_addr;
 
        env_splashimage_value = env_get("splashimage");
        if (env_splashimage_value == NULL)
                return -ENOENT;
 
-       bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16);
+       bmp_load_addr = hextoul(env_splashimage_value, 0);
        if (bmp_load_addr == 0) {
                printf("Error: bad splashimage address specified\n");
                return -EFAULT;
@@ -402,6 +465,10 @@ int splash_source_load(struct splash_location *locations, uint size)
        if (!splash_location)
                return -EINVAL;
 
+       devpart = env_get("splashdevpart");
+       if (devpart)
+               splash_location->devpart = devpart;
+
        if (splash_location->flags == SPLASH_STORAGE_RAW)
                return splash_load_raw(splash_location, bmp_load_addr);
        else if (splash_location->flags == SPLASH_STORAGE_FS)
This page took 0.029809 seconds and 4 git commands to generate.