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;
}