From 5af7d0f090b9fe2464d7980841b940846a547716 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 13 Jun 2013 17:13:11 -0600 Subject: lcd: remove unaligned access in lcd_dt_simplefb_configure_node() Some ARM compilers may emit code that makes unaligned accesses when faced with constructs such as: const char format[] = "r5g6b5"; Make this data static since it doesn't chagne; the compiler will simply place it into the .rodata section directly, and avoid any unaligned run- time initialization. Signed-off-by: Stephen Warren --- common/lcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'common') diff --git a/common/lcd.c b/common/lcd.c index 3a60484eea..c9a589e976 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -1193,7 +1193,7 @@ static int lcd_dt_simplefb_configure_node(void *blob, int off) u32 stride; fdt32_t cells[2]; int ret; - const char format[] = + static const char format[] = #if LCD_BPP == LCD_COLOR16 "r5g6b5"; #else @@ -1239,8 +1239,8 @@ static int lcd_dt_simplefb_configure_node(void *blob, int off) 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"); -- cgit v1.2.1 From f7ef9d610cb28d31c106792f18b58424e39275c7 Mon Sep 17 00:00:00 2001 From: Piotr Wilczek Date: Wed, 5 Jun 2013 08:14:30 +0200 Subject: lcd: align bmp header when uncopmressing image When compressed image is loaded, it must be decompressed to an aligned address + 2 to avoid unaligned access exception on some ARM platforms. Signed-off-by: Piotr Wilczek Signed-off-by: Kyungmin Park CC: Anatolij Gustschin CC: Wolfgang Denk Signed-off-by: Anatolij Gustschin --- common/cmd_bmp.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'common') diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index 5a52edde31..946031deaa 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -38,14 +38,19 @@ static int bmp_info (ulong addr); /* * 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 +60,19 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) * 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 +80,6 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) puts("Image could be truncated" " (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n"); - bmp = dst; - /* * Check for bmp mark 'BM' */ @@ -81,10 +91,12 @@ bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp) 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; } @@ -189,11 +201,12 @@ U_BOOT_CMD( 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 +218,8 @@ static int bmp_info(ulong addr) 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 +238,12 @@ int bmp_display(ulong addr, int x, int y) { 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 +258,8 @@ int bmp_display(ulong addr, int x, int y) # 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; } -- cgit v1.2.1 From dd4425e85260c2e750676e2dc9c225cfff1b4bcd Mon Sep 17 00:00:00 2001 From: Robert Winkler Date: Mon, 17 Jun 2013 11:31:29 -0700 Subject: video: lcd: Add CONFIG_SPLASH_SCREEN_PREPARE support to CONFIG_VIDEO Create splash.c/h to put the function and any future common splash screen code in. Signed-off-by: Robert Winkler Acked-by: Igor Grinberg --- common/Makefile | 1 + common/lcd.c | 16 +++------------- common/splash.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 13 deletions(-) create mode 100644 common/splash.c (limited to 'common') diff --git a/common/Makefile b/common/Makefile index 48791b7ffc..53c92ef62e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -196,6 +196,7 @@ COBJS-y += flash.o 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/lcd.c b/common/lcd.c index c9a589e976..95006aa124 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -43,6 +43,8 @@ #include #include +#include + #if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \ defined(CONFIG_CPU_MONAHANS) #define CONFIG_CPU_PXA @@ -1072,18 +1074,6 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #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,7 +1086,7 @@ static void *lcd_logo(void) 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 diff --git a/common/splash.c b/common/splash.c new file mode 100644 index 0000000000..5cf52723a5 --- /dev/null +++ b/common/splash.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2013, Boundary Devices + * + * 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 +#include + +#ifdef CONFIG_SPLASH_SCREEN_PREPARE +int splash_screen_prepare(void) +{ + return board_splash_screen_prepare(); +} +#else +int splash_screen_prepare(void) +{ + return 0; +} +#endif -- cgit v1.2.1 From 59b15922119f79289df6714972acaeec0de1fe95 Mon Sep 17 00:00:00 2001 From: Robert Winkler Date: Mon, 17 Jun 2013 11:31:30 -0700 Subject: video: lcd: Make splash_screen_prepare weak, remove config macro Remove CONFIG_SPLASH_SCREEN_PREPARE from README Add doc/README.splashprepare to document functionality Signed-off-by: Robert Winkler Acked-by: Igor Grinberg --- common/splash.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'common') diff --git a/common/splash.c b/common/splash.c index 5cf52723a5..c7444977ed 100644 --- a/common/splash.c +++ b/common/splash.c @@ -21,16 +21,11 @@ */ #include -#include -#ifdef CONFIG_SPLASH_SCREEN_PREPARE -int splash_screen_prepare(void) -{ - return board_splash_screen_prepare(); -} -#else -int splash_screen_prepare(void) +int __splash_screen_prepare(void) { return 0; } -#endif + +int splash_screen_prepare(void) + __attribute__ ((weak, alias("__splash_screen_prepare"))); -- cgit v1.2.1 From ff8fb56b6f7edafc1bcba8ef008b3f368cabe60d Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 2 Jul 2013 00:04:05 +0200 Subject: video: consolidate splash screen alignment code Code for checking "splashpos" environment variable is duplicated in drivers, move it to the common function. Call this function also in the bmp display command to consider "splashpos" settings. Signed-off-by: Anatolij Gustschin Acked-by: Otavio Salvador --- common/cmd_bmp.c | 3 +++ common/lcd.c | 19 ++----------------- common/splash.c | 25 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 17 deletions(-) (limited to 'common') diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c index 946031deaa..a7c5fbd269 100644 --- a/common/cmd_bmp.c +++ b/common/cmd_bmp.c @@ -31,6 +31,7 @@ #include #include #include +#include #include static int bmp_info (ulong addr); @@ -125,6 +126,8 @@ static int do_bmp_display(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar 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; diff --git a/common/lcd.c b/common/lcd.c index 95006aa124..50ea4d6cac 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -1089,23 +1089,8 @@ static void *lcd_logo(void) 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; diff --git a/common/splash.c b/common/splash.c index c7444977ed..18885f1bfe 100644 --- a/common/splash.c +++ b/common/splash.c @@ -20,6 +20,7 @@ * */ +#include #include int __splash_screen_prepare(void) @@ -29,3 +30,27 @@ int __splash_screen_prepare(void) 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 */ -- cgit v1.2.1