#include <stdarg.h>
#include <linux/types.h>
#include <stdio_dev.h>
+#include <malloc.h>
#if defined(CONFIG_POST)
#include <post.h>
#endif
/************************************************************************/
#ifdef CONFIG_LCD_LOGO
# include <bmp_logo.h> /* Get logo data, width and height */
-# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
+# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
# error Default Color Map overlaps with Logo Color Map
# endif
#endif
static int lcd_init (void *lcdbase);
static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
-extern void lcd_ctrl_init (void *lcdbase);
-extern void lcd_enable (void);
static void *lcd_logo (void);
-
-#if (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
-extern void lcd_setcolreg (ushort regno,
- ushort red, ushort green, ushort blue);
-#endif
-#if LCD_BPP == LCD_MONOCHROME
-extern void lcd_initcolregs (void);
-#endif
-
static int lcd_getbgcolor (void);
static void lcd_setfgcolor (int color);
static void lcd_setbgcolor (int color);
char lcd_is_enabled = 0;
-extern vidinfo_t panel_info;
#ifdef NOT_USED_SO_FAR
static void lcd_getcolreg (ushort regno,
static void console_scrollup (void)
{
-#if 1
/* Copy up rows ignoring the first one */
memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
/* Clear the last one */
memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
-#else
- /*
- * Poor attempt to optimize speed by moving "long"s.
- * But the code is ugly, and not a bit faster :-(
- */
- ulong *t = (ulong *)CONSOLE_ROW_FIRST;
- ulong *s = (ulong *)CONSOLE_ROW_SECOND;
- ulong l = CONSOLE_SCROLL_SIZE / sizeof(ulong);
- uchar c = lcd_color_bg & 0xFF;
- ulong val= (c<<24) | (c<<16) | (c<<8) | c;
-
- while (l--)
- *t++ = *s++;
-
- t = (ulong *)CONSOLE_ROW_LAST;
- l = CONSOLE_ROW_SIZE / sizeof(ulong);
-
- while (l-- > 0)
- *t++ = val;
-#endif
}
/*----------------------------------------------------------------------*/
for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
uchar *s = str;
- uchar *d = dest;
int i;
+#if LCD_BPP == LCD_COLOR16
+ ushort *d = (ushort *)dest;
+#else
+ uchar *d = dest;
+#endif
#if LCD_BPP == LCD_MONOCHROME
uchar rest = *d & -(1 << (8-off));
bits <<= 1;
}
#elif LCD_BPP == LCD_COLOR16
- for (c=0; c<16; ++c) {
+ for (c=0; c<8; ++c) {
*d++ = (bits & 0x80) ?
lcd_color_fg : lcd_color_bg;
bits <<= 1;
/************************************************************************/
/* ** GENERIC Initialization Routines */
/************************************************************************/
+int drv_lcd_init_resume (void)
+{
+ lcd_base = (void *)(gd->fb_base);
+
+ lcd_line_length = (panel_info.vl_col * (panel_info.vl_bpix)) / 8;
+
+ lcd_init (lcd_base); /* LCD initialization */
+
+ return 0;
+}
int drv_lcd_init (void)
{
lcd_base = (void *)(gd->fb_base);
- lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
+ lcd_line_length = (panel_info.vl_col * (panel_info.vl_bpix / 8));
lcd_init (lcd_base); /* LCD initialization */
ulong lcd_setmem (ulong addr)
{
ulong size;
- int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
+ int line_length = (panel_info.vl_col * (panel_info.vl_bpix)) / 8;
debug ("LCD panel info: %d x %d, %d bit/pix\n",
- panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
+ panel_info.vl_col, panel_info.vl_row, (panel_info.vl_bpix) );
size = line_length * panel_info.vl_row;
static void lcd_setfgcolor (int color)
{
-#ifdef CONFIG_ATMEL_LCD
lcd_color_fg = color;
-#else
- lcd_color_fg = color & 0x0F;
-#endif
}
/*----------------------------------------------------------------------*/
static void lcd_setbgcolor (int color)
{
-#ifdef CONFIG_ATMEL_LCD
lcd_color_bg = color;
-#else
- lcd_color_bg = color & 0x0F;
-#endif
}
/*----------------------------------------------------------------------*/
bmap = &bmp_logo_bitmap[0];
fb = (uchar *)(lcd_base + y * lcd_line_length + x);
- if (NBITS(panel_info.vl_bpix) < 12) {
+ if ((panel_info.vl_bpix) < 12) {
/* Leave room for default color map */
#if defined(CONFIG_PXA250)
cmap = (ushort *)fbi->palette;
cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
#elif defined(CONFIG_ATMEL_LCD)
cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
+#else
+ /*
+ * default case: generic system with no cmap (most likely 16bpp)
+ * We set cmap to the source palette, so no change is done.
+ * This avoids even more ifdef in the next stanza
+ */
+ cmap = bmp_logo_palette;
#endif
WATCHDOG_RESET();
}
}
else { /* true color mode */
+ u16 col16;
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])];
+ col16 = bmp_logo_palette[(bmap[j]-16)];
+ fb16[j] =
+ ((col16 & 0x000F) << 1) |
+ ((col16 & 0x00F0) << 3) |
+ ((col16 & 0x0F00) << 4);
}
bmap += BMP_LOGO_WIDTH;
fb16 += panel_info.vl_col;
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
#define BMP_ALIGN_CENTER 0x7FFF
#endif
+void lcd_display_clear(void)
+{
+ unsigned int *fb = lcd_base;
+ printf("Clean the display\n");
+
+ memset(fb, 0, panel_info.vl_row * panel_info.vl_col * panel_info.vl_bpix / 8);
+}
int lcd_display_bitmap(ulong bmp_image, int x, int y)
{
colors = 1 << bmp_bpix;
compression = le32_to_cpu (bmp->header.compression);
- bpix = NBITS(panel_info.vl_bpix);
+ bpix = (panel_info.vl_bpix);
- if ((bpix != 1) && (bpix != 8) && (bpix != 16)) {
- printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
+ if ((bpix != 1) && (bpix != 8) && (bpix != 16) && (bpix != 32)) {
+ printf ("Error0: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix, bmp_bpix);
return 1;
}
- /* We support displaying 8bpp BMPs on 16bpp LCDs */
- if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {
- printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
+ /* We support displaying 8bpp BMPs on 16bpp LCDs and 4bpp BMPs on 32bpp LCDs */
+ if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16) && !(bpix == 32 && bmp_bpix == 4) ) {
+ printf ("Error1: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix,
le16_to_cpu(bmp->header.bit_count));
return 1;
#elif defined(CONFIG_MPC823)
cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
#elif !defined(CONFIG_ATMEL_LCD)
- cmap = panel_info.cmap;
+ /* cmap = panel_info.cmap; */
+ cmap = (ushort *) malloc(1024);
#endif
cmap_base = cmap;
(y + height - 1) * lcd_line_length + x);
switch (bmp_bpix) {
+ case 4: /* Display 4b bmp at 32b lcd */
+ if (bpix == 32) {
+ /* 1. Get the color map */
+ unsigned int cmap_32[16];
+ unsigned int effective_width;
+
+ for (i=0; i<colors; ++i) {
+ bmp_color_table_entry_t cte = bmp->color_table[i];
+ cmap_32[i] = (cte.red << 0) | (cte.green << 8) |
+ (cte.blue << 16) | (cte.reserved << 24);
+ }
+
+ /* 2. Put'em on the screen */
+ lcd_line_length = (panel_info.vl_col * (panel_info.vl_bpix / 8));
+ fb = (uchar *) lcd_base;
+ fb += lcd_line_length * (y + height) + x * 4;
+
+ printf("Drawing the 32bit bmp.. @ 4b (%d,%d) of [%ldx%ld] in %d (%d color)\n",
+ x, y, width, height, lcd_line_length, colors);
+ effective_width = (width % 2) ? (width + 1) : width;
+ for (i = 0; i < height; ++i) {
+ WATCHDOG_RESET();
+ for (j = 0; j < width; j++) {
+ int color_v;
+ color_v = bmap[(j + i * effective_width) / 2];
+ if ((j + i * effective_width) % 2)
+ color_v = color_v & 0xf;
+ else
+ color_v = (color_v >> 4) & 0xf;
+
+ memcpy(fb, cmap_32 + color_v, 4);
+ fb += 4;
+ }
+ fb -= (lcd_line_length + width * 4);
+ }
+ }
+ break;
case 1: /* pass through */
case 8:
if (bpix != 16)
}
break;
#endif /* CONFIG_BMP_16BPP */
+ case 32:
+ lcd_line_length = (panel_info.vl_col * (panel_info.vl_bpix / 8));
+ fb = (uchar *) lcd_base;
+ fb += lcd_line_length * (y + height) + x * 4;
+
+ printf("Drawing the 32bit bmp.. @ (%d,%d) of [%ldx%ld] in %d\n",
+ x, y, width, height, lcd_line_length);
+ for (i = 0; i < height; ++i) {
+ WATCHDOG_RESET();
+ for (j = 0; j < width; j++) {
+ *(fb++) = *(bmap++);
+ *(fb++) = *(bmap++);
+ *(fb++) = *(bmap++);
+ *(fb++) = *(bmap++);
+ }
+ //bmap += (padded_line - width) * 4;
+ fb -= (lcd_line_length + width * 4);
+ }
+ break;
default:
break;
}
#endif
-#ifdef CONFIG_VIDEO_BMP_GZIP
-extern bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp);
-#endif
-
static void *lcd_logo (void)
{
#ifdef CONFIG_SPLASH_SCREEN
char *s;
ulong addr;
+ int allocated = 0;
static int do_splash = 1;
if (do_splash && (s = getenv("splashimage")) != NULL) {
if (!((bmp->header.signature[0]=='B') &&
(bmp->header.signature[1]=='M'))) {
addr = (ulong)gunzip_bmp(addr, &len);
+ if (addr)
+ allocated = 1;
}
#endif
if (lcd_display_bitmap (addr, x, y) == 0) {
+#ifdef CONFIG_VIDEO_BMP_GZIP
+ if (addr && allocated)
+ free((void *)addr);
+#endif
return ((void *)lcd_base);
}
+#ifdef CONFIG_VIDEO_BMP_GZIP
+ if (addr && allocated)
+ free((void *)addr);
+#endif
}
#endif /* CONFIG_SPLASH_SCREEN */