
Hi,
I'm attaching patch against latest CVS for pxa FB driver which enables use of bootsplash feature in u-boot.
CHANGELOG: Patch by Hinko Kocevar, 05 Aug 2004: Add support for bmp command and bootsplash feature under pxa Add support for ATAG_VIDEOLFB usage when LCD is used
regards, himba
--- u-boot/lib_arm/armlinux.c~xcep-lcd 2004-08-04 22:40:27.000000000 +0200 +++ u-boot/lib_arm/armlinux.c 2004-08-04 23:10:20.000000000 +0200 @@ -55,7 +55,7 @@ # endif static void setup_end_tag (bd_t *bd);
-# if defined (CONFIG_VFD) +# if defined (CONFIG_VFD) || defined (CONFIG_LCD) static void setup_videolfb_tag (gd_t *gd); # endif
@@ -247,7 +247,7 @@ if (initrd_start && initrd_end) setup_initrd_tag (bd, initrd_start, initrd_end); #endif -#if defined (CONFIG_VFD) +#if defined (CONFIG_VFD) || defined (CONFIG_LCD) setup_videolfb_tag ((gd_t *) gd); #endif setup_end_tag (bd); @@ -351,7 +351,7 @@ #endif /* CONFIG_INITRD_TAG */
-#if defined (CONFIG_VFD) +#if defined (CONFIG_VFD) || defined (CONFIG_LCD) static void setup_videolfb_tag (gd_t *gd) { /* An ATAG_VIDEOLFB node tells the kernel where and how large @@ -365,8 +365,16 @@ params->hdr.size = tag_size (tag_videolfb);
params->u.videolfb.lfb_base = (u32) gd->fb_base; - /* 7168 = 256*4*56/8 - actually 2 pages (8192 bytes) are allocated */ - params->u.videolfb.lfb_size = 7168; + /* 80896 = (320*240) + PAGE_SIZE; for 8bpp and not page aligned + * UPDATE: lcd_setmem is not needed to get fb working, because + * we are not relocating the code properly. 80896b includes + * palette also - see pxafb_init_mem() for (al)location! + * layout of the mem block: + * FB + * DMA descriptors + * palette + */ + params->u.videolfb.lfb_size = 80896;
params = tag_next (params); } --- u-boot/common/cmd_bmp.c~xcep-lcd 2004-08-04 22:40:55.000000000 +0200 +++ u-boot/common/cmd_bmp.c 2004-08-04 23:35:37.000000000 +0200 @@ -28,6 +28,7 @@ #include <common.h> #include <bmp_layout.h> #include <command.h> +#include <linux/byteorder/little_endian.h>
#if (CONFIG_COMMANDS & CFG_CMD_BMP)
--- u-boot/cpu/pxa/pxafb.c~xcep-lcd 2004-08-04 22:40:27.000000000 +0200 +++ u-boot/cpu/pxa/pxafb.c 2004-08-04 23:34:49.000000000 +0200 @@ -34,6 +34,7 @@ #include <linux/types.h> #include <devices.h> #include <asm/arch/pxa-regs.h> +#include <linux/byteorder/little_endian.h>
#ifdef CONFIG_LCD
@@ -52,19 +53,26 @@
#undef CONFIG_LCD_LOGO
-#define LCD_TEST_PATTERN -/* #define LCD_TEST_PATTERN */ /* color backgnd for frame/color adjust */ +/* #define LCD_TEST_PATTERN*/ /* color backgnd for frame/color adjust */ /* #define CFG_INVERT_COLORS */ /* Not needed - adjust vl_dp instead */ /************************************************************************/
/************************************************************************/ +/* ** BITMAP DISPLAY SUPPORT -- should probably be moved elsewhere */ +/************************************************************************/ + +#if (CONFIG_COMMANDS & CFG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) +#include <bmp_layout.h> +#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */ + +/************************************************************************/ /* ** FONT AND LOGO DATA */ /************************************************************************/
#include <video_font.h> /* Get font data, width and height */
#ifdef CONFIG_LCD_LOGO -# include <bmp_nexus.h> /* Get logo data, width and height */ +# include <bmp_logo.h> /* Get logo data, width and height */ #endif
/************************************************************************/ @@ -153,7 +161,7 @@ #define LCD_COLOR16 4
/*----------------------------------------------------------------------*/ -#define CONFIG_PXA_VGA +/* #define CONFIG_PXA_VGA */ #ifdef CONFIG_PXA_VGA /* * LCD outputs connected to a video DAC @@ -225,8 +233,39 @@ }; #endif /* CONFIG_SHARP_LM8V31 */
-/*----------------------------------------------------------------------*/ +#ifdef CONFIG_HITACHI_SX14 +/* settings for Hitachi SX14Q004-ZZA color STN LCD */ + +#define LCD_BPP LCD_COLOR8
+/* you have to set lccr0 and lccr3 (including pcd) */ +#define REG_LCCR0 0x00301079 +#define REG_LCCR3 0x0340FF20 + +static vidinfo_t panel_info = { + vl_col: 320, + vl_row: 240, + vl_width: 320, /* UNUSED */ + vl_height: 240, /* UNUSED */ + vl_clkp: CFG_HIGH, /* UNUSED; clk polarity H->L */ + vl_oep: CFG_HIGH, /* UNUSED; ignored for STN */ + vl_hsp: CFG_HIGH, /* active high */ + vl_vsp: CFG_HIGH, /* active high */ + vl_dp: CFG_HIGH, /* UNUSED; data polarity, active high */ + vl_bpix: LCD_BPP, /* 8bitPERpixel */ + vl_lbw: 1, /* UNUSED; bus width is 8bit */ + vl_splt: 0, /* UNUSED; single scan display */ + vl_clor: 1, /* UNUSED; display is color */ + vl_lcdac: 0, /* UNUSED; AC timing 0xFF? */ + vl_tft: 0, /* UNUSED; passive display */ + vl_hpw: 1, /* HSW; hor sync pulse width */ + vl_blw: 1, /* BOL clk wait */ + vl_elw: 1, /* EOL clk wait */ + vl_vpw: 7, /* VSW; vert sync pulse width */ + vl_bfw: 0, /* BOF clk wait */ + vl_efw: 0, /* EOF clk wait */ +}; +#endif /* CONFIG_HITACHI_SX14 */ /*----------------------------------------------------------------------*/
#if defined(LCD_INFO_BELOW_LOGO) @@ -364,8 +403,8 @@ static void lcd_setfgcolor (int color); static void lcd_setbgcolor (int color);
-#ifdef NOT_USED_SO_FAR static int lcd_getbgcolor (void); +#ifdef NOT_USED_SO_FAR static void lcd_disable (void); static void lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue); @@ -604,7 +643,7 @@ lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
lcd_init (lcd_base); /* LCD initialization */ - + /* Device initialization */ memset (&lcddev, 0, sizeof (lcddev));
@@ -707,9 +746,12 @@ size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
/* Allocate pages for the frame buffer. */ - addr -= size; +/* according to WD we are not relocating code as needed, + * so this has no effect, at least display correct info now + */ + /* addr -= size;*/
- debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr); + debug ("Reserving 0x%08lx (%ldk) for LCD Framebuffer at: %08lx\n", size, size>>10, addr);
return (addr); } @@ -754,7 +796,7 @@ #ifdef LCD_INVERT_COLORS palette[regno] = ~val; #else - palette[regno] = ~val; + palette[regno] = val; #endif }
@@ -807,12 +849,12 @@
/*----------------------------------------------------------------------*/
-#ifdef NOT_USED_SO_FAR +/*#ifdef NOT_USED_SO_FAR*/ static int lcd_getbgcolor (void) { return lcd_color_bg; } -#endif /* NOT_USED_SO_FAR */ +/*#endif*/ /* NOT_USED_SO_FAR */
/*----------------------------------------------------------------------*/
@@ -837,9 +879,10 @@ static void bitmap_plot (int x, int y) { ushort *cmap; - ushort i; + ushort i, j; uchar *bmap; uchar *fb; + ushort *fb16; struct pxafb_info *fbi = &panel_info.pxa;
debug ("Logo: width %d height %d colors %d cmap %d\n", @@ -847,38 +890,152 @@ sizeof(bmp_logo_palette)/(sizeof(ushort)) );
- /* Leave room for default color map */ - cmap = (ushort *)fbi->palette; + bmap = &bmp_logo_bitmap[0]; + fb = (char *)(lcd_base + y * lcd_line_length + x);
- /* Set color map */ - for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) { - ushort colreg = bmp_logo_palette[i]; + if (NBITS(panel_info.vl_bpix) < 12) { + /* Leave room for default color map */ + cmap = (ushort *)fbi->palette; + + /* Set color map */ + for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) { + ushort colreg = bmp_logo_palette[i]; #ifdef CFG_INVERT_COLORS - colreg ^= 0xFFF; + *cmap++ = 0xffff - colreg; +#else + *cmap++ = colreg; #endif - *cmap++ = colreg; - } - - bmap = &bmp_logo_bitmap[0]; - fb = (char *)(lcd_base + y * lcd_line_length + x); + }
- for (i=0; i<BMP_LOGO_HEIGHT; ++i) { - memcpy (fb, bmap, BMP_LOGO_WIDTH); - bmap += BMP_LOGO_WIDTH; - fb += panel_info.vl_col; + for (i=0; i<BMP_LOGO_HEIGHT; ++i) { + memcpy (fb, bmap, BMP_LOGO_WIDTH); + bmap += BMP_LOGO_WIDTH; + fb += panel_info.vl_col; + } + } + else { /* true color mode */ + fb16 = (ushort *)(lcd_base + y * lcd_line_length + x); + for (i=0; i<BMP_LOGO_HEIGHT; ++i) { + for (j=0; j<BMP_LOGO_WIDTH; j++) { + fb16[j] = bmp_logo_palette[(bmap[j])]; + } + bmap += BMP_LOGO_WIDTH; + fb16 += panel_info.vl_col; + } } } #endif /* CONFIG_LCD_LOGO */
/*----------------------------------------------------------------------*/ +#if (CONFIG_COMMANDS & CFG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) +/* + * Display the BMP file located at address bmp_image. + * Only uncompressed, taken from cpu/mpc8xx/lcd.c. + */ +int lcd_display_bitmap(ulong bmp_image, int x, int y) +{ + ushort *cmap; + ushort i, j; + uchar *fb; + bmp_image_t *bmp=(bmp_image_t *)bmp_image; + uchar *bmap; + ushort padded_line; + unsigned long width, height; + unsigned colors,bpix; + unsigned long compression; + struct pxafb_info *fbi = &panel_info.pxa; + + + if (!((bmp->header.signature[0]=='B') && + (bmp->header.signature[1]=='M'))) { + printf ("Error: no valid bmp image at %lx\n", bmp_image); + return 1; + } + + width = le32_to_cpu (bmp->header.width); + height = le32_to_cpu (bmp->header.height); + colors = 1<<le16_to_cpu (bmp->header.bit_count); + compression = le32_to_cpu (bmp->header.compression); + + bpix = NBITS(panel_info.vl_bpix); + + if ((bpix != 1) && (bpix != 8)) { + printf ("Error: %d bit/pixel mode not supported by U-Boot\n", + bpix); + return 1; + } + + if (bpix != le16_to_cpu(bmp->header.bit_count)) { + printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", + bpix, + le16_to_cpu(bmp->header.bit_count)); + return 1; + } + + + debug ("Display-bmp: %d x %d with %d colors\n", + (int)width, (int)height, (int)colors); + + if (bpix==8) { + cmap = (ushort *)fbi->palette; + + /* Set color map */ + for (i=0; i<colors; ++i) { + bmp_color_table_entry_t cte = bmp->color_table[i]; + ushort colreg = + ( ((cte.red) << 8) & 0xf800) | + ( ((cte.green) << 4) & 0x07e0) | + ( (cte.blue) & 0x001f) ; + if (i < 10) + printf("%d - colreg value: %X\n", i, colreg); + +#ifdef CFG_INVERT_COLORS + *cmap++ = 0xffff - colreg; +#endif + *cmap++ = colreg; + } + + } + + padded_line = (width&0x3) ? ((width&~0x3)+4) : (width); + if ((x + width)>panel_info.vl_col) + width = panel_info.vl_col - x; + if ((y + height)>panel_info.vl_row) + height = panel_info.vl_row - y; + + bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset); + fb = (uchar *) (lcd_base + + (y + height - 1) * lcd_line_length + x); + for (i = 0; i < height; ++i) { + for (j = 0; j < width ; j++) + *(fb++)=*(bmap++); + bmap += (width - padded_line); + fb -= (width + lcd_line_length); + } + + return (0); +} +#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */ + +/*----------------------------------------------------------------------*/
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) { + addr = simple_strtoul(s, NULL, 16); + do_splash = 0; + + if (lcd_display_bitmap (addr, 0, 0) == 0) { + return ((void *)lcd_base); + } + } +#endif /* CONFIG_SPLASH_SCREEN */ #ifdef CONFIG_LCD_LOGO - DECLARE_GLOBAL_DATA_PTR; - char info[80]; - char temp[32]; - bitmap_plot (0, 0); #endif /* CONFIG_LCD_LOGO */
@@ -905,7 +1062,7 @@ palette_mem_size = fbi->palette_size * sizeof(u16); debug("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size); /* locate palette and descs at end of page following fb */ - fbi->palette = (u_long)lcdbase + fb_size + 2*PAGE_SIZE - palette_mem_size; + fbi->palette = (u_long)lcdbase + fb_size + PAGE_SIZE - palette_mem_size;
return 0; }