Commit 98f4a3df authored by Stefan Roese's avatar Stefan Roese

Add SM501 support to HH405 board.

Add support for gzip compressed bmp's (CONFIG_VIDEO_BMP_GZIP).
Add support for eeprom write-enable (CFG_EEPROM_WREN).
Patch by Stefan Roese, 22 Sep 2005
parent 5810dc3a
......@@ -2,6 +2,11 @@
Changes for U-Boot 1.1.4:
======================================================================
* Add SM501 support to HH405 board.
Add support for gzip compressed bmp's (CONFIG_VIDEO_BMP_GZIP).
Add support for eeprom write-enable (CFG_EEPROM_WREN).
Patch by Stefan Roese, 22 Sep 2005
* Update configuration for INKA4x0 board
* Update configuration for PM854 board
......
......@@ -960,6 +960,12 @@ The following options need to be configured:
allows for a "silent" boot where a splash screen is
loaded very quickly after power-on.
- Gzip compressed BMP image support: CONFIG_VIDEO_BMP_GZIP
If this option is set, additionally to standard BMP
images, gzipped BMP images can be displayed via the
splashscreen support or the bmp command.
- Compression support:
CONFIG_BZIP2
......
......@@ -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"
);
This diff is collapsed.
This diff is collapsed.
......@@ -49,6 +49,9 @@ extern int eeprom_read (unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt);
extern int eeprom_write (unsigned dev_addr, unsigned offset,
uchar *buffer, unsigned cnt);
#if defined(CFG_EEPROM_WREN)
extern int eeprom_write_enable (unsigned dev_addr, int state);
#endif
#endif
......@@ -214,6 +217,9 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
int i;
#endif
#if defined(CFG_EEPROM_WREN)
eeprom_write_enable (dev_addr,1);
#endif
/* Write data until done or would cross a write page boundary.
* We must write the address again when changing pages
* because the address counter only increments within a page.
......@@ -367,6 +373,9 @@ int eeprom_write (unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cn
udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
#endif
}
#if defined(CFG_EEPROM_WREN)
eeprom_write_enable (dev_addr,0);
#endif
return rcode;
}
......
......@@ -130,6 +130,16 @@ CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the
#define VIDEO_HW_BITBLT
#endif
/*****************************************************************************/
/* Defines for the SED13806 driver */
/*****************************************************************************/
#ifdef CONFIG_VIDEO_SM501
#ifdef CONFIG_HH405
#define VIDEO_FB_LITTLE_ENDIAN
#endif
#endif
/*****************************************************************************/
/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */
/*****************************************************************************/
......@@ -372,6 +382,8 @@ static const int video_font_draw_table32[16][4] = {
{ 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
int gunzip(void *, int, unsigned char *, unsigned long *);
/******************************************************************************/
static void video_drawchars (int xx, int yy, unsigned char *s, int count)
......@@ -751,13 +763,42 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
unsigned colors;
unsigned long compression;
bmp_color_table_entry_t cte;
#ifdef CONFIG_VIDEO_BMP_GZIP
unsigned char *dst = NULL;
ulong len;
#endif
WATCHDOG_RESET ();
if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
#ifdef CONFIG_VIDEO_BMP_GZIP
/*
* Could be a gzipped bmp image, try to decrompress...
*/
len = CFG_VIDEO_LOGO_MAX_SIZE;
dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE);
if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
free(dst);
return 1;
}
/*
* Set addr to decompressed image
*/
bmp = (bmp_image_t *)dst;
if (!((bmp->header.signature[0] == 'B') &&
(bmp->header.signature[1] == 'M'))) {
printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
return 1;
}
#else
printf ("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
#endif /* CONFIG_VIDEO_BMP_GZIP */
}
width = le32_to_cpu (bmp->header.width);
......@@ -947,6 +988,13 @@ int video_display_bitmap (ulong bmp_image, int x, int y)
le16_to_cpu (bmp->header.bit_count));
break;
}
#ifdef CONFIG_VIDEO_BMP_GZIP
if (dst) {
free(dst);
}
#endif
return (0);
}
#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */
......@@ -1061,7 +1109,6 @@ static void *video_logo (void)
}
#endif /* CONFIG_SPLASH_SCREEN */
logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
sprintf (info, " %s", &version_string);
......
......@@ -2,6 +2,9 @@
* (C) Copyright 2001-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.
*
......@@ -60,17 +63,47 @@
#define CONFIG_PHY_CLK_FREQ EMAC_STACR_CLK_66MHZ /* 66 MHz OPB clock*/
/*
* Video console
*/
#define CONFIG_VIDEO
#define CONFIG_VIDEO_SM501
#if 0
#define CONFIG_VIDEO_SM501_32BPP
#else
#define CONFIG_VIDEO_SM501_16BPP
#endif
#define CONFIG_CFB_CONSOLE
#define CONFIG_VIDEO_LOGO
#define CONFIG_VGA_AS_SINGLE_DEVICE
#define CONFIG_CONSOLE_EXTRA_INFO
#define CONFIG_VIDEO_SW_CURSOR
#define CONFIG_SPLASH_SCREEN
#define CFG_CONSOLE_IS_IN_ENV
#define CONFIG_SPLASH_SCREEN
#define CONFIG_VIDEO_BMP_GZIP /* gzip compressed bmp images */
#define CFG_VIDEO_LOGO_MAX_SIZE (1024*1024) /* for decompressed img */
#ifdef CONFIG_VIDEO
#define ADD_BMP_CMD CFG_CMD_BMP
#else
#define ADD_BMP_CMD 0
#endif
#define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \
CFG_CMD_DHCP | \
CFG_CMD_PCI | \
CFG_CMD_IRQ | \
CFG_CMD_IDE | \
CFG_CMD_FAT | \
CFG_CMD_EXT2 | \
CFG_CMD_ELF | \
CFG_CMD_NAND | \
CFG_CMD_I2C | \
CFG_CMD_DATE | \
CFG_CMD_MII | \
CFG_CMD_PING | \
ADD_BMP_CMD | \
CFG_CMD_EEPROM )
#define CONFIG_MAC_PARTITION
......@@ -111,7 +144,7 @@
#define CFG_DEVICE_NULLDEV 1 /* include nulldev device */
#define CFG_CONSOLE_INFO_QUIET 1 /* don't print console @ startup*/
#undef CFG_CONSOLE_INFO_QUIET /* print console @ startup */
#define CONFIG_AUTO_COMPLETE 1 /* add autocompletion support */
......@@ -139,6 +172,13 @@
#define CFG_RX_ETH_BUFFER 16 /* use 16 rx buffer on 405 emac */
/*-----------------------------------------------------------------------
* RTC stuff
*-----------------------------------------------------------------------
*/
#define CONFIG_RTC_DS1338
#define CFG_I2C_RTC_ADDR 0x68
/*-----------------------------------------------------------------------
* NAND-FLASH stuff
*-----------------------------------------------------------------------
......@@ -294,6 +334,8 @@
#define CFG_I2C_SLAVE 0x7F
#define CFG_I2C_EEPROM_ADDR 0x50 /* EEPROM CAT24WC08 */
#define CFG_EEPROM_WREN 1
#if 1 /* test-only */
/* CAT24WC08/16... */
#define CFG_I2C_EEPROM_ADDR_LEN 1 /* Bytes of address */
......@@ -449,7 +491,8 @@
#define CFG_GPIO0_TCR 0xF7FE0017
#define CFG_LCD_ENDIAN (0x80000000 >> 7)
#define CFG_TOUCH_RST (0x80000000 >> 9)
#define CFG_EEPROM_WP (0x80000000 >> 8) /* GPIO8 */
#define CFG_TOUCH_RST (0x80000000 >> 9) /* GPIO9 */
#define CFG_LCD0_RST (0x80000000 >> 30)
#define CFG_LCD1_RST (0x80000000 >> 31)
......
......@@ -32,6 +32,9 @@
#ifndef _SM501_H_
#define _SM501_H_
#define PCI_VENDOR_SM 0x126f
#define PCI_DEVICE_SM501 0x0501
typedef struct {
unsigned int Index;
unsigned int Value;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment