#ifdef CONFIG_LCD_LOGO
# include <bmp_logo.h> /* Get logo data, width and height */
# include <bmp_logo_data.h>
-# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
+# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP < LCD_COLOR16)
# error Default Color Map overlaps with Logo Color Map
# endif
#endif
CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
};
+#if LCD_BPP == LCD_COLOR8
+typedef uchar pix_t;
+#elif LCD_BPP == LCD_COLOR16
+typedef ushort pix_t;
+#elif LCD_BPP == LCD_COLOR32
+typedef ulong pix_t;
+#else
+#error Unsupported pixelformat
+#endif
+
static void test_pattern(void)
{
ushort v_max = panel_info.vl_row;
ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR;
ushort v, h;
- uchar *pix = (uchar *)lcd_base;
+ pix_t *pix = lcd_base;
printf("[LCD] Test Pattern: %d x %d [%d x %d]\n",
h_max, v_max, h_step, v_step);
#endif
#endif
/* Paint the logo and retrieve LCD base address */
- debug("[LCD] Drawing the logo...\n");
+ debug("[LCD] Drawing the logo @ %p...\n", lcd_base);
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT);
console_rows /= VIDEO_FONT_HEIGHT;
static int lcd_init(void *lcdbase)
{
/* Initialize the lcd controller */
- debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
+ debug("[LCD] Initializing %ux%ux%u LCD framebuffer at %p\n",
+ panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix),
+ lcdbase);
lcd_ctrl_init(lcdbase);
struct pxafb_info *fbi = &panel_info.pxa;
return (ushort *)fbi->palette;
#elif defined(CONFIG_MPC823)
- immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
#elif defined(CONFIG_ATMEL_LCD)
uchar *fb;
ushort *fb16;
#if defined(CONFIG_MPC823)
- immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+ immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
cpm8xx_t *cp = &(immr->im_cpm);
#endif
unsigned bpix = NBITS(panel_info.vl_bpix);
bmap += BMP_LOGO_WIDTH;
fb += panel_info.vl_col;
}
- }
- else { /* true color mode */
+ } else if (NBITS(panel_info.vl_bpix) == 16) {
u16 col16;
fb16 = (ushort *)fb;
for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
bmap += BMP_LOGO_WIDTH;
fb16 += panel_info.vl_col;
}
+ } else { /* true color mode */
+ u16 col16;
+ u32 *fb32 = lcd_base + y * lcd_line_length + x;
+
+ for (i = 0; i < BMP_LOGO_HEIGHT; i++) {
+ for (j = 0; j < BMP_LOGO_WIDTH; j++) {
+ col16 = bmp_logo_palette[bmap[j] - 16];
+ fb32[j] =
+ ((col16 & 0x000F) << 4) |
+ ((col16 & 0x00F0) << 8) |
+ ((col16 & 0x0F00) << 12);
+ }
+ bmap += BMP_LOGO_WIDTH;
+ fb32 += panel_info.vl_col;
+ }
}
WATCHDOG_RESET();
#endif
#endif /* CONFIG_BMP_16BPP */
+static inline bmp_color_table_entry_t *get_color_table(bmp_image_t *bmp)
+{
+ bmp_header_t *bh = &bmp->header;
+ return (void *)bmp + offsetof(bmp_header_t, size) + bh->size;
+}
+
int lcd_display_bitmap(ulong bmp_image, int x, int y)
{
ushort *cmap = NULL;
bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
uchar *bmap;
ushort padded_width;
- unsigned long width, height, byte_width;
+ unsigned long width, height;
unsigned long pwidth = panel_info.vl_col;
- unsigned colors, bpix, bmp_bpix;
+ unsigned long long colors;
+ unsigned bpix, bmp_bpix;
+ bmp_color_table_entry_t *cte;
if (!bmp || !(bmp->header.signature[0] == 'B' &&
bmp->header.signature[1] == 'M')) {
return 1;
}
- debug("Display-bmp: %d x %d with %d colors\n",
- (int)width, (int)height, (int)colors);
+ debug("Display-bmp: %lu x %lu with %llu colors\n",
+ width, height, colors);
+ cte = get_color_table(bmp);
if (bmp_bpix == 8) {
cmap = configuration_get_cmap();
cmap_base = cmap;
/* Set color map */
for (i = 0; i < colors; ++i) {
- bmp_color_table_entry_t cte = bmp->color_table[i];
#if !defined(CONFIG_ATMEL_LCD)
ushort colreg =
- ( ((cte.red) << 8) & 0xf800) |
- ( ((cte.green) << 3) & 0x07e0) |
- ( ((cte.blue) >> 3) & 0x001f) ;
+ ( ((cte[i].red) << 8) & 0xf800) |
+ ( ((cte[i].green) << 3) & 0x07e0) |
+ ( ((cte[i].blue) >> 3) & 0x001f) ;
*cmap = colreg;
#if defined(CONFIG_MPC823)
cmap--;
cmap++;
#endif
#else /* CONFIG_ATMEL_LCD */
- lcd_setcolreg(i, cte.red, cte.green, cte.blue);
+ lcd_setcolreg(i, cte[i].red, cte[i].green, cte[i].blue);
#endif
}
}
- padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
+ padded_width = ALIGN(width, 4);
#ifdef CONFIG_SPLASH_SCREEN_ALIGN
splash_align_axis(&x, pwidth, width);
splash_align_axis(&y, panel_info.vl_row, height);
#endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+ bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
if ((x + width) > pwidth)
width = pwidth - x;
- if ((y + height) > panel_info.vl_row)
+ if ((y + height) > panel_info.vl_row) {
height = panel_info.vl_row - y;
+ bmap += (panel_info.vl_row - y) * padded_width;
+ }
- bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
fb = (uchar *)(lcd_base +
(y + height - 1) * lcd_line_length + x * bpix / 8);
}
#endif
- if (bpix != 16)
- byte_width = width;
- else
- byte_width = width * 2;
-
for (i = 0; i < height; ++i) {
WATCHDOG_RESET();
for (j = 0; j < width; j++) {
- if (bpix != 16) {
- FB_PUT_BYTE(fb, bmap);
- } else {
+ if (bpix == 32) {
+ int i = *bmap++;
+
+ fb[3] = 0; /* T */
+ fb[0] = cte[i].blue;
+ fb[1] = cte[i].green;
+ fb[2] = cte[i].red;
+ fb += sizeof(uint32_t) / sizeof(*fb);
+ } else if (bpix == 16) {
*(uint16_t *)fb = cmap_base[*(bmap++)];
fb += sizeof(uint16_t) / sizeof(*fb);
+ } else {
+ FB_PUT_BYTE(fb, bmap);
}
}
- bmap += (padded_width - width);
- fb -= byte_width + lcd_line_length;
+ if (bpix > 8) {
+ bmap += padded_width - width;
+ fb -= width * bpix / 8 + lcd_line_length;
+ } else {
+ bmap += padded_width;
+ fb -= lcd_line_length;
+ }
}
break;
}
fb -= lcd_line_length + width * (bpix / 8);
}
break;
-#endif /* CONFIG_BMP_24BMP */
+#endif /* CONFIG_BMP_24BPP */
#if defined(CONFIG_BMP_32BPP)
case 32:
for (i = 0; i < height; ++i) {
+ WATCHDOG_RESET();
for (j = 0; j < width; j++) {
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
- *(fb++) = *(bmap++);
+ fb[3] = *bmap++; /* T */
+ fb[0] = *bmap++; /* B */
+ fb[1] = *bmap++; /* G */
+ fb[2] = *bmap++; /* R */
+ fb += 4;
}
+ bmap += (padded_width - width) * 4;
fb -= lcd_line_length + width * (bpix / 8);
}
break;
#endif /* CONFIG_BMP_32BPP */
- default:
- break;
};
- lcd_sync();
return 0;
}
#endif
if (do_splash && (s = getenv("splashimage")) != NULL) {
int x = 0, y = 0;
+ char *end;
+
do_splash = 0;
if (splash_screen_prepare())
return (void *)lcd_base;
- addr = simple_strtoul (s, NULL, 16);
+ addr = simple_strtoul (s, &end, 16);
+ if (addr == 0 || *end != '\0')
+ return lcd_base;
splash_get_pos(&x, &y);
#endif /* CONFIG_LCD_INFO */
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
+ return lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
#else
- return (void *)lcd_base;
-#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
+ return lcd_base;
+#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
}
#ifdef CONFIG_SPLASHIMAGE_GUARD