diff options
Diffstat (limited to 'board/esd/common')
-rw-r--r-- | board/esd/common/lcd.c | 258 |
1 files changed, 177 insertions, 81 deletions
diff --git a/board/esd/common/lcd.c b/board/esd/common/lcd.c index d2d642a..22b49ce 100644 --- a/board/esd/common/lcd.c +++ b/board/esd/common/lcd.c @@ -2,6 +2,9 @@ * (C) Copyright 2003-2004 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com * + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * * See file CREDITS for list of people who contributed to this * project. * @@ -24,9 +27,14 @@ #include "lcd.h" +extern int video_display_bitmap (ulong, int, int); + + int palette_index; int palette_value; - +int lcd_depth; +unsigned char *glob_lcd_reg; +unsigned char *glob_lcd_mem; #ifdef CFG_LCD_ENDIAN void lcd_setup(int lcd, int config) @@ -67,12 +75,9 @@ void lcd_setup(int lcd, int config) #endif /* #ifdef CFG_LCD_ENDIAN */ -void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, - uchar *logo_bmp, ulong len) +void lcd_bmp(uchar *logo_bmp) { int i; - ushort s1dReg; - uchar s1dValue; uchar *ptr; ushort *ptr2; ushort val; @@ -83,76 +88,37 @@ void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, unsigned char *bmp; unsigned char r, g, b; BITMAPINFOHEADER *bm_info; - int reg_byte_swap; + ulong len; + int do_free = 0; /* - * Detect epson + * Check for bmp mark 'BM' */ - if (lcd_reg[0] == 0x1c) { - /* - * Big epson detected - */ - reg_byte_swap = FALSE; - palette_index = 0x1e2; - palette_value = 0x1e4; - puts("LCD: S1D13806"); - } else if (lcd_reg[1] == 0x1c) { + if (*(ushort *)logo_bmp != 0x424d) { + /* - * Big epson detected (with register swap bug) + * Decompress bmp image */ - reg_byte_swap = TRUE; - palette_index = 0x1e3; - palette_value = 0x1e5; - puts("LCD: S1D13806S"); - } else if (lcd_reg[0] == 0x18) { + len = CFG_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CFG_LCD_LOGO_MAX_SIZE); + do_free = 1; + if (gunzip(dst, CFG_LCD_LOGO_MAX_SIZE, (uchar *)logo_bmp, &len) != 0) { + return; + } + /* - * Small epson detected (704) + * Check for bmp mark 'BM' */ - reg_byte_swap = FALSE; - palette_index = 0x15; - palette_value = 0x17; - puts("LCD: S1D13704"); - } else if (lcd_reg[0x10000] == 0x24) { + if (*(ushort *)dst != 0x424d) { + printf("LCD: Unknown image format!\n"); + free(dst); + return; + } + } else { /* - * Small epson detected (705) + * Uncompressed BMP image, just use this pointer */ - reg_byte_swap = FALSE; - palette_index = 0x15; - palette_value = 0x17; - lcd_reg += 0x10000; /* add offset for 705 regs */ - puts("LCD: S1D13705"); - } else { - puts("LCD: No controller detected!\n"); - return; - } - - for (i = 0; i<reg_count; i++) { - s1dReg = regs[i].Index; - if (reg_byte_swap) { - if ((s1dReg & 0x0001) == 0) - s1dReg |= 0x0001; - else - s1dReg &= ~0x0001; - } - s1dValue = regs[i].Value; - lcd_reg[s1dReg] = s1dValue; - } - - /* - * Decompress bmp image - */ - dst = malloc(CFG_LCD_LOGO_MAX_SIZE); - if (gunzip(dst, CFG_LCD_LOGO_MAX_SIZE, (uchar *)logo_bmp, &len) != 0) { - return; - } - - /* - * Check for bmp mark 'BM' - */ - if (*(ushort *)dst != 0x424d) { - printf("LCD: Unknown image format!\n"); - free(dst); - return; + dst = (uchar *)logo_bmp; } /* @@ -189,35 +155,48 @@ void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, /* * Write color palette */ - if (colors <= 256) { + if ((colors <= 256) && (lcd_depth <= 8)) { ptr = (unsigned char *)(dst + 14 + 40); for (i=0; i<colors; i++) { b = *ptr++; g = *ptr++; r = *ptr++; ptr++; - S1D_WRITE_PALETTE(lcd_reg, i, r, g, b); + S1D_WRITE_PALETTE(glob_lcd_reg, i, r, g, b); } } /* * Write bitmap data into framebuffer */ - ptr = lcd_mem; - ptr2 = (ushort *)lcd_mem; + ptr = glob_lcd_mem; + ptr2 = (ushort *)glob_lcd_mem; header_size = 14 + 40 + 4*colors; /* skip bmp header */ for (y=0; y<height; y++) { bmp = &dst[(height-1-y)*line_size + header_size]; - if (bpp == 24) { - for (x=0; x<width; x++) { - /* - * Generate epson 16bpp fb-format from 24bpp image - */ - b = *bmp++ >> 3; - g = *bmp++ >> 2; - r = *bmp++ >> 3; - val = ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f); - *ptr2++ = val; + if (lcd_depth == 16) { + if (bpp == 24) { + for (x=0; x<width; x++) { + /* + * Generate epson 16bpp fb-format from 24bpp image + */ + b = *bmp++ >> 3; + g = *bmp++ >> 2; + r = *bmp++ >> 3; + val = ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f); + *ptr2++ = val; + } + } else if (bpp == 8) { + for (x=0; x<line_size; x++) { + /* query rgb value from palette */ + ptr = (unsigned char *)(dst + 14 + 40) ; + ptr += (*bmp++) << 2; + b = *ptr++ >> 3; + g = *ptr++ >> 2; + r = *ptr++ >> 3; + val = ((r & 0x1f) << 11) | ((g & 0x3f) << 5) | (b & 0x1f); + *ptr2++ = val; + } } } else { for (x=0; x<line_size; x++) { @@ -226,5 +205,122 @@ void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, } } - free(dst); + if (do_free) { + free(dst); + } +} + + +void lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, + uchar *logo_bmp, ulong len) +{ + int i; + ushort s1dReg; + uchar s1dValue; + int reg_byte_swap; + + /* + * Detect epson + */ + if (lcd_reg[0] == 0x1c) { + /* + * Big epson detected + */ + reg_byte_swap = FALSE; + palette_index = 0x1e2; + palette_value = 0x1e4; + lcd_depth = 16; + puts("LCD: S1D13806"); + } else if (lcd_reg[1] == 0x1c) { + /* + * Big epson detected (with register swap bug) + */ + reg_byte_swap = TRUE; + palette_index = 0x1e3; + palette_value = 0x1e5; + lcd_depth = 16; + puts("LCD: S1D13806S"); + } else if (lcd_reg[0] == 0x18) { + /* + * Small epson detected (704) + */ + reg_byte_swap = FALSE; + palette_index = 0x15; + palette_value = 0x17; + lcd_depth = 8; + puts("LCD: S1D13704"); + } else if (lcd_reg[0x10000] == 0x24) { + /* + * Small epson detected (705) + */ + reg_byte_swap = FALSE; + palette_index = 0x15; + palette_value = 0x17; + lcd_depth = 8; + lcd_reg += 0x10000; /* add offset for 705 regs */ + puts("LCD: S1D13705"); + } else { + puts("LCD: No controller detected!\n"); + return; + } + + /* + * Setup lcd controller regs + */ + for (i = 0; i<reg_count; i++) { + s1dReg = regs[i].Index; + if (reg_byte_swap) { + if ((s1dReg & 0x0001) == 0) + s1dReg |= 0x0001; + else + s1dReg &= ~0x0001; + } + s1dValue = regs[i].Value; + lcd_reg[s1dReg] = s1dValue; + } + + /* + * Save reg & mem pointer for later usage (e.g. bmp command) + */ + glob_lcd_reg = lcd_reg; + glob_lcd_mem = lcd_mem; + + /* + * Display bmp image + */ + lcd_bmp(logo_bmp); } + + +int do_esdbmp(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + ulong addr; + char *str; + + if (argc != 2) { + printf ("Usage:\n%s\n", cmdtp->usage); + return 1; + } + + addr = simple_strtoul(argv[1], NULL, 16); + + str = getenv("bd_type"); + if ((strcmp(str, "ppc221") == 0) || (strcmp(str, "ppc231") == 0)) { + /* + * SM501 available, use standard bmp command + */ + return (video_display_bitmap(addr, 0, 0)); + } else { + /* + * No SM501 available, use esd epson bmp command + */ + lcd_bmp((uchar *)addr); + return 0; + } +} + +U_BOOT_CMD( + esdbmp, 2, 1, do_esdbmp, + "esdbmp - display BMP image\n", + "<imageAddr> - display image\n" +); |