Merge branch 'master' of git://git.denx.de/u-boot-video
diff --git a/README b/README
index 85e5a8d..33b5728 100644
--- a/README
+++ b/README
@@ -1648,14 +1648,6 @@
 			=> vertically centered image
 			   at x = dspWidth - bmpWidth - 9
 
-		CONFIG_SPLASH_SCREEN_PREPARE
-
-		If this option is set then the board_splash_screen_prepare()
-		function, which must be defined in your code, is called as part
-		of the splash screen display sequence. It gives the board an
-		opportunity to prepare the splash image data before it is
-		processed and sent to the frame buffer by U-Boot.
-
 - Gzip compressed BMP image support: CONFIG_VIDEO_BMP_GZIP
 
 		If this option is set, additionally to standard BMP
diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c
index b0b80e5..95098af 100644
--- a/board/compulab/cm_t35/cm_t35.c
+++ b/board/compulab/cm_t35/cm_t35.c
@@ -120,7 +120,7 @@
 }
 #endif /* CONFIG_CMD_NAND */
 
-int board_splash_screen_prepare(void)
+int splash_screen_prepare(void)
 {
 	char *env_splashimage_value;
 	u32 bmp_load_addr;
diff --git a/common/Makefile b/common/Makefile
index 48791b7..53c92ef 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -196,6 +196,7 @@
 COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
 COBJS-$(CONFIG_I2C_EDID) += edid.o
 COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
+COBJS-y += splash.o
 COBJS-$(CONFIG_LCD) += lcd.o
 COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
 COBJS-$(CONFIG_MENU) += menu.o
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index 5a52edd..a7c5fbd 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -31,6 +31,7 @@
 #include <command.h>
 #include <asm/byteorder.h>
 #include <malloc.h>
+#include <splash.h>
 #include <video.h>
 
 static int bmp_info (ulong addr);
@@ -38,14 +39,19 @@
 /*
  * Allocate and decompress a BMP image using gunzip().
  *
- * Returns a pointer to the decompressed image data. Must be freed by
- * the caller after use.
+ * Returns a pointer to the decompressed image data. This pointer is
+ * aligned to 32-bit-aligned-address + 2.
+ * See doc/README.displaying-bmps for explanation.
+ *
+ * The allocation address is passed to 'alloc_addr' and must be freed
+ * by the caller after use.
  *
  * Returns NULL if decompression failed, or if the decompressed data
  * didn't contain a valid BMP signature.
  */
 #ifdef CONFIG_VIDEO_BMP_GZIP
-bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
+bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp,
+			void **alloc_addr)
 {
 	void *dst;
 	unsigned long len;
@@ -55,12 +61,19 @@
 	 * Decompress bmp image
 	 */
 	len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE;
-	dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE);
+	/* allocate extra 3 bytes for 32-bit-aligned-address + 2 alignment */
+	dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE + 3);
 	if (dst == NULL) {
 		puts("Error: malloc in gunzip failed!\n");
 		return NULL;
 	}
-	if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) {
+
+	bmp = dst;
+
+	/* align to 32-bit-aligned-address + 2 */
+	bmp = (bmp_image_t *)((((unsigned int)dst + 1) & ~3) + 2);
+
+	if (gunzip(bmp, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, (uchar *)addr, &len) != 0) {
 		free(dst);
 		return NULL;
 	}
@@ -68,8 +81,6 @@
 		puts("Image could be truncated"
 				" (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n");
 
-	bmp = dst;
-
 	/*
 	 * Check for bmp mark 'BM'
 	 */
@@ -81,10 +92,12 @@
 
 	debug("Gzipped BMP image detected!\n");
 
+	*alloc_addr = dst;
 	return bmp;
 }
 #else
-bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp)
+bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp,
+			void **alloc_addr)
 {
 	return NULL;
 }
@@ -113,6 +126,8 @@
 	ulong addr;
 	int x = 0, y = 0;
 
+	splash_get_pos(&x, &y);
+
 	switch (argc) {
 	case 1:		/* use load_addr as default address */
 		addr = load_addr;
@@ -189,11 +204,12 @@
 static int bmp_info(ulong addr)
 {
 	bmp_image_t *bmp=(bmp_image_t *)addr;
+	void *bmp_alloc_addr = NULL;
 	unsigned long len;
 
 	if (!((bmp->header.signature[0]=='B') &&
 	      (bmp->header.signature[1]=='M')))
-		bmp = gunzip_bmp(addr, &len);
+		bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr);
 
 	if (bmp == NULL) {
 		printf("There is no valid bmp file at the given address\n");
@@ -205,8 +221,8 @@
 	printf("Bits per pixel: %d\n", le16_to_cpu(bmp->header.bit_count));
 	printf("Compression   : %d\n", le32_to_cpu(bmp->header.compression));
 
-	if ((unsigned long)bmp != addr)
-		free(bmp);
+	if (bmp_alloc_addr)
+		free(bmp_alloc_addr);
 
 	return(0);
 }
@@ -225,11 +241,12 @@
 {
 	int ret;
 	bmp_image_t *bmp = (bmp_image_t *)addr;
+	void *bmp_alloc_addr = NULL;
 	unsigned long len;
 
 	if (!((bmp->header.signature[0]=='B') &&
 	      (bmp->header.signature[1]=='M')))
-		bmp = gunzip_bmp(addr, &len);
+		bmp = gunzip_bmp(addr, &len, &bmp_alloc_addr);
 
 	if (!bmp) {
 		printf("There is no valid bmp file at the given address\n");
@@ -244,8 +261,8 @@
 # error bmp_display() requires CONFIG_LCD or CONFIG_VIDEO
 #endif
 
-	if ((unsigned long)bmp != addr)
-		free(bmp);
+	if (bmp_alloc_addr)
+		free(bmp_alloc_addr);
 
 	return ret;
 }
diff --git a/common/lcd.c b/common/lcd.c
index 3a60484..50ea4d6 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -43,6 +43,8 @@
 #include <lcd.h>
 #include <watchdog.h>
 
+#include <splash.h>
+
 #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \
 	defined(CONFIG_CPU_MONAHANS)
 #define CONFIG_CPU_PXA
@@ -1072,18 +1074,6 @@
 }
 #endif
 
-#ifdef CONFIG_SPLASH_SCREEN_PREPARE
-static inline int splash_screen_prepare(void)
-{
-	return board_splash_screen_prepare();
-}
-#else
-static inline int splash_screen_prepare(void)
-{
-	return 0;
-}
-#endif
-
 static void *lcd_logo(void)
 {
 #ifdef CONFIG_SPLASH_SCREEN
@@ -1096,26 +1086,11 @@
 		do_splash = 0;
 
 		if (splash_screen_prepare())
-			return (void *)gd->fb_base;
+			return (void *)lcd_base;
 
 		addr = simple_strtoul (s, NULL, 16);
-#ifdef CONFIG_SPLASH_SCREEN_ALIGN
-		s = getenv("splashpos");
-		if (s != NULL) {
-			if (s[0] == 'm')
-				x = BMP_ALIGN_CENTER;
-			else
-				x = simple_strtol(s, NULL, 0);
 
-			s = strchr(s + 1, ',');
-			if (s != NULL) {
-				if (s[1] == 'm')
-					y = BMP_ALIGN_CENTER;
-				else
-					y = simple_strtol (s + 1, NULL, 0);
-			}
-		}
-#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+		splash_get_pos(&x, &y);
 
 		if (bmp_display(addr, x, y) == 0)
 			return (void *)lcd_base;
@@ -1193,7 +1168,7 @@
 	u32 stride;
 	fdt32_t cells[2];
 	int ret;
-	const char format[] =
+	static const char format[] =
 #if LCD_BPP == LCD_COLOR16
 		"r5g6b5";
 #else
@@ -1239,8 +1214,8 @@
 
 int lcd_dt_simplefb_add_node(void *blob)
 {
-	const char compat[] = "simple-framebuffer";
-	const char disabled[] = "disabled";
+	static const char compat[] = "simple-framebuffer";
+	static const char disabled[] = "disabled";
 	int off, ret;
 
 	off = fdt_add_subnode(blob, 0, "framebuffer");
diff --git a/common/splash.c b/common/splash.c
new file mode 100644
index 0000000..18885f1
--- /dev/null
+++ b/common/splash.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/
+ *
+ */
+
+#include <common.h>
+#include <splash.h>
+
+int __splash_screen_prepare(void)
+{
+	return 0;
+}
+
+int splash_screen_prepare(void)
+	__attribute__ ((weak, alias("__splash_screen_prepare")));
+
+
+#ifdef CONFIG_SPLASH_SCREEN_ALIGN
+void splash_get_pos(int *x, int *y)
+{
+	char *s = getenv("splashpos");
+
+	if (!s)
+		return;
+
+	if (s[0] == 'm')
+		*x = BMP_ALIGN_CENTER;
+	else
+		*x = simple_strtol(s, NULL, 0);
+
+	s = strchr(s + 1, ',');
+	if (s != NULL) {
+		if (s[1] == 'm')
+			*y = BMP_ALIGN_CENTER;
+		else
+			*y = simple_strtol(s + 1, NULL, 0);
+	}
+}
+#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
diff --git a/doc/README.splashprepare b/doc/README.splashprepare
new file mode 100644
index 0000000..61b4ec5
--- /dev/null
+++ b/doc/README.splashprepare
@@ -0,0 +1,8 @@
+---------------------------------------------------------------------
+Splash Screen
+---------------------------------------------------------------------
+The splash_screen_prepare() function is a weak function defined in
+common/splash.c. It is called as part of the splash screen display
+sequence. It gives the board an opportunity to prepare the splash
+image data before it is processed and sent to the frame buffer by
+U-Boot.  Define your own version to use this feature.
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index b10f159..e384b71 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -181,6 +181,8 @@
  */
 #include <video_fb.h>
 
+#include <splash.h>
+
 /*
  * some Macros
  */
@@ -220,13 +222,9 @@
 #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
 #include <watchdog.h>
 #include <bmp_layout.h>
-
-#ifdef CONFIG_SPLASH_SCREEN_ALIGN
-#define BMP_ALIGN_CENTER	0x7FFF
+#include <splash.h>
 #endif
 
-#endif
-
 /*
  * Cursor definition:
  * CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/input/i8042.c)
@@ -1974,31 +1972,14 @@
 	__maybe_unused ulong addr;
 	__maybe_unused char *s;
 
-#ifdef CONFIG_SPLASH_SCREEN_ALIGN
-	s = getenv("splashpos");
-	if (s != NULL) {
-		if (s[0] == 'm')
-			video_logo_xpos = BMP_ALIGN_CENTER;
-		else
-			video_logo_xpos = simple_strtol(s, NULL, 0);
-
-		s = strchr(s + 1, ',');
-		if (s != NULL) {
-			if (s[1] == 'm')
-				video_logo_ypos = BMP_ALIGN_CENTER;
-			else
-				video_logo_ypos = simple_strtol(s + 1, NULL, 0);
-		}
-	}
-#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+	splash_get_pos(&video_logo_xpos, &video_logo_ypos);
 
 #ifdef CONFIG_SPLASH_SCREEN
 	s = getenv("splashimage");
 	if (s != NULL) {
-
+		splash_screen_prepare();
 		addr = simple_strtoul(s, NULL, 16);
 
-
 		if (video_display_bitmap(addr,
 					video_logo_xpos,
 					video_logo_ypos) == 0) {
diff --git a/drivers/video/s6e8ax0.c b/drivers/video/s6e8ax0.c
index 176c518..f6db694 100644
--- a/drivers/video/s6e8ax0.c
+++ b/drivers/video/s6e8ax0.c
@@ -29,7 +29,7 @@
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
 	int reverse = dsim_dev->dsim_lcd_dev->reverse_panel;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x4c,
 		0x6e, 0x10, 0x27, 0x7d, 0x3f, 0x10, 0x00, 0x00, 0x20,
 		0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08,
@@ -37,7 +37,7 @@
 		0xff, 0xff, 0xc8
 	};
 
-	const unsigned char data_to_send_reverse[] = {
+	static const unsigned char data_to_send_reverse[] = {
 		0xf8, 0x19, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3c,
 		0x7d, 0x08, 0x27, 0x7d, 0x3f, 0x00, 0x00, 0x00, 0x20,
 		0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08,
@@ -58,7 +58,7 @@
 static void s6e8ax0_display_cond(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf2, 0x80, 0x03, 0x0d
 	};
 
@@ -71,7 +71,7 @@
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
 	/* 7500K 2.2 Set : 30cd */
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xfa, 0x01, 0x60, 0x10, 0x60, 0xf5, 0x00, 0xff, 0xad,
 		0xaf, 0xba, 0xc3, 0xd8, 0xc5, 0x9f, 0xc6, 0x9e, 0xc1,
 		0xdc, 0xc0, 0x00, 0x61, 0x00, 0x5a, 0x00, 0x74,
@@ -92,7 +92,7 @@
 static void s6e8ax0_etc_source_control(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf6, 0x00, 0x02, 0x00
 	};
 
@@ -104,7 +104,7 @@
 static void s6e8ax0_etc_pentile_control(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
 		0x00
 	};
@@ -117,7 +117,7 @@
 static void s6e8ax0_etc_mipi_control1(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
 	};
 
@@ -129,7 +129,7 @@
 static void s6e8ax0_etc_mipi_control2(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
 	};
 
@@ -141,7 +141,7 @@
 static void s6e8ax0_etc_power_control(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
 	};
 
@@ -159,7 +159,7 @@
 static void s6e8ax0_etc_mipi_control4(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
 	};
 
@@ -170,7 +170,7 @@
 static void s6e8ax0_elvss_set(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xb1, 0x04, 0x00
 	};
 
@@ -198,7 +198,7 @@
 static void s6e8ax0_apply_level1_key(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf0, 0x5a, 0x5a
 	};
 
@@ -209,7 +209,7 @@
 static void s6e8ax0_apply_mtp_key(struct mipi_dsim_device *dsim_dev)
 {
 	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
-	const unsigned char data_to_send[] = {
+	static const unsigned char data_to_send[] = {
 		0xf1, 0x5a, 0x5a
 	};
 
diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h
index c6e357a..b258da9 100644
--- a/include/configs/cm_t35.h
+++ b/include/configs/cm_t35.h
@@ -339,6 +339,5 @@
 #define CONFIG_SPLASH_SCREEN
 #define CONFIG_CMD_BMP
 #define CONFIG_BMP_16BPP
-#define CONFIG_SPLASH_SCREEN_PREPARE
 
 #endif /* __CONFIG_H */
diff --git a/include/lcd.h b/include/lcd.h
index 30225ed..8718a01 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -37,7 +37,6 @@
 
 void lcd_ctrl_init(void *lcdbase);
 void lcd_enable(void);
-int board_splash_screen_prepare(void);
 
 /* setcolreg used in 8bpp/16bpp; initcolregs used in monochrome */
 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue);
@@ -46,7 +45,8 @@
 int lcd_getfgcolor(void);
 
 /* gunzip_bmp used if CONFIG_VIDEO_BMP_GZIP */
-struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp);
+struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
+			     void **alloc_addr);
 int bmp_display(ulong addr, int x, int y);
 
 /**
diff --git a/include/splash.h b/include/splash.h
new file mode 100644
index 0000000..89ee7b2
--- /dev/null
+++ b/include/splash.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/
+ */
+
+#ifndef _SPLASH_H_
+#define _SPLASH_H_
+
+
+int splash_screen_prepare(void);
+
+#ifdef CONFIG_SPLASH_SCREEN_ALIGN
+void splash_get_pos(int *x, int *y);
+#else
+static inline void splash_get_pos(int *x, int *y) { }
+#endif
+
+#define BMP_ALIGN_CENTER	0x7FFF
+
+#endif