]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/lcd.c
Merge branch 'master' of git://git.denx.de/u-boot-blackfin
[karo-tx-uboot.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 <version.h>
36 #include <stdarg.h>
37 #include <linux/types.h>
38 #include <devices.h>
39 #if defined(CONFIG_POST)
40 #include <post.h>
41 #endif
42 #include <lcd.h>
43 #include <watchdog.h>
44
45 #if defined(CONFIG_PXA250)
46 #include <asm/byteorder.h>
47 #endif
48
49 #if defined(CONFIG_MPC823)
50 #include <lcdvideo.h>
51 #endif
52
53 #if defined(CONFIG_ATMEL_LCD)
54 #include <atmel_lcdc.h>
55 #endif
56
57 /************************************************************************/
58 /* ** FONT DATA                                                         */
59 /************************************************************************/
60 #include <video_font.h>         /* Get font data, width and height      */
61
62 /************************************************************************/
63 /* ** LOGO DATA                                                         */
64 /************************************************************************/
65 #ifdef CONFIG_LCD_LOGO
66 # include <bmp_logo.h>          /* Get logo data, width and height      */
67 # if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
68 #  error Default Color Map overlaps with Logo Color Map
69 # endif
70 #endif
71
72 DECLARE_GLOBAL_DATA_PTR;
73
74 ulong lcd_setmem (ulong addr);
75
76 static void lcd_drawchars (ushort x, ushort y, uchar *str, int count);
77 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s);
78 static inline void lcd_putc_xy (ushort x, ushort y, uchar  c);
79
80 static int lcd_init (void *lcdbase);
81
82 static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
83 extern void lcd_ctrl_init (void *lcdbase);
84 extern void lcd_enable (void);
85 static void *lcd_logo (void);
86
87
88 #if LCD_BPP == LCD_COLOR8
89 extern void lcd_setcolreg (ushort regno,
90                                 ushort red, ushort green, ushort blue);
91 #endif
92 #if LCD_BPP == LCD_MONOCHROME
93 extern void lcd_initcolregs (void);
94 #endif
95
96 static int lcd_getbgcolor (void);
97 static void lcd_setfgcolor (int color);
98 static void lcd_setbgcolor (int color);
99
100 char lcd_is_enabled = 0;
101 extern vidinfo_t panel_info;
102
103 #ifdef  NOT_USED_SO_FAR
104 static void lcd_getcolreg (ushort regno,
105                                 ushort *red, ushort *green, ushort *blue);
106 static int lcd_getfgcolor (void);
107 #endif  /* NOT_USED_SO_FAR */
108
109 /************************************************************************/
110
111 /*----------------------------------------------------------------------*/
112
113 static void console_scrollup (void)
114 {
115 #if 1
116         /* Copy up rows ignoring the first one */
117         memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
118
119         /* Clear the last one */
120         memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
121 #else
122         /*
123          * Poor attempt to optimize speed by moving "long"s.
124          * But the code is ugly, and not a bit faster :-(
125          */
126         ulong *t = (ulong *)CONSOLE_ROW_FIRST;
127         ulong *s = (ulong *)CONSOLE_ROW_SECOND;
128         ulong    l = CONSOLE_SCROLL_SIZE / sizeof(ulong);
129         uchar  c = lcd_color_bg & 0xFF;
130         ulong val= (c<<24) | (c<<16) | (c<<8) | c;
131
132         while (l--)
133                 *t++ = *s++;
134
135         t = (ulong *)CONSOLE_ROW_LAST;
136         l = CONSOLE_ROW_SIZE / sizeof(ulong);
137
138         while (l-- > 0)
139                 *t++ = val;
140 #endif
141 }
142
143 /*----------------------------------------------------------------------*/
144
145 static inline void console_back (void)
146 {
147         if (--console_col < 0) {
148                 console_col = CONSOLE_COLS-1 ;
149                 if (--console_row < 0) {
150                         console_row = 0;
151                 }
152         }
153
154         lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
155                      console_row * VIDEO_FONT_HEIGHT,
156                      ' ');
157 }
158
159 /*----------------------------------------------------------------------*/
160
161 static inline void console_newline (void)
162 {
163         ++console_row;
164         console_col = 0;
165
166         /* Check if we need to scroll the terminal */
167         if (console_row >= CONSOLE_ROWS) {
168                 /* Scroll everything up */
169                 console_scrollup () ;
170                 --console_row;
171         }
172 }
173
174 /*----------------------------------------------------------------------*/
175
176 void lcd_putc (const char c)
177 {
178         if (!lcd_is_enabled) {
179                 serial_putc(c);
180                 return;
181         }
182
183         switch (c) {
184         case '\r':      console_col = 0;
185                         return;
186
187         case '\n':      console_newline();
188                         return;
189
190         case '\t':      /* Tab (8 chars alignment) */
191                         console_col |=  8;
192                         console_col &= ~7;
193
194                         if (console_col >= CONSOLE_COLS) {
195                                 console_newline();
196                         }
197                         return;
198
199         case '\b':      console_back();
200                         return;
201
202         default:        lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
203                                      console_row * VIDEO_FONT_HEIGHT,
204                                      c);
205                         if (++console_col >= CONSOLE_COLS) {
206                                 console_newline();
207                         }
208                         return;
209         }
210         /* NOTREACHED */
211 }
212
213 /*----------------------------------------------------------------------*/
214
215 void lcd_puts (const char *s)
216 {
217         if (!lcd_is_enabled) {
218                 serial_puts (s);
219                 return;
220         }
221
222         while (*s) {
223                 lcd_putc (*s++);
224         }
225 }
226
227 /*----------------------------------------------------------------------*/
228
229 void lcd_printf(const char *fmt, ...)
230 {
231         va_list args;
232         char buf[CONFIG_SYS_PBSIZE];
233
234         va_start(args, fmt);
235         vsprintf(buf, fmt, args);
236         va_end(args);
237
238         lcd_puts(buf);
239 }
240
241 /************************************************************************/
242 /* ** Low-Level Graphics Routines                                       */
243 /************************************************************************/
244
245 static void lcd_drawchars (ushort x, ushort y, uchar *str, int count)
246 {
247         uchar *dest;
248         ushort off, row;
249
250         dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
251         off  = x * (1 << LCD_BPP) % 8;
252
253         for (row=0;  row < VIDEO_FONT_HEIGHT;  ++row, dest += lcd_line_length)  {
254                 uchar *s = str;
255                 uchar *d = dest;
256                 int i;
257
258 #if LCD_BPP == LCD_MONOCHROME
259                 uchar rest = *d & -(1 << (8-off));
260                 uchar sym;
261 #endif
262                 for (i=0; i<count; ++i) {
263                         uchar c, bits;
264
265                         c = *s++;
266                         bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
267
268 #if LCD_BPP == LCD_MONOCHROME
269                         sym  = (COLOR_MASK(lcd_color_fg) & bits) |
270                                (COLOR_MASK(lcd_color_bg) & ~bits);
271
272                         *d++ = rest | (sym >> off);
273                         rest = sym << (8-off);
274 #elif LCD_BPP == LCD_COLOR8
275                         for (c=0; c<8; ++c) {
276                                 *d++ = (bits & 0x80) ?
277                                                 lcd_color_fg : lcd_color_bg;
278                                 bits <<= 1;
279                         }
280 #elif LCD_BPP == LCD_COLOR16
281                         for (c=0; c<16; ++c) {
282                                 *d++ = (bits & 0x80) ?
283                                                 lcd_color_fg : lcd_color_bg;
284                                 bits <<= 1;
285                         }
286 #endif
287                 }
288 #if LCD_BPP == LCD_MONOCHROME
289                 *d  = rest | (*d & ((1 << (8-off)) - 1));
290 #endif
291         }
292 }
293
294 /*----------------------------------------------------------------------*/
295
296 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s)
297 {
298 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
299         lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen ((char *)s));
300 #else
301         lcd_drawchars (x, y, s, strlen ((char *)s));
302 #endif
303 }
304
305 /*----------------------------------------------------------------------*/
306
307 static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
308 {
309 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
310         lcd_drawchars (x, y+BMP_LOGO_HEIGHT, &c, 1);
311 #else
312         lcd_drawchars (x, y, &c, 1);
313 #endif
314 }
315
316 /************************************************************************/
317 /**  Small utility to check that you got the colours right              */
318 /************************************************************************/
319 #ifdef LCD_TEST_PATTERN
320
321 #define N_BLK_VERT      2
322 #define N_BLK_HOR       3
323
324 static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
325         CONSOLE_COLOR_RED,      CONSOLE_COLOR_GREEN,    CONSOLE_COLOR_YELLOW,
326         CONSOLE_COLOR_BLUE,     CONSOLE_COLOR_MAGENTA,  CONSOLE_COLOR_CYAN,
327 };
328
329 static void test_pattern (void)
330 {
331         ushort v_max  = panel_info.vl_row;
332         ushort h_max  = panel_info.vl_col;
333         ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
334         ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
335         ushort v, h;
336         uchar *pix = (uchar *)lcd_base;
337
338         printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
339                 h_max, v_max, h_step, v_step);
340
341         /* WARNING: Code silently assumes 8bit/pixel */
342         for (v=0; v<v_max; ++v) {
343                 uchar iy = v / v_step;
344                 for (h=0; h<h_max; ++h) {
345                         uchar ix = N_BLK_HOR * iy + (h/h_step);
346                         *pix++ = test_colors[ix];
347                 }
348         }
349 }
350 #endif /* LCD_TEST_PATTERN */
351
352
353 /************************************************************************/
354 /* ** GENERIC Initialization Routines                                   */
355 /************************************************************************/
356
357 int drv_lcd_init (void)
358 {
359         device_t lcddev;
360         int rc;
361
362         lcd_base = (void *)(gd->fb_base);
363
364         lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
365
366         lcd_init (lcd_base);            /* LCD initialization */
367
368         /* Device initialization */
369         memset (&lcddev, 0, sizeof (lcddev));
370
371         strcpy (lcddev.name, "lcd");
372         lcddev.ext   = 0;                       /* No extensions */
373         lcddev.flags = DEV_FLAGS_OUTPUT;        /* Output only */
374         lcddev.putc  = lcd_putc;                /* 'putc' function */
375         lcddev.puts  = lcd_puts;                /* 'puts' function */
376
377         rc = device_register (&lcddev);
378
379         return (rc == 0) ? 1 : rc;
380 }
381
382 /*----------------------------------------------------------------------*/
383 static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
384 {
385 #if LCD_BPP == LCD_MONOCHROME
386         /* Setting the palette */
387         lcd_initcolregs();
388
389 #elif LCD_BPP == LCD_COLOR8
390         /* Setting the palette */
391         lcd_setcolreg  (CONSOLE_COLOR_BLACK,       0,    0,    0);
392         lcd_setcolreg  (CONSOLE_COLOR_RED,      0xFF,    0,    0);
393         lcd_setcolreg  (CONSOLE_COLOR_GREEN,       0, 0xFF,    0);
394         lcd_setcolreg  (CONSOLE_COLOR_YELLOW,   0xFF, 0xFF,    0);
395         lcd_setcolreg  (CONSOLE_COLOR_BLUE,        0,    0, 0xFF);
396         lcd_setcolreg  (CONSOLE_COLOR_MAGENTA,  0xFF,    0, 0xFF);
397         lcd_setcolreg  (CONSOLE_COLOR_CYAN,        0, 0xFF, 0xFF);
398         lcd_setcolreg  (CONSOLE_COLOR_GREY,     0xAA, 0xAA, 0xAA);
399         lcd_setcolreg  (CONSOLE_COLOR_WHITE,    0xFF, 0xFF, 0xFF);
400 #endif
401
402 #ifndef CONFIG_SYS_WHITE_ON_BLACK
403         lcd_setfgcolor (CONSOLE_COLOR_BLACK);
404         lcd_setbgcolor (CONSOLE_COLOR_WHITE);
405 #else
406         lcd_setfgcolor (CONSOLE_COLOR_WHITE);
407         lcd_setbgcolor (CONSOLE_COLOR_BLACK);
408 #endif  /* CONFIG_SYS_WHITE_ON_BLACK */
409
410 #ifdef  LCD_TEST_PATTERN
411         test_pattern();
412 #else
413         /* set framebuffer to background color */
414         memset ((char *)lcd_base,
415                 COLOR_MASK(lcd_getbgcolor()),
416                 lcd_line_length*panel_info.vl_row);
417 #endif
418         /* Paint the logo and retrieve LCD base address */
419         debug ("[LCD] Drawing the logo...\n");
420         lcd_console_address = lcd_logo ();
421
422         console_col = 0;
423         console_row = 0;
424
425         return (0);
426 }
427
428 U_BOOT_CMD(
429         cls,    1,      1,      lcd_clear,
430         "cls     - clear screen\n",
431         NULL
432 );
433
434 /*----------------------------------------------------------------------*/
435
436 static int lcd_init (void *lcdbase)
437 {
438         /* Initialize the lcd controller */
439         debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
440
441         lcd_ctrl_init (lcdbase);
442         lcd_is_enabled = 1;
443         lcd_clear (NULL, 1, 1, NULL);   /* dummy args */
444         lcd_enable ();
445
446         /* Initialize the console */
447         console_col = 0;
448 #ifdef CONFIG_LCD_INFO_BELOW_LOGO
449         console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
450 #else
451         console_row = 1;        /* leave 1 blank line below logo */
452 #endif
453
454         return 0;
455 }
456
457
458 /************************************************************************/
459 /* ** ROM capable initialization part - needed to reserve FB memory     */
460 /************************************************************************/
461 /*
462  * This is called early in the system initialization to grab memory
463  * for the LCD controller.
464  * Returns new address for monitor, after reserving LCD buffer memory
465  *
466  * Note that this is running from ROM, so no write access to global data.
467  */
468 ulong lcd_setmem (ulong addr)
469 {
470         ulong size;
471         int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
472
473         debug ("LCD panel info: %d x %d, %d bit/pix\n",
474                 panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
475
476         size = line_length * panel_info.vl_row;
477
478         /* Round up to nearest full page */
479         size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
480
481         /* Allocate pages for the frame buffer. */
482         addr -= size;
483
484         debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
485
486         return (addr);
487 }
488
489 /*----------------------------------------------------------------------*/
490
491 static void lcd_setfgcolor (int color)
492 {
493 #ifdef CONFIG_ATMEL_LCD
494         lcd_color_fg = color;
495 #else
496         lcd_color_fg = color & 0x0F;
497 #endif
498 }
499
500 /*----------------------------------------------------------------------*/
501
502 static void lcd_setbgcolor (int color)
503 {
504 #ifdef CONFIG_ATMEL_LCD
505         lcd_color_bg = color;
506 #else
507         lcd_color_bg = color & 0x0F;
508 #endif
509 }
510
511 /*----------------------------------------------------------------------*/
512
513 #ifdef  NOT_USED_SO_FAR
514 static int lcd_getfgcolor (void)
515 {
516         return lcd_color_fg;
517 }
518 #endif  /* NOT_USED_SO_FAR */
519
520 /*----------------------------------------------------------------------*/
521
522 static int lcd_getbgcolor (void)
523 {
524         return lcd_color_bg;
525 }
526
527 /*----------------------------------------------------------------------*/
528
529 /************************************************************************/
530 /* ** Chipset depending Bitmap / Logo stuff...                          */
531 /************************************************************************/
532 #ifdef CONFIG_LCD_LOGO
533 void bitmap_plot (int x, int y)
534 {
535 #ifdef CONFIG_ATMEL_LCD
536         uint *cmap;
537 #else
538         ushort *cmap;
539 #endif
540         ushort i, j;
541         uchar *bmap;
542         uchar *fb;
543         ushort *fb16;
544 #if defined(CONFIG_PXA250)
545         struct pxafb_info *fbi = &panel_info.pxa;
546 #elif defined(CONFIG_MPC823)
547         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
548         volatile cpm8xx_t *cp = &(immr->im_cpm);
549 #endif
550
551         debug ("Logo: width %d  height %d  colors %d  cmap %d\n",
552                 BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
553                 (int)(sizeof(bmp_logo_palette)/(sizeof(ushort))));
554
555         bmap = &bmp_logo_bitmap[0];
556         fb   = (uchar *)(lcd_base + y * lcd_line_length + x);
557
558         if (NBITS(panel_info.vl_bpix) < 12) {
559                 /* Leave room for default color map */
560 #if defined(CONFIG_PXA250)
561                 cmap = (ushort *)fbi->palette;
562 #elif defined(CONFIG_MPC823)
563                 cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
564 #elif defined(CONFIG_ATMEL_LCD)
565                 cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
566 #endif
567
568                 WATCHDOG_RESET();
569
570                 /* Set color map */
571                 for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
572                         ushort colreg = bmp_logo_palette[i];
573 #ifdef CONFIG_ATMEL_LCD
574                         uint lut_entry;
575 #ifdef CONFIG_ATMEL_LCD_BGR555
576                         lut_entry = ((colreg & 0x000F) << 11) |
577                                     ((colreg & 0x00F0) <<  2) |
578                                     ((colreg & 0x0F00) >>  7);
579 #else /* CONFIG_ATMEL_LCD_RGB565 */
580                         lut_entry = ((colreg & 0x000F) << 1) |
581                                     ((colreg & 0x00F0) << 3) |
582                                     ((colreg & 0x0F00) << 4);
583 #endif
584                         *(cmap + BMP_LOGO_OFFSET) = lut_entry;
585                         cmap++;
586 #else /* !CONFIG_ATMEL_LCD */
587 #ifdef  CONFIG_SYS_INVERT_COLORS
588                         *cmap++ = 0xffff - colreg;
589 #else
590                         *cmap++ = colreg;
591 #endif
592 #endif /* CONFIG_ATMEL_LCD */
593                 }
594
595                 WATCHDOG_RESET();
596
597                 for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
598                         memcpy (fb, bmap, BMP_LOGO_WIDTH);
599                         bmap += BMP_LOGO_WIDTH;
600                         fb   += panel_info.vl_col;
601                 }
602         }
603         else { /* true color mode */
604                 fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
605                 for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
606                         for (j=0; j<BMP_LOGO_WIDTH; j++) {
607                                 fb16[j] = bmp_logo_palette[(bmap[j])];
608                                 }
609                         bmap += BMP_LOGO_WIDTH;
610                         fb16 += panel_info.vl_col;
611                 }
612         }
613
614         WATCHDOG_RESET();
615 }
616 #endif /* CONFIG_LCD_LOGO */
617
618 /*----------------------------------------------------------------------*/
619 #if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
620 /*
621  * Display the BMP file located at address bmp_image.
622  * Only uncompressed.
623  */
624 int lcd_display_bitmap(ulong bmp_image, int x, int y)
625 {
626 #ifdef CONFIG_ATMEL_LCD
627         uint *cmap;
628 #elif !defined(CONFIG_MCC200)
629         ushort *cmap;
630 #endif
631         ushort i, j;
632         uchar *fb;
633         bmp_image_t *bmp=(bmp_image_t *)bmp_image;
634         uchar *bmap;
635         ushort padded_line;
636         unsigned long width, height;
637         unsigned long pwidth = panel_info.vl_col;
638         unsigned colors,bpix;
639         unsigned long compression;
640 #if defined(CONFIG_PXA250)
641         struct pxafb_info *fbi = &panel_info.pxa;
642 #elif defined(CONFIG_MPC823)
643         volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
644         volatile cpm8xx_t *cp = &(immr->im_cpm);
645 #endif
646
647         if (!((bmp->header.signature[0]=='B') &&
648                 (bmp->header.signature[1]=='M'))) {
649                 printf ("Error: no valid bmp image at %lx\n", bmp_image);
650                 return 1;
651 }
652
653         width = le32_to_cpu (bmp->header.width);
654         height = le32_to_cpu (bmp->header.height);
655         colors = 1<<le16_to_cpu (bmp->header.bit_count);
656         compression = le32_to_cpu (bmp->header.compression);
657
658         bpix = NBITS(panel_info.vl_bpix);
659
660         if ((bpix != 1) && (bpix != 8)) {
661                 printf ("Error: %d bit/pixel mode not supported by U-Boot\n",
662                         bpix);
663                 return 1;
664         }
665
666         if (bpix != le16_to_cpu(bmp->header.bit_count)) {
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 (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 = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
685 #else
686 # error "Don't know location of color map"
687 #endif
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_PXA250)
703                         cmap++;
704 #elif defined(CONFIG_MPC823)
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         for (i = 0; i < height; ++i) {
743                 WATCHDOG_RESET();
744                 for (j = 0; j < width ; j++)
745 #if defined(CONFIG_PXA250) || defined(CONFIG_ATMEL_LCD)
746                         *(fb++) = *(bmap++);
747 #elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
748                         *(fb++)=255-*(bmap++);
749 #endif
750                 bmap += (width - padded_line);
751                 fb   -= (width + lcd_line_length);
752         }
753
754         return (0);
755 }
756 #endif
757
758 #ifdef CONFIG_VIDEO_BMP_GZIP
759 extern bmp_image_t *gunzip_bmp(unsigned long addr, unsigned long *lenp);
760 #endif
761
762 static void *lcd_logo (void)
763 {
764 #ifdef CONFIG_SPLASH_SCREEN
765         char *s;
766         ulong addr;
767         static int do_splash = 1;
768
769         if (do_splash && (s = getenv("splashimage")) != NULL) {
770                 addr = simple_strtoul(s, NULL, 16);
771                 do_splash = 0;
772
773 #ifdef CONFIG_VIDEO_BMP_GZIP
774                 bmp_image_t *bmp = (bmp_image_t *)addr;
775                 unsigned long len;
776
777                 if (!((bmp->header.signature[0]=='B') &&
778                       (bmp->header.signature[1]=='M'))) {
779                         addr = (ulong)gunzip_bmp(addr, &len);
780                 }
781 #endif
782
783                 if (lcd_display_bitmap (addr, 0, 0) == 0) {
784                         return ((void *)lcd_base);
785                 }
786         }
787 #endif /* CONFIG_SPLASH_SCREEN */
788
789 #ifdef CONFIG_LCD_LOGO
790         bitmap_plot (0, 0);
791 #endif /* CONFIG_LCD_LOGO */
792
793 #ifdef CONFIG_LCD_INFO
794         console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
795         console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
796         lcd_show_board_info();
797 #endif /* CONFIG_LCD_INFO */
798
799 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
800         return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
801 #else
802         return ((void *)lcd_base);
803 #endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
804 }
805
806 /************************************************************************/
807 /************************************************************************/