diff options
Diffstat (limited to 'board/esd/common/lcd.c')
| -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 d2d642a1a..22b49ce25 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" +); |