diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 2 | ||||
-rw-r--r-- | common/board_f.c | 4 | ||||
-rw-r--r-- | common/board_r.c | 14 | ||||
-rw-r--r-- | common/cmd_bdinfo.c | 16 | ||||
-rw-r--r-- | common/lcd.c | 358 | ||||
-rw-r--r-- | common/lcd_simplefb.c | 59 | ||||
-rw-r--r-- | common/splash.c | 16 | ||||
-rw-r--r-- | common/splash_source.c | 176 |
8 files changed, 360 insertions, 285 deletions
diff --git a/common/Makefile b/common/Makefile index 9579ab4..7216a13 100644 --- a/common/Makefile +++ b/common/Makefile @@ -198,7 +198,9 @@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o obj-$(CONFIG_I2C_EDID) += edid.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-y += splash.o +obj-$(CONFIG_SPLASH_SOURCE) += splash_source.o obj-$(CONFIG_LCD) += lcd.o lcd_console.o +obj-$(CONFIG_LCD_DT_SIMPLEFB) += lcd_simplefb.o obj-$(CONFIG_LYNXKDI) += lynxkdi.o obj-$(CONFIG_MENU) += menu.o obj-$(CONFIG_MODEM_SUPPORT) += modem.o diff --git a/common/board_f.c b/common/board_f.c index 6c44dee..bdad36b 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -262,7 +262,7 @@ static int zero_global_data(void) static int setup_mon_len(void) { -#ifdef __ARM__ +#if defined(__ARM__) || defined(__MICROBLAZE__) gd->mon_len = (ulong)&__bss_end - (ulong)_start; #elif defined(CONFIG_SANDBOX) gd->mon_len = (ulong)&_end - (ulong)_init; @@ -909,7 +909,7 @@ static init_fnc_t init_sequence_f[] = { #endif announce_dram_init, /* TODO: unify all these dram functions? */ -#if defined(CONFIG_ARM) || defined(CONFIG_X86) +#if defined(CONFIG_ARM) || defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) dram_init, /* configure available RAM banks */ #endif #if defined(CONFIG_MIPS) || defined(CONFIG_PPC) diff --git a/common/board_r.c b/common/board_r.c index 68a9448..907b33c 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -294,6 +294,15 @@ static int initr_announce(void) return 0; } +#ifdef CONFIG_NEEDS_MANUAL_RELOC +static int initr_manual_reloc_cmdtable(void) +{ + fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd), + ll_entry_count(cmd_tbl_t, cmd)); + return 0; +} +#endif + #if !defined(CONFIG_SYS_NO_FLASH) static int initr_flash(void) { @@ -702,6 +711,9 @@ init_fnc_t init_sequence_r[] = { initr_serial, initr_announce, INIT_FUNC_WATCHDOG_RESET +#ifdef CONFIG_NEEDS_MANUAL_RELOC + initr_manual_reloc_cmdtable, +#endif #ifdef CONFIG_PPC initr_trap, #endif @@ -801,7 +813,7 @@ init_fnc_t init_sequence_r[] = { #if defined(CONFIG_ARM) initr_enable_interrupts, #endif -#ifdef CONFIG_X86 +#if defined(CONFIG_X86) || defined(CONFIG_MICROBLAZE) timer_init, /* initialize timer */ #endif #if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT) diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index e6d8a7a..e9eab23 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -183,8 +183,14 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { bd_t *bd = gd->bd; - print_num("mem start ", (ulong)bd->bi_memstart); - print_lnum("mem size ", (u64)bd->bi_memsize); + int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + print_num("DRAM bank", i); + print_num("-> start", bd->bi_dram[i].start); + print_num("-> size", bd->bi_dram[i].size); + } + print_num("flash start ", (ulong)bd->bi_flashstart); print_num("flash size ", (ulong)bd->bi_flashsize); print_num("flash offset ", (ulong)bd->bi_flashoffset); @@ -196,6 +202,12 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) print_eths(); #endif printf("baudrate = %u bps\n", gd->baudrate); + print_num("relocaddr", gd->relocaddr); + print_num("reloc off", gd->reloc_off); + print_num("fdt_blob", (ulong)gd->fdt_blob); + print_num("new_fdt", (ulong)gd->new_fdt); + print_num("fdt_size", (ulong)gd->fdt_size); + return 0; } diff --git a/common/lcd.c b/common/lcd.c index 1195a54..f33942c 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -1,5 +1,5 @@ /* - * Common LCD routines for supported CPUs + * Common LCD routines * * (C) Copyright 2001-2002 * Wolfgang Denk, DENX Software Engineering -- wd@denx.de @@ -7,62 +7,27 @@ * SPDX-License-Identifier: GPL-2.0+ */ -/************************************************************************/ -/* ** HEADER FILES */ -/************************************************************************/ - /* #define DEBUG */ - #include <config.h> #include <common.h> #include <command.h> -#include <stdarg.h> -#include <search.h> #include <env_callback.h> #include <linux/types.h> #include <stdio_dev.h> -#if defined(CONFIG_POST) -#include <post.h> -#endif #include <lcd.h> #include <watchdog.h> #include <asm/unaligned.h> #include <splash.h> #include <asm/io.h> #include <asm/unaligned.h> -#include <fdt_support.h> - -#if defined(CONFIG_CPU_PXA25X) || defined(CONFIG_CPU_PXA27X) || \ - defined(CONFIG_CPU_MONAHANS) -#include <asm/byteorder.h> -#endif - -#if defined(CONFIG_MPC823) -#include <lcdvideo.h> -#endif +#include <video_font.h> -#if defined(CONFIG_ATMEL_LCD) -#include <atmel_lcdc.h> -#endif - -#if defined(CONFIG_LCD_DT_SIMPLEFB) -#include <libfdt.h> -#endif - -/************************************************************************/ -/* ** FONT DATA */ -/************************************************************************/ -#include <video_font.h> /* Get font data, width and height */ - -/************************************************************************/ -/* ** LOGO DATA */ -/************************************************************************/ #ifdef CONFIG_LCD_LOGO -# include <bmp_logo.h> /* Get logo data, width and height */ -# include <bmp_logo_data.h> -# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16) -# error Default Color Map overlaps with Logo Color Map -# endif +#include <bmp_logo.h> +#include <bmp_logo_data.h> +#if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16) +#error Default Color Map overlaps with Logo Color Map +#endif #endif #ifdef CONFIG_SANDBOX @@ -75,30 +40,23 @@ #if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \ (LCD_BPP != LCD_COLOR32) -# error Unsupported LCD BPP. +#error Unsupported LCD BPP. #endif DECLARE_GLOBAL_DATA_PTR; static int lcd_init(void *lcdbase); - -static void *lcd_logo(void); - +static void lcd_logo(void); static void lcd_setfgcolor(int color); static void lcd_setbgcolor(int color); static int lcd_color_fg; static int lcd_color_bg; int lcd_line_length; - char lcd_is_enabled = 0; - static void *lcd_base; /* Start of framebuffer memory */ - static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */ -/************************************************************************/ - /* Flush LCD activity to the caches */ void lcd_sync(void) { @@ -128,8 +86,6 @@ void lcd_set_flush_dcache(int flush) lcd_flush_dcache = (flush != 0); } -/*----------------------------------------------------------------------*/ - static void lcd_stub_putc(struct stdio_dev *dev, const char c) { lcd_putc(c); @@ -140,9 +96,7 @@ static void lcd_stub_puts(struct stdio_dev *dev, const char *s) lcd_puts(s); } -/************************************************************************/ -/** Small utility to check that you got the colours right */ -/************************************************************************/ +/* Small utility to check that you got the colours right */ #ifdef LCD_TEST_PATTERN #define N_BLK_VERT 2 @@ -176,10 +130,6 @@ static void test_pattern(void) } #endif /* LCD_TEST_PATTERN */ - -/************************************************************************/ -/* ** GENERIC Initialization Routines */ -/************************************************************************/ /* * With most lcd drivers the line length is set up * by calculating it from panel_info parameters. Some @@ -199,7 +149,7 @@ int drv_lcd_init(void) lcd_base = map_sysmem(gd->fb_base, 0); - lcd_init(lcd_base); /* LCD initialization */ + lcd_init(lcd_base); /* Device initialization */ memset(&lcddev, 0, sizeof(lcddev)); @@ -215,11 +165,13 @@ int drv_lcd_init(void) return (rc == 0) ? 1 : rc; } -/*----------------------------------------------------------------------*/ void lcd_clear(void) { short console_rows, console_cols; int bg_color; + char *s; + ulong addr; + static int do_splash = 1; #if LCD_BPP == LCD_COLOR8 /* Setting the palette */ lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0); @@ -269,7 +221,23 @@ void lcd_clear(void) #endif console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH; lcd_init_console(lcd_base, console_rows, console_cols); - lcd_init_console(lcd_logo(), console_rows, console_cols); + if (do_splash) { + s = getenv("splashimage"); + if (s) { + do_splash = 0; + addr = simple_strtoul(s, NULL, 16); + if (lcd_splash(addr) == 0) { + lcd_sync(); + return; + } + } + } + + lcd_logo(); +#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) + addr = (ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length; + lcd_init_console((void *)addr, console_rows, console_cols); +#endif lcd_sync(); } @@ -279,20 +247,11 @@ static int do_lcd_clear(cmd_tbl_t *cmdtp, int flag, int argc, lcd_clear(); return 0; } - -U_BOOT_CMD( - cls, 1, 1, do_lcd_clear, - "clear screen", - "" -); - -/*----------------------------------------------------------------------*/ +U_BOOT_CMD(cls, 1, 1, do_lcd_clear, "clear screen", ""); static int lcd_init(void *lcdbase) { - /* Initialize the lcd controller */ debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase); - lcd_ctrl_init(lcdbase); /* @@ -322,10 +281,6 @@ static int lcd_init(void *lcdbase) return 0; } - -/************************************************************************/ -/* ** ROM capable initialization part - needed to reserve FB memory */ -/************************************************************************/ /* * This is called early in the system initialization to grab memory * for the LCD controller. @@ -356,8 +311,6 @@ ulong lcd_setmem(ulong addr) return addr; } -/*----------------------------------------------------------------------*/ - static void lcd_setfgcolor(int color) { lcd_color_fg = color; @@ -368,8 +321,6 @@ int lcd_getfgcolor(void) return lcd_color_fg; } -/*----------------------------------------------------------------------*/ - static void lcd_setbgcolor(int color) { lcd_color_bg = color; @@ -380,91 +331,30 @@ int lcd_getbgcolor(void) return lcd_color_bg; } -/************************************************************************/ -/* ** Chipset depending Bitmap / Logo stuff... */ -/************************************************************************/ -static inline ushort *configuration_get_cmap(void) +#ifdef CONFIG_LCD_LOGO +__weak void lcd_logo_set_cmap(void) { -#if defined CONFIG_CPU_PXA - struct pxafb_info *fbi = &panel_info.pxa; - return (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) - immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - cpm8xx_t *cp = &(immr->im_cpm); - return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); -#elif defined(CONFIG_ATMEL_LCD) - return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); -#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) - return panel_info.cmap; -#elif defined(CONFIG_LCD_LOGO) - return bmp_logo_palette; -#else - return NULL; -#endif + int i; + ushort *cmap = configuration_get_cmap(); + + for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) + *cmap++ = bmp_logo_palette[i]; } -#ifdef CONFIG_LCD_LOGO -void bitmap_plot(int x, int y) +void lcd_logo_plot(int x, int y) { -#ifdef CONFIG_ATMEL_LCD - uint *cmap = (uint *)bmp_logo_palette; -#else - ushort *cmap = (ushort *)bmp_logo_palette; -#endif ushort i, j; - uchar *bmap; - uchar *fb; - ushort *fb16; -#if defined(CONFIG_MPC823) - immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; - cpm8xx_t *cp = &(immr->im_cpm); -#endif + uchar *bmap = &bmp_logo_bitmap[0]; unsigned bpix = NBITS(panel_info.vl_bpix); + uchar *fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); + ushort *fb16; - debug("Logo: width %d height %d colors %d cmap %d\n", - BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS, - ARRAY_SIZE(bmp_logo_palette)); - - bmap = &bmp_logo_bitmap[0]; - fb = (uchar *)(lcd_base + y * lcd_line_length + x * bpix / 8); + debug("Logo: width %d height %d colors %d\n", + BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); if (bpix < 12) { - /* Leave room for default color map - * default case: generic system with no cmap (most likely 16bpp) - * cmap was set to the source palette, so no change is done. - * This avoids even more ifdefs in the next stanza - */ -#if defined(CONFIG_MPC823) - cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]); -#elif defined(CONFIG_ATMEL_LCD) - cmap = (uint *)configuration_get_cmap(); -#else - cmap = configuration_get_cmap(); -#endif - WATCHDOG_RESET(); - - /* Set color map */ - for (i = 0; i < ARRAY_SIZE(bmp_logo_palette); ++i) { - ushort colreg = bmp_logo_palette[i]; -#ifdef CONFIG_ATMEL_LCD - uint lut_entry; -#ifdef CONFIG_ATMEL_LCD_BGR555 - lut_entry = ((colreg & 0x000F) << 11) | - ((colreg & 0x00F0) << 2) | - ((colreg & 0x0F00) >> 7); -#else /* CONFIG_ATMEL_LCD_RGB565 */ - lut_entry = ((colreg & 0x000F) << 1) | - ((colreg & 0x00F0) << 3) | - ((colreg & 0x0F00) << 4); -#endif - *(cmap + BMP_LOGO_OFFSET) = lut_entry; - cmap++; -#else /* !CONFIG_ATMEL_LCD */ - *cmap++ = colreg; -#endif /* CONFIG_ATMEL_LCD */ - } - + lcd_logo_set_cmap(); WATCHDOG_RESET(); for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { @@ -493,16 +383,10 @@ void bitmap_plot(int x, int y) lcd_sync(); } #else -static inline void bitmap_plot(int x, int y) {} +static inline void lcd_logo_plot(int x, int y) {} #endif /* CONFIG_LCD_LOGO */ -/*----------------------------------------------------------------------*/ #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) -/* - * Display the BMP file located at address bmp_image. - * Only uncompressed. - */ - #ifdef CONFIG_SPLASH_SCREEN_ALIGN #define BMP_ALIGN_CENTER 0x7FFF @@ -523,9 +407,7 @@ static void splash_align_axis(int *axis, unsigned long panel_size, } #endif - #ifdef CONFIG_LCD_BMP_RLE8 - #define BMP_RLE8_ESCAPE 0 #define BMP_RLE8_EOL 0 #define BMP_RLE8_EOBMP 1 @@ -654,32 +536,40 @@ static void lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, } #endif -#if defined(CONFIG_MPC823) -#define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) -#else -#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ -#endif - -#if defined(CONFIG_BMP_16BPP) -#if defined(CONFIG_ATMEL_LCD_BGR555) -static inline void fb_put_word(uchar **fb, uchar **from) +__weak void fb_put_byte(uchar **fb, uchar **from) { - *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); - *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); - *from += 2; + *(*fb)++ = *(*from)++; } -#else -static inline void fb_put_word(uchar **fb, uchar **from) + +#if defined(CONFIG_BMP_16BPP) +__weak void fb_put_word(uchar **fb, uchar **from) { *(*fb)++ = *(*from)++; *(*fb)++ = *(*from)++; } -#endif #endif /* CONFIG_BMP_16BPP */ +__weak void lcd_set_cmap(bmp_image_t *bmp, unsigned colors) +{ + int i; + bmp_color_table_entry_t cte; + ushort *cmap = configuration_get_cmap(); + + for (i = 0; i < colors; ++i) { + cte = bmp->color_table[i]; + *cmap = (((cte.red) << 8) & 0xf800) | + (((cte.green) << 3) & 0x07e0) | + (((cte.blue) >> 3) & 0x001f); +#if defined(CONFIG_MPC823) + cmap--; +#else + cmap++; +#endif + } +} + int lcd_display_bitmap(ulong bmp_image, int x, int y) { - ushort *cmap = NULL; ushort *cmap_base = NULL; ushort i, j; uchar *fb; @@ -727,29 +617,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) debug("Display-bmp: %d x %d with %d colors\n", (int)width, (int)height, (int)colors); - if (bmp_bpix == 8) { - cmap = configuration_get_cmap(); - cmap_base = cmap; - - /* Set color map */ - for (i = 0; i < colors; ++i) { - bmp_color_table_entry_t cte = bmp->color_table[i]; -#if !defined(CONFIG_ATMEL_LCD) - ushort colreg = - ( ((cte.red) << 8) & 0xf800) | - ( ((cte.green) << 3) & 0x07e0) | - ( ((cte.blue) >> 3) & 0x001f) ; - *cmap = colreg; -#if defined(CONFIG_MPC823) - cmap--; -#else - cmap++; -#endif -#else /* CONFIG_ATMEL_LCD */ - lcd_setcolreg(i, cte.red, cte.green, cte.blue); -#endif - } - } + if (bmp_bpix == 8) + lcd_set_cmap(bmp, colors); padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width); @@ -768,8 +637,9 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) (y + height - 1) * lcd_line_length + x * bpix / 8); switch (bmp_bpix) { - case 1: /* pass through */ + case 1: case 8: { + cmap_base = configuration_get_cmap(); #ifdef CONFIG_LCD_BMP_RLE8 u32 compression = get_unaligned_le32(&bmp->header.compression); if (compression == BMP_BI_RLE8) { @@ -792,7 +662,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) WATCHDOG_RESET(); for (j = 0; j < width; j++) { if (bpix != 16) { - FB_PUT_BYTE(fb, bmap); + fb_put_byte(&fb, &bmap); } else { *(uint16_t *)fb = cmap_base[*(bmap++)]; fb += sizeof(uint16_t) / sizeof(*fb); @@ -850,42 +720,15 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) } #endif -static void *lcd_logo(void) +static void lcd_logo(void) { -#ifdef CONFIG_SPLASH_SCREEN - char *s; - ulong addr; - static int do_splash = 1; - - if (do_splash && (s = getenv("splashimage")) != NULL) { - int x = 0, y = 0; - do_splash = 0; - - if (splash_screen_prepare()) - return (void *)lcd_base; - - addr = simple_strtoul (s, NULL, 16); - - splash_get_pos(&x, &y); - - if (bmp_display(addr, x, y) == 0) - return (void *)lcd_base; - } -#endif /* CONFIG_SPLASH_SCREEN */ - - bitmap_plot(0, 0); + lcd_logo_plot(0, 0); #ifdef CONFIG_LCD_INFO lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH); lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT); lcd_show_board_info(); #endif /* CONFIG_LCD_INFO */ - -#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO) - return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length); -#else - return (void *)lcd_base; -#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */ } #ifdef CONFIG_SPLASHIMAGE_GUARD @@ -921,48 +764,3 @@ int lcd_get_pixel_height(void) { return panel_info.vl_row; } - -#if defined(CONFIG_LCD_DT_SIMPLEFB) -static int lcd_dt_simplefb_configure_node(void *blob, int off) -{ -#if LCD_BPP == LCD_COLOR16 - return fdt_setup_simplefb_node(blob, off, gd->fb_base, - panel_info.vl_col, panel_info.vl_row, - panel_info.vl_col * 2, "r5g6b5"); -#else - return -1; -#endif -} - -int lcd_dt_simplefb_add_node(void *blob) -{ - static const char compat[] = "simple-framebuffer"; - static const char disabled[] = "disabled"; - int off, ret; - - off = fdt_add_subnode(blob, 0, "framebuffer"); - if (off < 0) - return -1; - - ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); - if (ret < 0) - return -1; - - ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); - if (ret < 0) - return -1; - - return lcd_dt_simplefb_configure_node(blob, off); -} - -int lcd_dt_simplefb_enable_existing_node(void *blob) -{ - int off; - - off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); - if (off < 0) - return -1; - - return lcd_dt_simplefb_configure_node(blob, off); -} -#endif diff --git a/common/lcd_simplefb.c b/common/lcd_simplefb.c new file mode 100644 index 0000000..8db2add --- /dev/null +++ b/common/lcd_simplefb.c @@ -0,0 +1,59 @@ +/* + * Simplefb device tree support + * + * (C) Copyright 2015 + * Stephen Warren <swarren@wwwdotorg.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <lcd.h> +#include <fdt_support.h> +#include <libfdt.h> + +DECLARE_GLOBAL_DATA_PTR; + +static int lcd_dt_simplefb_configure_node(void *blob, int off) +{ +#if LCD_BPP == LCD_COLOR16 + int vl_col = lcd_get_pixel_width(); + int vl_row = lcd_get_pixel_height(); + return fdt_setup_simplefb_node(blob, off, gd->fb_base, vl_col, vl_row, + vl_col * 2, "r5g6b5"); +#else + return -1; +#endif +} + +int lcd_dt_simplefb_add_node(void *blob) +{ + static const char compat[] = "simple-framebuffer"; + static const char disabled[] = "disabled"; + int off, ret; + + off = fdt_add_subnode(blob, 0, "framebuffer"); + if (off < 0) + return -1; + + ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); + if (ret < 0) + return -1; + + ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); + if (ret < 0) + return -1; + + return lcd_dt_simplefb_configure_node(blob, off); +} + +int lcd_dt_simplefb_enable_existing_node(void *blob) +{ + int off; + + off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); + if (off < 0) + return -1; + + return lcd_dt_simplefb_configure_node(blob, off); +} diff --git a/common/splash.c b/common/splash.c index 144fb10..561d35b 100644 --- a/common/splash.c +++ b/common/splash.c @@ -22,6 +22,7 @@ #include <common.h> #include <splash.h> +#include <lcd.h> __weak int splash_screen_prepare(void) { @@ -50,3 +51,18 @@ void splash_get_pos(int *x, int *y) } } #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ + +#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_LCD) +int lcd_splash(ulong addr) +{ + int x = 0, y = 0, ret; + + ret = splash_screen_prepare(); + if (ret) + return ret; + + splash_get_pos(&x, &y); + + return bmp_display(addr, x, y); +} +#endif diff --git a/common/splash_source.c b/common/splash_source.c new file mode 100644 index 0000000..d1bb5a4 --- /dev/null +++ b/common/splash_source.c @@ -0,0 +1,176 @@ +/* + * (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il> + * + * Authors: Igor Grinberg <grinberg@compulab.co.il> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <nand.h> +#include <errno.h> +#include <splash.h> +#include <spi_flash.h> +#include <spi.h> +#include <bmp_layout.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_SPI_FLASH +static struct spi_flash *sf; +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + if (!sf) { + sf = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, + CONFIG_SF_DEFAULT_CS, + CONFIG_SF_DEFAULT_SPEED, + CONFIG_SF_DEFAULT_MODE); + if (!sf) + return -ENODEV; + } + + return spi_flash_read(sf, offset, read_size, (void *)bmp_load_addr); +} +#else +static int splash_sf_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: sf support not available\n", __func__); + return -ENOSYS; +} +#endif + +#ifdef CONFIG_CMD_NAND +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + return nand_read_skip_bad(&nand_info[nand_curr_device], offset, + &read_size, NULL, + nand_info[nand_curr_device].size, + (u_char *)bmp_load_addr); +} +#else +static int splash_nand_read(u32 bmp_load_addr, int offset, size_t read_size) +{ + debug("%s: nand support not available\n", __func__); + return -ENOSYS; +} +#endif + +static int splash_storage_read(struct splash_location *location, + u32 bmp_load_addr, size_t 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); + case SPLASH_STORAGE_SF: + return splash_sf_read(bmp_load_addr, offset, read_size); + default: + printf("Unknown splash location\n"); + } + + return -EINVAL; +} + +static int splash_load_raw(struct splash_location *location, u32 bmp_load_addr) +{ + struct bmp_header *bmp_hdr; + int res; + size_t bmp_size, bmp_header_size = sizeof(struct bmp_header); + + if (bmp_load_addr + bmp_header_size >= gd->start_addr_sp) + goto splash_address_too_high; + + res = splash_storage_read(location, bmp_load_addr, bmp_header_size); + if (res < 0) + return res; + + bmp_hdr = (struct bmp_header *)bmp_load_addr; + bmp_size = le32_to_cpu(bmp_hdr->file_size); + + if (bmp_load_addr + bmp_size >= gd->start_addr_sp) + goto splash_address_too_high; + + return splash_storage_read(location, bmp_load_addr, bmp_size); + +splash_address_too_high: + printf("Error: splashimage address too high. Data overwrites U-Boot and/or placed beyond DRAM boundaries.\n"); + + return -EFAULT; +} + +/** + * 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; +} + +/** + * splash_source_load - load splash image from a supported location. + * + * Select a splash image location based on the value of splashsource environment + * variable and the board supported splash source locations, and load a + * splashimage to the address pointed to by splashimage environment variable. + * + * @locations: An array of supported splash locations. + * @size: Size of splash_locations array. + * + * @return: 0 on success, negative value on failure. + */ +int splash_source_load(struct splash_location *locations, uint size) +{ + struct splash_location *splash_location; + char *env_splashimage_value; + u32 bmp_load_addr; + + env_splashimage_value = getenv("splashimage"); + if (env_splashimage_value == NULL) + return -ENOENT; + + bmp_load_addr = simple_strtoul(env_splashimage_value, 0, 16); + if (bmp_load_addr == 0) { + printf("Error: bad splashimage address specified\n"); + return -EFAULT; + } + + splash_location = select_splash_location(locations, size); + if (!splash_location) + return -EINVAL; + + return splash_load_raw(splash_location, bmp_load_addr); +} |