compulab: splash: support multiple splash sources
authorNikita Kiryanov <nikita@compulab.co.il>
Wed, 14 Jan 2015 08:42:51 +0000 (10:42 +0200)
committerStefano Babic <sbabic@denx.de>
Thu, 29 Jan 2015 16:42:29 +0000 (17:42 +0100)
Define a generic way for boards to define splash image locations:
- introduce struct splash_location
- introduce enum splash_storage
- update cl_splash_screen_prepare() to take an array of above struct
  and select the appropriate one based on the splashsource environment
  variable (if it is not defined- use the first splash location as default).

cm-t35 is updated to work with the new interface.

Signed-off-by: Nikita Kiryanov <nikita@compulab.co.il>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Igor Grinberg <grinberg@compulab.co.il>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
board/compulab/cm_t35/cm_t35.c
board/compulab/common/common.h
board/compulab/common/splash.c

index 9a3b2ee72fed905b567d46928bdf6fbda1af8b7f..8143c05353cc615a2802e33619b555ea314cfd34 100644 (file)
@@ -59,11 +59,18 @@ void get_board_mem_timings(struct board_sdrc_timings *timings)
 }
 #endif
 
-#define CM_T35_SPLASH_NAND_OFFSET 0x100000
+struct splash_location splash_locations[] = {
+       {
+               .name = "nand",
+               .storage = SPLASH_STORAGE_NAND,
+               .offset = 0x100000,
+       },
+};
 
 int splash_screen_prepare(void)
 {
-       return cl_splash_screen_prepare(CM_T35_SPLASH_NAND_OFFSET);
+       return cl_splash_screen_prepare(splash_locations,
+                                       ARRAY_SIZE(splash_locations));
 }
 
 /*
index 80753b4b73211922e9d5d99b7e498abcb40a233d..09b4de6fe30a6c6f4557f2ebd518daa102a9880b 100644 (file)
@@ -24,10 +24,21 @@ static inline int cl_usb_hub_init(int gpio, const char *label)
 static inline void cl_usb_hub_deinit(int gpio) {}
 #endif /* CONFIG_CMD_USB */
 
+enum splash_storage {
+       SPLASH_STORAGE_NAND,
+};
+
+struct splash_location {
+       char *name;
+       enum splash_storage storage;
+       u32 offset;     /* offset from start of storage */
+};
+
 #ifdef CONFIG_SPLASH_SCREEN
-int cl_splash_screen_prepare(int offset);
+int cl_splash_screen_prepare(struct splash_location *locations, uint size);
 #else /* !CONFIG_SPLASH_SCREEN */
-static inline int cl_splash_screen_prepare(int offset)
+static inline int cl_splash_screen_prepare(struct splash_location *locations,
+                                          uint size)
 {
        return -ENOSYS;
 }
index 09a075568c2f827208f541bcd22569004c78e79e..f230d6db42b76ea0382639623a96bfdd1f05950d 100644 (file)
@@ -30,12 +30,26 @@ static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size)
 }
 #endif
 
-static int splash_storage_read(u32 bmp_load_addr, int offset, size_t read_size)
+static int splash_storage_read(struct splash_location *location,
+                              u32 bmp_load_addr, size_t read_size)
 {
-       return splash_nand_read(bmp_load_addr, offset, read_size);
+       u32 offset;
+
+       if (!location)
+               return -EINVAL;
+
+       offset = location->offset;
+       switch (location->storage) {
+       case SPLASH_STORAGE_NAND:
+               return splash_nand_read(bmp_load_addr, offset, read_size);
+       default:
+               printf("Unknown splash location\n");
+       }
+
+       return -EINVAL;
 }
 
-static int splash_load_raw(u32 bmp_load_addr, int offset)
+static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr)
 {
        struct bmp_header *bmp_hdr;
        int res;
@@ -44,7 +58,7 @@ static int splash_load_raw(u32 bmp_load_addr, int offset)
        if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp)
                goto splash_address_too_high;
 
-       res = splash_storage_read(bmp_load_addr, offset, bmp_header_size);
+       res = splash_storage_read(location, bmp_load_addr, bmp_header_size);
        if (res < 0)
                return res;
 
@@ -54,7 +68,7 @@ static int splash_load_raw(u32 bmp_load_addr, int offset)
        if (bmp_load_addr + bmp_size >= gd->start_addr_sp)
                goto splash_address_too_high;
 
-       return splash_storage_read(bmp_load_addr, offset, bmp_size);
+       return splash_storage_read(location, bmp_load_addr, bmp_size);
 
 splash_address_too_high:
        printf("Error: splashimage address too high. Data overwrites U-Boot "
@@ -63,8 +77,46 @@ splash_address_too_high:
        return -EFAULT;
 }
 
-int cl_splash_screen_prepare(int offset)
+/**
+ * select_splash_location - return the splash location based on board support
+ *                         and env variable "splashsource".
+ *
+ * @locations:         An array of supported splash locations.
+ * @size:              Size of splash_locations array.
+ *
+ * @return: If a null set of splash locations is given, or
+ *         splashsource env variable is set to unsupported value
+ *                     return NULL.
+ *         If splashsource env variable is not defined
+ *                     return the first entry in splash_locations as default.
+ *         If splashsource env variable contains a supported value
+ *                     return the location selected by splashsource.
+ */
+static struct splash_location *select_splash_location(
+                           struct splash_location *locations, uint size)
+{
+       int i;
+       char *env_splashsource;
+
+       if (!locations || size == 0)
+               return NULL;
+
+       env_splashsource = getenv("splashsource");
+       if (env_splashsource == NULL)
+               return &locations[0];
+
+       for (i = 0; i < size; i++) {
+               if (!strcmp(locations[i].name, env_splashsource))
+                       return &locations[i];
+       }
+
+       printf("splashsource env variable set to unsupported value\n");
+       return NULL;
+}
+
+int cl_splash_screen_prepare(struct splash_location *locations, uint size)
 {
+       struct splash_location *splash_location;
        char *env_splashimage_value;
        u32 bmp_load_addr;
 
@@ -78,5 +130,9 @@ int cl_splash_screen_prepare(int offset)
                return -EFAULT;
        }
 
-       return splash_load_raw(bmp_load_addr, offset);
+       splash_location = select_splash_location(locations, size);
+       if (!splash_location)
+               return -EINVAL;
+
+       return splash_load_raw(splash_location, bmp_load_addr);
 }