]> git.ipfire.org Git - people/ms/u-boot.git/blob - common/lcd.c
83xx: Replace CONFIG_MPC83XX with CONFIG_MPC83xx
[people/ms/u-boot.git] / common / lcd.c
1 /*
2 * Common LCD routines for supported CPUs
3 *
4 * (C) Copyright 2001-2002
5 * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26 /************************************************************************/
27 /* ** HEADER FILES */
28 /************************************************************************/
29
30 /* #define DEBUG */
31
32 #include <config.h>
33 #include <common.h>
34 #include <command.h>
35 #include <stdarg.h>
36 #include <linux/types.h>
37 #include <devices.h>
38 #if defined(CONFIG_POST)
39 #include <post.h>
40 #endif
41 #include <lcd.h>
42 #include <watchdog.h>
43
44 #if defined(CONFIG_PXA250)
45 #include <asm/byteorder.h>
46 #endif
47
48 #if defined(CONFIG_MPC823)
49 #include <lcdvideo.h>
50 #endif
51
52 #if defined(CONFIG_ATMEL_LCD)
53 #include <atmel_lcdc.h>
54 #endif
55
56 /************************************************************************/
57 /* ** FONT DATA */
58 /************************************************************************/
59 #include <video_font.h> /* Get font data, width and height */
60
61 /************************************************************************/
62 /* ** LOGO DATA */
63 /************************************************************************/
64 #ifdef CONFIG_LCD_LOGO
65 # include <bmp_logo.h> /* Get logo data, width and height */
66 # if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
67 # error Default Color Map overlaps with Logo Color Map
68 # endif
69 #endif
70
71 DECLARE_GLOBAL_DATA_PTR;
72
73 ulong lcd_setmem (ulong addr);
74
75 static void lcd_drawchars (ushort x, ushort y, uchar *str, int count);
76 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s);
77 static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
78
79 static int lcd_init (void *lcdbase);
80
81 static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
82 extern void lcd_ctrl_init (void *lcdbase);
83 extern void lcd_enable (void);
84 static void *lcd_logo (void);
85
86
87 #if (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
88 extern void lcd_setcolreg (ushort regno,
89 ushort red, ushort green, ushort blue);
90 #endif
91 #if LCD_BPP == LCD_MONOCHROME
92 extern void lcd_initcolregs (void);
93 #endif
94
95 static int lcd_getbgcolor (void);
96 static void lcd_setfgcolor (int color);
97 static void lcd_setbgcolor (int color);
98
99 char lcd_is_enabled = 0;
100 extern vidinfo_t panel_info;
101
102 #ifdef NOT_USED_SO_FAR
103 static void lcd_getcolreg (ushort regno,
104 ushort *red, ushort *green, ushort *blue);
105 static int lcd_getfgcolor (void);
106 #endif /* NOT_USED_SO_FAR */
107
108 /************************************************************************/
109
110 /*----------------------------------------------------------------------*/
111
112 static void console_scrollup (void)
113 {
114 #if 1
115 /* Copy up rows ignoring the first one */
116 memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
117
118 /* Clear the last one */
119 memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
120 #else
121 /*
122 * Poor attempt to optimize speed by moving "long"s.
123 * But the code is ugly, and not a bit faster :-(
124 */
125 ulong *t = (ulong *)CONSOLE_ROW_FIRST;
126 ulong *s = (ulong *)CONSOLE_ROW_SECOND;
127 ulong l = CONSOLE_SCROLL_SIZE / sizeof(ulong);
128 uchar c = lcd_color_bg & 0xFF;
129 ulong val= (c<<24) | (c<<16) | (c<<8) | c;
130
131 while (l--)
132 *t++ = *s++;
133
134 t = (ulong *)CONSOLE_ROW_LAST;
135 l = CONSOLE_ROW_SIZE / sizeof(ulong);
136
137 while (l-- > 0)
138 *t++ = val;
139 #endif
140 }
141
142 /*----------------------------------------------------------------------*/
143
144 static inline void console_back (void)
145 {
146 if (--console_col < 0) {
147 console_col = CONSOLE_COLS-1 ;
148 if (--console_row < 0) {
149 console_row = 0;
150 }
151 }
152
153 lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
154 console_row * VIDEO_FONT_HEIGHT,
155 ' ');
156 }
157
158 /*----------------------------------------------------------------------*/
159
160 static inline void console_newline (void)
161 {
162 ++console_row;
163 console_col = 0;
164
165 /* Check if we need to scroll the terminal */
166 if (console_row >= CONSOLE_ROWS) {
167 /* Scroll everything up */
168 console_scrollup () ;
169 --console_row;
170 }
171 }
172
173 /*----------------------------------------------------------------------*/
174
175 void lcd_putc (const char c)
176 {
177 if (!lcd_is_enabled) {
178 serial_putc(c);
179 return;
180 }
181
182 switch (c) {
183 case '\r': console_col = 0;
184 return;
185
186 case '\n': console_newline();
187 return;
188
189 case '\t': /* Tab (8 chars alignment) */
190 console_col += 8;
191 console_col &= ~7;
192
193 if (console_col >= CONSOLE_COLS) {
194 console_newline();
195 }
196 return;
197
198 case '\b': console_back();
199 return;
200
201 default: lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
202 console_row * VIDEO_FONT_HEIGHT,
203 c);
204 if (++console_col >= CONSOLE_COLS) {
205 console_newline();
206 }
207 return;
208 }
209 /* NOTREACHED */
210 }
211
212 /*----------------------------------------------------------------------*/
213
214 void lcd_puts (const char *s)
215 {
216 if (!lcd_is_enabled) {
217 serial_puts (s);
218 return;
219 }
220
221 while (*s) {
222 lcd_putc (*s++);
223 }
224 }
225
226 /*----------------------------------------------------------------------*/
227
228 void lcd_printf(const char *fmt, ...)
229 {
230 va_list args;
231 char buf[CONFIG_SYS_PBSIZE];
232
233 va_start(args, fmt);
234 vsprintf(buf, fmt, args);
235 va_end(args);
236
237 lcd_puts(buf);
238 }
239
240 /************************************************************************/
241 /* ** Low-Level Graphics Routines */
242 /************************************************************************/
243
244 static void lcd_drawchars (ushort x, ushort y, uchar *str, int count)
245 {
246 uchar *dest;
247 ushort off, row;
248
249 dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
250 off = x * (1 << LCD_BPP) % 8;
251
252 for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
253 uchar *s = str;
254 uchar *d = dest;
255 int i;
256
257 #if LCD_BPP == LCD_MONOCHROME
258 uchar rest = *d & -(1 << (8-off));
259 uchar sym;
260 #endif
261 for (i=0; i<count; ++i) {
262 uchar c, bits;
263
264 c = *s++;
265 bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
266
267 #if LCD_BPP == LCD_MONOCHROME
268 sym = (COLOR_MASK(lcd_color_fg) & bits) |
269 (COLOR_MASK(lcd_color_bg) & ~bits);
270
271 *d++ = rest | (sym >> off);
272 rest = sym << (8-off);
273 #elif LCD_BPP == LCD_COLOR8
274 for (c=0; c<8; ++c) {
275 *d++ = (bits & 0x80) ?
276 lcd_color_fg : lcd_color_bg;
277 bits <<= 1;
278 }
279 #elif LCD_BPP == LCD_COLOR16
280 for (c=0; c<16; ++c) {
281 *d++ = (bits & 0x80) ?
282 lcd_color_fg : lcd_color_bg;
283 bits <<= 1;
284 }
285 #endif
286 }
287 #if LCD_BPP == LCD_MONOCHROME
288 *d = rest | (*d & ((1 << (8-off)) - 1));
289 #endif
290 }
291 }
292
293 /*----------------------------------------------------------------------*/
294
295 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s)
296 {
297 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
298 lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen ((char *)s));
299 #else
300 lcd_drawchars (x, y, s, strlen ((char *)s));
301 #endif
302 }
303
304 /*----------------------------------------------------------------------*/
305
306 static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
307 {
308 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
309 lcd_drawchars (x, y+BMP_LOGO_HEIGHT, &c, 1);
310 #else
311 lcd_drawchars (x, y, &c, 1);
312 #endif
313 }
314
315 /************************************************************************/
316 /** Small utility to check that you got the colours right */
317 /************************************************************************/
318 #ifdef LCD_TEST_PATTERN
319
320 #define N_BLK_VERT 2
321 #define N_BLK_HOR 3
322
323 static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
324 CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW,
325 CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
326 };
327
328 static void test_pattern (void)
329 {
330 ushort v_max = panel_info.vl_row;
331 ushort h_max = panel_info.vl_col;
332 ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
333 ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR;
334 ushort v, h;
335 uchar *pix = (uchar *)lcd_base;
336
337 printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
338 h_max, v_max, h_step, v_step);
339
340 /* WARNING: Code silently assumes 8bit/pixel */
341 for (v=0; v<v_max; ++v) {
342 uchar iy = v / v_step;
343 for (h=0; h<h_max; ++h) {
344 uchar ix = N_BLK_HOR * iy + (h/h_step);
345 *pix++ = test_colors[ix];
346 }
347 }
348 }
349 #endif /* LCD_TEST_PATTERN */
350
351
352 /************************************************************************/
353 /* ** GENERIC Initialization Routines */
354 /************************************************************************/
355
356 int drv_lcd_init (void)
357 {
358 device_t lcddev;
359 int rc;
360
361 lcd_base = (void *)(gd->fb_base);
362
363 lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
364
365 lcd_init (lcd_base); /* LCD initialization */
366
367 /* Device initialization */
368 memset (&lcddev, 0, sizeof (lcddev));
369
370 strcpy (lcddev.name, "lcd");
371 lcddev.ext = 0; /* No extensions */
372 lcddev.flags = DEV_FLAGS_OUTPUT; /* Output only */
373 lcddev.putc = lcd_putc; /* 'putc' function */
374 lcddev.puts = lcd_puts; /* 'puts' function */
375
376 rc = device_register (&lcddev);
377
378 return (rc == 0) ? 1 : rc;
379 }
380
381 /*----------------------------------------------------------------------*/
382 static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
383 {
384 #if LCD_BPP == LCD_MONOCHROME
385 /* Setting the palette */
386 lcd_initcolregs();
387
388 #elif LCD_BPP == LCD_COLOR8
389 /* Setting the palette */
390 lcd_setcolreg (CONSOLE_COLOR_BLACK, 0, 0, 0);
391 lcd_setcolreg (CONSOLE_COLOR_RED, 0xFF, 0, 0);
392 lcd_setcolreg (CONSOLE_COLOR_GREEN, 0, 0xFF, 0);
393 lcd_setcolreg (CONSOLE_COLOR_YELLOW, 0xFF, 0xFF, 0);
394 lcd_setcolreg (CONSOLE_COLOR_BLUE, 0, 0, 0xFF);
395 lcd_setcolreg (CONSOLE_COLOR_MAGENTA, 0xFF, 0, 0xFF);
396 lcd_setcolreg (CONSOLE_COLOR_CYAN, 0, 0xFF, 0xFF);
397 lcd_setcolreg (CONSOLE_COLOR_GREY, 0xAA, 0xAA, 0xAA);
398 lcd_setcolreg (CONSOLE_COLOR_WHITE, 0xFF, 0xFF, 0xFF);
399 #endif
400
401 #ifndef CONFIG_SYS_WHITE_ON_BLACK
402 lcd_setfgcolor (CONSOLE_COLOR_BLACK);
403 lcd_setbgcolor (CONSOLE_COLOR_WHITE);
404 #else
405 lcd_setfgcolor (CONSOLE_COLOR_WHITE);
406 lcd_setbgcolor (CONSOLE_COLOR_BLACK);
407 #endif /* CONFIG_SYS_WHITE_ON_BLACK */
408
409 #ifdef LCD_TEST_PATTERN
410 test_pattern();
411 #else
412 /* set framebuffer to background color */
413 memset ((char *)lcd_base,
414 COLOR_MASK(lcd_getbgcolor()),
415 lcd_line_length*panel_info.vl_row);
416 #endif
417 /* Paint the logo and retrieve LCD base address */
418 debug ("[LCD] Drawing the logo...\n");
419 lcd_console_address = lcd_logo ();
420
421 console_col = 0;
422 console_row = 0;
423
424 return (0);
425 }
426
427 U_BOOT_CMD(
428 cls, 1, 1, lcd_clear,
429 "clear screen",
430 ""
431 );
432
433 /*----------------------------------------------------------------------*/
434
435 static int lcd_init (void *lcdbase)
436 {
437 /* Initialize the lcd controller */
438 debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
439
440 lcd_ctrl_init (lcdbase);
441 lcd_is_enabled = 1;
442 lcd_clear (NULL, 1, 1, NULL); /* dummy args */
443 lcd_enable ();
444
445 /* Initialize the console */
446 console_col = 0;
447 #ifdef CONFIG_LCD_INFO_BELOW_LOGO
448 console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
449 #else
450 console_row = 1; /* leave 1 blank line below logo */
451 #endif
452
453 return 0;
454 }
455
456
457 /************************************************************************/
458 /* ** ROM capable initialization part - needed to reserve FB memory */
459 /************************************************************************/
460 /*
461 * This is called early in the system initialization to grab memory
462 * for the LCD controller.
463 * Returns new address for monitor, after reserving LCD buffer memory
464 *
465 * Note that this is running from ROM, so no write access to global data.
466 */
467 ulong lcd_setmem (ulong addr)
468 {
469 ulong size;
470 int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
471
472 debug ("LCD panel info: %d x %d, %d bit/pix\n",
473 panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
474
475 size = line_length * panel_info.vl_row;
476
477 /* Round up to nearest full page */
478 size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
479
480 /* Allocate pages for the frame buffer. */
481 addr -= size;
482
483 debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
484
485 return (addr);
486 }
487
488 /*----------------------------------------------------------------------*/
489
490 static void lcd_setfgcolor (int color)
491 {
492 #ifdef CONFIG_ATMEL_LCD
493 lcd_color_fg = color;
494 #else
495 lcd_color_fg = color & 0x0F;
496 #endif
497 }
498
499 /*----------------------------------------------------------------------*/
500
501 static void lcd_setbgcolor (int color)
502 {
503 #ifdef CONFIG_ATMEL_LCD
504 lcd_color_bg = color;
505 #else
506 lcd_color_bg = color & 0x0F;
507 #endif
508 }
509
510 /*----------------------------------------------------------------------*/
511
512 #ifdef NOT_USED_SO_FAR
513 static int lcd_getfgcolor (void)
514 {
515 return lcd_color_fg;
516 }
517 #endif /* NOT_USED_SO_FAR */
518
519 /*----------------------------------------------------------------------*/
520
521 static int lcd_getbgcolor (void)
522 {
523 return lcd_color_bg;
524 }
525
526 /*----------------------------------------------------------------------*/
527
528 /************************************************************************/
529 /* ** Chipset depending Bitmap / Logo stuff... */
530 /************************************************************************/
531 #ifdef CONFIG_LCD_LOGO
532 void bitmap_plot (int x, int y)
533 {
534 #ifdef CONFIG_ATMEL_LCD
535 uint *cmap;
536 #else
537 ushort *cmap;
538 #endif
539 ushort i, j;
540 uchar *bmap;
541 uchar *fb;
542 ushort *fb16;
543 #if defined(CONFIG_PXA250)
544 struct pxafb_info *fbi = &panel_info.pxa;
545 #elif defined(CONFIG_MPC823)
546 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
547 volatile cpm8xx_t *cp = &(immr->im_cpm);
548 #endif
549
550 debug ("Logo: width %d height %d colors %d cmap %d\n",
551 BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
552 (int)(sizeof(bmp_logo_palette)/(sizeof(ushort))));
553
554 bmap = &bmp_logo_bitmap[0];
555 fb = (uchar *)(lcd_base + y * lcd_line_length + x);
556
557 if (NBITS(panel_info.vl_bpix) < 12) {
558 /* Leave room for default color map */
559 #if defined(CONFIG_PXA250)
560 cmap = (ushort *)fbi->palette;
561 #elif defined(CONFIG_MPC823)
562 cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
563 #elif defined(CONFIG_ATMEL_LCD)
564 cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
565 #endif
566
567 WATCHDOG_RESET();
568
569 /* Set color map */
570 for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
571 ushort colreg = bmp_logo_palette[i];
572 #ifdef CONFIG_ATMEL_LCD
573 uint lut_entry;
574 #ifdef CONFIG_ATMEL_LCD_BGR555
575 lut_entry = ((colreg & 0x000F) << 11) |
576 ((colreg & 0x00F0) << 2) |
577 ((colreg & 0x0F00) >> 7);
578 #else /* CONFIG_ATMEL_LCD_RGB565 */
579 lut_entry = ((colreg & 0x000F) << 1) |
580 ((colreg & 0x00F0) << 3) |
581 ((colreg & 0x0F00) << 4);
582 #endif
583 *(cmap + BMP_LOGO_OFFSET) = lut_entry;
584 cmap++;
585 #else /* !CONFIG_ATMEL_LCD */
586 #ifdef CONFIG_SYS_INVERT_COLORS
587 *cmap++ = 0xffff - colreg;
588 #else
589 *cmap++ = colreg;
590 #endif
591 #endif /* CONFIG_ATMEL_LCD */
592 }
593
594 WATCHDOG_RESET();
595
596 for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
597 memcpy (fb, bmap, BMP_LOGO_WIDTH);
598 bmap += BMP_LOGO_WIDTH;
599 fb += panel_info.vl_col;
600 }
601 }
602 else { /* true color mode */
603 fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
604 for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
605 for (j=0; j<BMP_LOGO_WIDTH; j++) {
606 fb16[j] = bmp_logo_palette[(bmap[j])];
607 }
608 bmap += BMP_LOGO_WIDTH;
609 fb16 += panel_info.vl_col;
610 }
611 }
612
613 WATCHDOG_RESET();
614 }
615 #endif /* CONFIG_LCD_LOGO */
616
617 /*----------------------------------------------------------------------*/
618 #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
619 /*
620 * Display the BMP file located at address bmp_image.
621 * Only uncompressed.
622 */
623 int lcd_display_bitmap(ulong bmp_image, int x, int y)
624 {
625 #if !defined(CONFIG_MCC200)
626 ushort *cmap = NULL;
627 #endif
628 ushort *cmap_base = NULL;
629 ushort i, j;
630 uchar *fb;
631 bmp_image_t *bmp=(bmp_image_t *)bmp_image;
632 uchar *bmap;
633 ushort padded_line;
634 unsigned long width, height, byte_width;
635 unsigned long pwidth = panel_info.vl_col;
636 unsigned colors, bpix, bmp_bpix;
637 unsigned long compression;
638 #if defined(CONFIG_PXA250)
639 struct pxafb_info *fbi = &panel_info.pxa;
640 #elif defined(CONFIG_MPC823)
641 volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
642 volatile cpm8xx_t *cp = &(immr->im_cpm);
643 #endif
644
645 if (!((bmp->header.signature[0]=='B') &&
646 (bmp->header.signature[1]=='M'))) {
647 printf ("Error: no valid bmp image at %lx\n", bmp_image);
648 return 1;
649 }
650
651 width = le32_to_cpu (bmp->header.width);
652 height = le32_to_cpu (bmp->header.height);
653 bmp_bpix = le16_to_cpu(bmp->header.bit_count);
654 colors = 1 << bmp_bpix;
655 compression = le32_to_cpu (bmp->header.compression);
656
657 bpix = NBITS(panel_info.vl_bpix);
658
659 if ((bpix != 1) && (bpix != 8) && (bpix != 16)) {
660 printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
661 bpix, bmp_bpix);
662 return 1;
663 }
664
665 /* We support displaying 8bpp BMPs on 16bpp LCDs */
666 if (bpix != bmp_bpix && (bmp_bpix != 8 || bpix != 16)) {
667 printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
668 bpix,
669 le16_to_cpu(bmp->header.bit_count));
670 return 1;
671 }
672
673 debug ("Display-bmp: %d x %d with %d colors\n",
674 (int)width, (int)height, (int)colors);
675
676 #if !defined(CONFIG_MCC200)
677 /* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */
678 if (bmp_bpix == 8) {
679 #if defined(CONFIG_PXA250)
680 cmap = (ushort *)fbi->palette;
681 #elif defined(CONFIG_MPC823)
682 cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
683 #elif !defined(CONFIG_ATMEL_LCD)
684 cmap = panel_info.cmap;
685 #endif
686
687 cmap_base = cmap;
688
689 /* Set color map */
690 for (i=0; i<colors; ++i) {
691 bmp_color_table_entry_t cte = bmp->color_table[i];
692 #if !defined(CONFIG_ATMEL_LCD)
693 ushort colreg =
694 ( ((cte.red) << 8) & 0xf800) |
695 ( ((cte.green) << 3) & 0x07e0) |
696 ( ((cte.blue) >> 3) & 0x001f) ;
697 #ifdef CONFIG_SYS_INVERT_COLORS
698 *cmap = 0xffff - colreg;
699 #else
700 *cmap = colreg;
701 #endif
702 #if defined(CONFIG_MPC823)
703 cmap--;
704 #else
705 cmap++;
706 #endif
707 #else /* CONFIG_ATMEL_LCD */
708 lcd_setcolreg(i, cte.red, cte.green, cte.blue);
709 #endif
710 }
711 }
712 #endif
713
714 /*
715 * BMP format for Monochrome assumes that the state of a
716 * pixel is described on a per Bit basis, not per Byte.
717 * So, in case of Monochrome BMP we should align widths
718 * on a byte boundary and convert them from Bit to Byte
719 * units.
720 * Probably, PXA250 and MPC823 process 1bpp BMP images in
721 * their own ways, so make the converting to be MCC200
722 * specific.
723 */
724 #if defined(CONFIG_MCC200)
725 if (bpix==1)
726 {
727 width = ((width + 7) & ~7) >> 3;
728 x = ((x + 7) & ~7) >> 3;
729 pwidth= ((pwidth + 7) & ~7) >> 3;
730 }
731 #endif
732
733 padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);
734 if ((x + width)>pwidth)
735 width = pwidth - x;
736 if ((y + height)>panel_info.vl_row)
737 height = panel_info.vl_row - y;
738
739 bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);
740 fb = (uchar *) (lcd_base +
741 (y + height - 1) * lcd_line_length + x);
742
743 switch (bmp_bpix) {
744 case 1: /* pass through */
745 case 8:
746 if (bpix != 16)
747 byte_width = width;
748 else
749 byte_width = width * 2;
750
751 for (i = 0; i < height; ++i) {
752 WATCHDOG_RESET();
753 for (j = 0; j < width; j++) {
754 if (bpix != 16) {
755 #if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)
756 *(fb++) = *(bmap++);
757 #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
758 *(fb++) = 255 - *(bmap++);
759 #endif
760 } else {
761 *(uint16_t *)fb = cmap_base[*(bmap++)];
762 fb += sizeof(uint16_t) / sizeof(*fb);
763 }
764 }
765 bmap += (width - padded_line);
766 fb -= (byte_width + lcd_line_length);
767 }
768 break;
769
770 #if defined(CONFIG_BMP_16BPP)
771 case 16:
772 for (i = 0; i < height; ++i) {
773 WATCHDOG_RESET();
774 for (j = 0; j < width; j++) {
775 #if defined(CONFIG_ATMEL_LCD_BGR555)
776 *(fb++) = ((bmap[0] & 0x1f) << 2) |
777 (bmap[1] & 0x03);
778 *(fb++) = (bmap[0] & 0xe0) |
779 ((bmap[1] & 0x7c) >> 2);
780 bmap += 2;
781 #else
782 *(fb++) = *(bmap++);
783 *(fb++) = *(bmap++);
784 #endif
785 }
786 bmap += (padded_line - width) * 2;
787 fb -= (width * 2 + lcd_line_length);
788 }
789 break;
790 #endif /* CONFIG_BMP_16BPP */
791
792 default:
793 break;
794 };
795
796 return (0);
797 }
798 #endif
799
800 #ifdef CONFIG_VIDEO_BMP_GZIP
801 extern bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp);
802 #endif
803
804 static void *lcd_logo (void)
805 {
806 #ifdef CONFIG_SPLASH_SCREEN
807 char *s;
808 ulong addr;
809 static int do_splash = 1;
810
811 if (do_splash && (s = getenv("splashimage")) != NULL) {
812 addr = simple_strtoul(s, NULL, 16);
813 do_splash = 0;
814
815 #ifdef CONFIG_VIDEO_BMP_GZIP
816 bmp_image_t *bmp = (bmp_image_t *)addr;
817 unsigned long len;
818
819 if (!((bmp->header.signature[0]=='B') &&
820 (bmp->header.signature[1]=='M'))) {
821 addr = (ulong)gunzip_bmp(addr, &len);
822 }
823 #endif
824
825 if (lcd_display_bitmap (addr, 0, 0) == 0) {
826 return ((void *)lcd_base);
827 }
828 }
829 #endif /* CONFIG_SPLASH_SCREEN */
830
831 #ifdef CONFIG_LCD_LOGO
832 bitmap_plot (0, 0);
833 #endif /* CONFIG_LCD_LOGO */
834
835 #ifdef CONFIG_LCD_INFO
836 console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
837 console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
838 lcd_show_board_info();
839 #endif /* CONFIG_LCD_INFO */
840
841 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
842 return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
843 #else
844 return ((void *)lcd_base);
845 #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
846 }
847
848 /************************************************************************/
849 /************************************************************************/