]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc8xx/lcd.c
* Add support for Promess ATC board
[karo-tx-uboot.git] / cpu / mpc8xx / lcd.c
1 /*
2  * (C) Copyright 2001-2002
3  * Wolfgang Denk, DENX Software Engineering -- wd@denx.de
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 /************************************************************************/
25 /* ** HEADER FILES                                                      */
26 /************************************************************************/
27
28 #include <config.h>
29 #include <common.h>
30 #include <watchdog.h>
31 #include <version.h>
32 #include <stdarg.h>
33 #include <lcdvideo.h>
34 #include <linux/types.h>
35 #include <devices.h>
36 #if defined(CONFIG_POST)
37 #include <post.h>
38 #endif
39
40
41 #ifdef CONFIG_LCD
42
43 /************************************************************************/
44 /* ** CONFIG STUFF -- should be moved to board config file              */
45 /************************************************************************/
46 #define CONFIG_LCD_LOGO
47 #define LCD_INFO                /* Display Logo, (C) and system info    */
48
49 #if defined(CONFIG_V37) || defined(CONFIG_EDT32F10)
50 #undef CONFIG_LCD_LOGO
51 #undef LCD_INFO
52 #endif
53
54 /* #define LCD_TEST_PATTERN */  /* color backgnd for frame/color adjust */
55 /* #define CFG_INVERT_COLORS */ /* Not needed - adjust vl_dp instead    */
56 /************************************************************************/
57
58 /************************************************************************/
59 /* ** BITMAP DISPLAY SUPPORT  -- should probably be moved elsewhere     */
60 /************************************************************************/
61
62 #if (CONFIG_COMMANDS & CFG_CMD_BMP)
63 #include <bmp_layout.h>
64 #endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) */
65
66 /************************************************************************/
67 /* ** FONT AND LOGO DATA                                                */
68 /************************************************************************/
69
70 #include <video_font.h>         /* Get font data, width and height      */
71
72 #ifdef CONFIG_LCD_LOGO
73 # include <bmp_logo.h>          /* Get logo data, width and height      */
74 #endif
75
76 /************************************************************************/
77 /************************************************************************/
78
79 /*
80  *  Information about displays we are using.  This is for configuring
81  *  the LCD controller and memory allocation.  Someone has to know what
82  *  is connected, as we can't autodetect anything.
83  */
84 #define CFG_HIGH        0       /* Pins are active high */
85 #define CFG_LOW         1       /* Pins are active low */
86
87 typedef struct vidinfo {
88     ushort      vl_col;         /* Number of columns (i.e. 640) */
89     ushort      vl_row;         /* Number of rows (i.e. 480) */
90     ushort      vl_width;       /* Width of display area in millimeters */
91     ushort      vl_height;      /* Height of display area in millimeters */
92
93     /* LCD configuration register.
94     */
95     u_char      vl_clkp;        /* Clock polarity */
96     u_char      vl_oep;         /* Output Enable polarity */
97     u_char      vl_hsp;         /* Horizontal Sync polarity */
98     u_char      vl_vsp;         /* Vertical Sync polarity */
99     u_char      vl_dp;          /* Data polarity */
100     u_char      vl_bpix;        /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8 */
101     u_char      vl_lbw;         /* LCD Bus width, 0 = 4, 1 = 8 */
102     u_char      vl_splt;        /* Split display, 0 = single-scan, 1 = dual-scan */
103     u_char      vl_clor;        /* Color, 0 = mono, 1 = color */
104     u_char      vl_tft;         /* 0 = passive, 1 = TFT */
105
106     /* Horizontal control register.  Timing from data sheet.
107     */
108     ushort      vl_wbl;         /* Wait between lines */
109
110     /* Vertical control register.
111     */
112     u_char      vl_vpw;         /* Vertical sync pulse width */
113     u_char      vl_lcdac;       /* LCD AC timing */
114     u_char      vl_wbf;         /* Wait between frames */
115 } vidinfo_t;
116
117 #define LCD_MONOCHROME  0
118 #define LCD_COLOR2      1
119 #define LCD_COLOR4      2
120 #define LCD_COLOR8      3
121
122 /*----------------------------------------------------------------------*/
123 #ifdef CONFIG_KYOCERA_KCS057QV1AJ
124 /*
125  *  Kyocera KCS057QV1AJ-G23. Passive, color, single scan.
126  */
127 #define LCD_BPP LCD_COLOR4
128
129 static vidinfo_t panel_info = {
130     640, 480, 132, 99, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH,
131     LCD_BPP, 1, 0, 1, 0,  5, 0, 0, 0
132                 /* wbl, vpw, lcdac, wbf */
133 };
134 #endif /* CONFIG_KYOCERA_KCS057QV1AJ */
135 /*----------------------------------------------------------------------*/
136
137 /*----------------------------------------------------------------------*/
138 #ifdef CONFIG_NEC_NL6648AC33
139 /*
140  *  NEC NL6648AC33-18. Active, color, single scan.
141  */
142 static vidinfo_t panel_info = {
143     640, 480, 132, 99, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
144     3, 0, 0, 1, 1, 144, 2, 0, 33
145                 /* wbl, vpw, lcdac, wbf */
146 };
147 #endif /* CONFIG_NEC_NL6648AC33 */
148 /*----------------------------------------------------------------------*/
149
150 #ifdef CONFIG_NEC_NL6648BC20
151 /*
152  *  NEC NL6648BC20-08. 6.5", 640x480. Active, color, single scan.
153  */
154 static vidinfo_t panel_info = {
155     640, 480, 132, 99, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
156     3, 0, 0, 1, 1, 144, 2, 0, 33
157                 /* wbl, vpw, lcdac, wbf */
158 };
159 #endif /* CONFIG_NEC_NL6648BC20 */
160 /*----------------------------------------------------------------------*/
161
162 #ifdef CONFIG_SHARP_LQ104V7DS01
163 /*
164  *  SHARP LQ104V7DS01. 6.5", 640x480. Active, color, single scan.
165  */
166 static vidinfo_t panel_info = {
167     640, 480, 132, 99, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_LOW,
168     3, 0, 0, 1, 1, 25, 1, 0, 33
169                 /* wbl, vpw, lcdac, wbf */
170 };
171 #endif /* CONFIG_SHARP_LQ104V7DS01 */
172 /*----------------------------------------------------------------------*/
173
174 #ifdef CONFIG_SHARP_16x9
175 /*
176  * Sharp 320x240. Active, color, single scan.  It isn't 16x9, and I am
177  * not sure what it is.......
178  */
179 static vidinfo_t panel_info = {
180     320, 240, 0, 0, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH,
181     3, 0, 0, 1, 1, 15, 4, 0, 3
182 };
183 #endif /* CONFIG_SHARP_16x9 */
184 /*----------------------------------------------------------------------*/
185
186 #ifdef CONFIG_SHARP_LQ057Q3DC02
187 /*
188  * Sharp LQ057Q3DC02 display. Active, color, single scan.
189  */
190 #define LCD_DF 12
191
192 static vidinfo_t panel_info = {
193     320, 240, 0, 0, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
194     3, 0, 0, 1, 1, 15, 4, 0, 3
195                 /* wbl, vpw, lcdac, wbf */
196 };
197 #define LCD_INFO_BELOW_LOGO
198 #endif /* CONFIG_SHARP_LQ057Q3DC02 */
199 /*----------------------------------------------------------------------*/
200
201 #ifdef CONFIG_SHARP_LQ64D341
202 /*
203  * Sharp LQ64D341 display, 640x480. Active, color, single scan.
204  */
205 static vidinfo_t panel_info = {
206     640, 480, 0, 0, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
207     3, 0, 0, 1, 1, 128, 16, 0, 32
208                 /* wbl, vpw, lcdac, wbf */
209 };
210 #endif /* CONFIG_SHARP_LQ64D341 */
211
212 #ifdef CONFIG_SHARP_LQ084V1DG21
213 /*
214  * Sharp LQ084V1DG21 display, 640x480. Active, color, single scan.
215  */
216 static vidinfo_t panel_info = {
217     640, 480, 171, 129, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_LOW,
218     3, 0, 0, 1, 1, 160, 3, 0, 48
219                 /* wbl, vpw, lcdac, wbf */
220 };
221 #endif /* CONFIG_SHARP_LQ084V1DG21 */
222
223 /*----------------------------------------------------------------------*/
224
225 #ifdef CONFIG_HLD1045
226 /*
227  * HLD1045 display, 640x480. Active, color, single scan.
228  */
229 static vidinfo_t panel_info = {
230     640, 480, 0, 0, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
231     3, 0, 0, 1, 1, 160, 3, 0, 48
232                 /* wbl, vpw, lcdac, wbf */
233 };
234 #endif /* CONFIG_HLD1045 */
235 /*----------------------------------------------------------------------*/
236
237 #ifdef CONFIG_PRIMEVIEW_V16C6448AC
238 /*
239  * Prime View V16C6448AC
240  */
241 static vidinfo_t panel_info = {
242     640, 480, 130, 98, CFG_HIGH, CFG_HIGH, CFG_LOW, CFG_LOW, CFG_HIGH,
243     3, 0, 0, 1, 1, 144, 2, 0, 35
244                 /* wbl, vpw, lcdac, wbf */
245 };
246 #endif /* CONFIG_PRIMEVIEW_V16C6448AC */
247
248 /*----------------------------------------------------------------------*/
249
250 #ifdef CONFIG_OPTREX_BW
251 /*
252  * Optrex   CBL50840-2 NF-FW 99 22 M5
253  * or
254  * Hitachi  LMG6912RPFC-00T
255  * or
256  * Hitachi  SP14Q002
257  *
258  * 320x240. Black & white.
259  */
260 #define OPTREX_BPP      0       /* 0 - monochrome,     1 bpp */
261                                 /* 1 -  4 grey levels, 2 bpp */
262                                 /* 2 - 16 grey levels, 4 bpp */
263 static vidinfo_t panel_info = {
264     320, 240, 0, 0, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_LOW,
265     OPTREX_BPP, 0, 0, 0, 0, 0, 0, 0, 0, 4
266 };
267 #endif /* CONFIG_OPTREX_BW */
268
269 /*-----------------------------------------------------------------*/
270 #ifdef CONFIG_EDT32F10
271 /*
272  * Emerging Display Technologies 320x240. Passive, monochrome, single scan.
273  */
274 #define LCD_BPP         LCD_MONOCHROME
275 #define LCD_DF          10
276
277 static vidinfo_t panel_info = {
278     320, 240, 0, 0, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_LOW,
279     LCD_BPP,  0, 0, 0, 0, 33, 0, 0, 0
280 };
281 #endif
282 /*----------------------------------------------------------------------*/
283
284 #if defined(LCD_INFO_BELOW_LOGO)
285 # define LCD_INFO_X             0
286 # define LCD_INFO_Y             (BMP_LOGO_HEIGHT + VIDEO_FONT_HEIGHT)
287 #elif defined(CONFIG_LCD_LOGO)
288 # define LCD_INFO_X             (BMP_LOGO_WIDTH + 4 * VIDEO_FONT_WIDTH)
289 # define LCD_INFO_Y             (VIDEO_FONT_HEIGHT)
290 #else
291 # define LCD_INFO_X             (VIDEO_FONT_WIDTH)
292 # define LCD_INFO_Y             (VIDEO_FONT_HEIGHT)
293 #endif
294
295 #ifndef LCD_BPP
296 #define LCD_BPP                 LCD_COLOR8
297 #endif
298 #ifndef LCD_DF
299 #define LCD_DF                  1
300 #endif
301
302 #define NBITS(bit_code)         (1 << (bit_code))
303 #define NCOLORS(bit_code)       (1 << NBITS(bit_code))
304
305 static int lcd_line_length;
306
307 static int lcd_color_fg;
308 static int lcd_color_bg;
309
310 static char lcd_is_enabled = 0;         /* Indicate that LCD is enabled */
311
312 /*
313  * Frame buffer memory information
314  */
315 static void *lcd_base;                  /* Start of framebuffer memory  */
316 static void *lcd_console_address;       /* Start of console buffer      */
317
318
319 /************************************************************************/
320 /* ** CONSOLE CONSTANTS                                                 */
321 /************************************************************************/
322
323 #if LCD_BPP == LCD_MONOCHROME
324
325 /*
326  * Simple color definitions
327  */
328 #define CONSOLE_COLOR_BLACK      0
329 #define CONSOLE_COLOR_WHITE      1      /* Must remain last / highest */
330
331 #else
332
333 /*
334  * Simple color definitions
335  */
336 #define CONSOLE_COLOR_BLACK      0
337 #define CONSOLE_COLOR_RED        1
338 #define CONSOLE_COLOR_GREEN      2
339 #define CONSOLE_COLOR_YELLOW     3
340 #define CONSOLE_COLOR_BLUE       4
341 #define CONSOLE_COLOR_MAGENTA    5
342 #define CONSOLE_COLOR_CYAN       6
343 #define CONSOLE_COLOR_GREY      14
344 #define CONSOLE_COLOR_WHITE     15      /* Must remain last / highest */
345
346 #endif
347
348 #if defined(CONFIG_LCD_LOGO) && (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
349 #error Default Color Map overlaps with Logo Color Map
350 #endif
351
352 /************************************************************************/
353
354 #ifndef PAGE_SIZE
355 #define PAGE_SIZE       4096
356 #endif
357
358
359 /************************************************************************/
360 /* ** CONSOLE DEFINITIONS & FUNCTIONS                                   */
361 /************************************************************************/
362
363 #if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)
364 #define CONSOLE_ROWS            ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
365                                         / VIDEO_FONT_HEIGHT)
366 #else
367 #define CONSOLE_ROWS            (panel_info.vl_row / VIDEO_FONT_HEIGHT)
368 #endif
369 #define CONSOLE_COLS            (panel_info.vl_col / VIDEO_FONT_WIDTH)
370 #define CONSOLE_ROW_SIZE        (VIDEO_FONT_HEIGHT * lcd_line_length)
371 #define CONSOLE_ROW_FIRST       (lcd_console_address)
372 #define CONSOLE_ROW_SECOND      (lcd_console_address + CONSOLE_ROW_SIZE)
373 #define CONSOLE_ROW_LAST        (lcd_console_address + CONSOLE_SIZE \
374                                         - CONSOLE_ROW_SIZE)
375 #define CONSOLE_SIZE            (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
376 #define CONSOLE_SCROLL_SIZE     (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
377
378 #if  LCD_BPP == LCD_MONOCHROME
379 #define COLOR_MASK(c)           ((c)      | (c) << 1 | (c) << 2 | (c) << 3 | \
380                                  (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
381 #elif LCD_BPP == LCD_COLOR8
382 #define COLOR_MASK(c)           (c)
383 #else
384 #error Unsupported LCD BPP.
385 #endif
386
387 static short console_col;
388 static short console_row;
389
390 /************************************************************************/
391
392 ulong   lcd_setmem (ulong addr);
393
394 static void     lcd_drawchars  (ushort x, ushort y, uchar *str, int count);
395 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s);
396 static inline void lcd_putc_xy (ushort x, ushort y, uchar  c);
397
398 static int      lcd_init (void *lcdbase);
399 static void     lcd_ctrl_init (void *lcdbase);
400 static void     lcd_enable (void);
401 static void    *lcd_logo (void);
402 #if LCD_BPP == LCD_COLOR8
403 static void     lcd_setcolreg (ushort regno,
404                                 ushort red, ushort green, ushort blue);
405 #endif
406 #if LCD_BPP == LCD_MONOCHROME
407 static void     lcd_initcolregs (void);
408 #endif
409 static int      lcd_getbgcolor (void);
410 static void     lcd_setfgcolor (int color);
411 static void     lcd_setbgcolor (int color);
412
413 #ifdef  NOT_USED_SO_FAR
414 static void     lcd_disable (void);
415 static void     lcd_getcolreg (ushort regno,
416                                 ushort *red, ushort *green, ushort *blue);
417 static int      lcd_getfgcolor (void);
418 #endif  /* NOT_USED_SO_FAR */
419
420 /************************************************************************/
421
422 /*----------------------------------------------------------------------*/
423
424 static void console_scrollup (void)
425 {
426 #if 1
427         /* Copy up rows ignoring the first one */
428         memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
429
430         /* Clear the last one */
431         memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
432 #else
433         /*
434          * Poor attempt to optimize speed by moving "long"s.
435          * But the code is ugly, and not a bit faster :-(
436          */
437         ulong *t = (ulong *)CONSOLE_ROW_FIRST;
438         ulong *s = (ulong *)CONSOLE_ROW_SECOND;
439         ulong    l = CONSOLE_SCROLL_SIZE / sizeof(ulong);
440         uchar  c = lcd_color_bg & 0xFF;
441         ulong val= (c<<24) | (c<<16) | (c<<8) | c;
442
443         while (l--)
444                 *t++ = *s++;
445
446         t = (ulong *)CONSOLE_ROW_LAST;
447         l = CONSOLE_ROW_SIZE / sizeof(ulong);
448
449         while (l-- > 0)
450                 *t++ = val;
451 #endif
452 }
453
454 /*----------------------------------------------------------------------*/
455
456 static inline void console_back (void)
457 {
458         if (--console_col < 0) {
459                 console_col = CONSOLE_COLS-1 ;
460                 if (--console_row < 0) {
461                         console_row = 0;
462                 }
463         }
464
465         lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
466                      console_row * VIDEO_FONT_HEIGHT,
467                      ' ');
468 }
469
470 /*----------------------------------------------------------------------*/
471
472 static inline void console_newline (void)
473 {
474         ++console_row;
475         console_col = 0;
476
477         /* Check if we need to scroll the terminal */
478         if (console_row >= CONSOLE_ROWS) {
479                 /* Scroll everything up */
480                 console_scrollup () ;
481                 --console_row;
482         }
483 }
484
485 /*----------------------------------------------------------------------*/
486
487 void lcd_putc (const char c)
488 {
489         if (!lcd_is_enabled) {
490                 serial_putc(c);
491                 return;
492         }
493
494         switch (c) {
495         case '\r':      console_col = 0;
496                         return;
497
498         case '\n':      console_newline();
499                         return;
500
501         case '\t':      /* Tab (8 chars alignment) */
502                         console_col |=  8;
503                         console_col &= ~7;
504
505                         if (console_col >= CONSOLE_COLS) {
506                                 console_newline();
507                         }
508                         return;
509
510         case '\b':      console_back();
511                         return;
512
513         default:        lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
514                                      console_row * VIDEO_FONT_HEIGHT,
515                                      c);
516                         if (++console_col >= CONSOLE_COLS) {
517                                 console_newline();
518                         }
519                         return;
520         }
521         /* NOTREACHED */
522 }
523
524 /*----------------------------------------------------------------------*/
525
526 void lcd_puts (const char *s)
527 {
528         if (!lcd_is_enabled) {
529                 serial_puts (s);
530                 return;
531         }
532
533         while (*s) {
534                 lcd_putc (*s++);
535         }
536 }
537
538 /************************************************************************/
539 /* ** Low-Level Graphics Routines                                       */
540 /************************************************************************/
541
542 static void lcd_drawchars (ushort x, ushort y, uchar *str, int count)
543 {
544         uchar *dest;
545         ushort off, row;
546
547         dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
548         off  = x * (1 << LCD_BPP) % 8;
549
550         for (row=0;  row < VIDEO_FONT_HEIGHT;  ++row, dest += lcd_line_length)  {
551                 uchar *s = str;
552                 uchar *d = dest;
553                 int i;
554
555 #if LCD_BPP == LCD_MONOCHROME
556                 uchar rest = *d & -(1 << (8-off));
557                 uchar sym;
558 #endif
559                 for (i=0; i<count; ++i) {
560                         uchar c, bits;
561
562                         c = *s++;
563                         bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
564
565 #if LCD_BPP == LCD_MONOCHROME
566                         sym  = (COLOR_MASK(lcd_color_fg) & bits) |
567                                (COLOR_MASK(lcd_color_bg) & ~bits);
568
569                         *d++ = rest | (sym >> off);
570                         rest = sym << (8-off);
571 #elif LCD_BPP == LCD_COLOR8
572                         for (c=0; c<8; ++c) {
573                                 *d++ = (bits & 0x80) ?
574                                                 lcd_color_fg : lcd_color_bg;
575                                 bits <<= 1;
576                         }
577 #endif
578                 }
579
580 #if LCD_BPP == LCD_MONOCHROME
581                 *d  = rest | (*d & ((1 << (8-off)) - 1));
582 #endif
583         }
584 }
585
586 /*----------------------------------------------------------------------*/
587
588 static inline void lcd_puts_xy (ushort x, ushort y, uchar *s)
589 {
590 #if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)
591         lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen (s));
592 #else
593         lcd_drawchars (x, y, s, strlen (s));
594 #endif
595 }
596
597 /*----------------------------------------------------------------------*/
598
599 static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
600 {
601 #if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)
602         lcd_drawchars (x, y+BMP_LOGO_HEIGHT, &c, 1);
603 #else
604         lcd_drawchars (x, y, &c, 1);
605 #endif
606 }
607
608 /************************************************************************/
609 /**  Small utility to check that you got the colours right              */
610 /************************************************************************/
611 #ifdef LCD_TEST_PATTERN
612
613 #define N_BLK_VERT      2
614 #define N_BLK_HOR       3
615
616 static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
617         CONSOLE_COLOR_RED,      CONSOLE_COLOR_GREEN,    CONSOLE_COLOR_YELLOW,
618         CONSOLE_COLOR_BLUE,     CONSOLE_COLOR_MAGENTA,  CONSOLE_COLOR_CYAN,
619 };
620
621 static void test_pattern (void)
622 {
623         ushort v_max  = panel_info.vl_row;
624         ushort h_max  = panel_info.vl_col;
625         ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
626         ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
627         ushort v, h;
628         uchar *pix = (uchar *)lcd_base;
629
630         printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
631                 h_max, v_max, h_step, v_step);
632
633         /* WARNING: Code silently assumes 8bit/pixel */
634         for (v=0; v<v_max; ++v) {
635                 uchar iy = v / v_step;
636                 for (h=0; h<h_max; ++h) {
637                         uchar ix = N_BLK_HOR * iy + (h/h_step);
638                         *pix++ = test_colors[ix];
639                 }
640         }
641 }
642 #endif /* LCD_TEST_PATTERN */
643
644
645 /************************************************************************/
646 /* ** GENERIC Initialization Routines                                   */
647 /************************************************************************/
648
649 int drv_lcd_init (void)
650 {
651         DECLARE_GLOBAL_DATA_PTR;
652
653         device_t lcddev;
654         int rc;
655
656         lcd_base = (void *)(gd->fb_base);
657
658         lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
659
660         lcd_init (lcd_base);            /* LCD initialization */
661
662         /* Device initialization */
663         memset (&lcddev, 0, sizeof (lcddev));
664
665         strcpy (lcddev.name, "lcd");
666         lcddev.ext   = 0;                       /* No extensions */
667         lcddev.flags = DEV_FLAGS_OUTPUT;        /* Output only */
668         lcddev.putc  = lcd_putc;                /* 'putc' function */
669         lcddev.puts  = lcd_puts;                /* 'puts' function */
670
671         rc = device_register (&lcddev);
672
673         return (rc == 0) ? 1 : rc;
674 }
675
676 /*----------------------------------------------------------------------*/
677
678 static int lcd_init (void *lcdbase)
679 {
680         /* Initialize the lcd controller */
681         debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
682
683         lcd_ctrl_init (lcdbase);
684
685 #if LCD_BPP == LCD_MONOCHROME
686         /* Setting the palette */
687         lcd_initcolregs();
688
689 #elif LCD_BPP == LCD_COLOR8
690         /* Setting the palette */
691         lcd_setcolreg  (CONSOLE_COLOR_BLACK,       0,    0,    0);
692         lcd_setcolreg  (CONSOLE_COLOR_RED,      0xFF,    0,    0);
693         lcd_setcolreg  (CONSOLE_COLOR_GREEN,       0, 0xFF,    0);
694         lcd_setcolreg  (CONSOLE_COLOR_YELLOW,   0xFF, 0xFF,    0);
695         lcd_setcolreg  (CONSOLE_COLOR_BLUE,        0,    0, 0xFF);
696         lcd_setcolreg  (CONSOLE_COLOR_MAGENTA,  0xFF,    0, 0xFF);
697         lcd_setcolreg  (CONSOLE_COLOR_CYAN,        0, 0xFF, 0xFF);
698         lcd_setcolreg  (CONSOLE_COLOR_GREY,     0xAA, 0xAA, 0xAA);
699         lcd_setcolreg  (CONSOLE_COLOR_WHITE,    0xFF, 0xFF, 0xFF);
700 #endif
701
702 #ifndef CFG_WHITE_ON_BLACK
703         lcd_setfgcolor (CONSOLE_COLOR_BLACK);
704         lcd_setbgcolor (CONSOLE_COLOR_WHITE);
705 #else
706         lcd_setfgcolor (CONSOLE_COLOR_WHITE);
707         lcd_setbgcolor (CONSOLE_COLOR_BLACK);
708 #endif  /* CFG_WHITE_ON_BLACK */
709
710 #ifdef  LCD_TEST_PATTERN
711         test_pattern();
712 #else
713         /* set framebuffer to background color */
714         memset ((char *)lcd_base,
715                 COLOR_MASK(lcd_getbgcolor()),
716                 lcd_line_length*panel_info.vl_row);
717 #endif
718
719         lcd_enable ();
720
721         /* Paint the logo and retrieve LCD base address */
722         debug ("[LCD] Drawing the logo...\n");
723         lcd_console_address = lcd_logo ();
724
725         /* Initialize the console */
726         console_col = 0;
727 #ifdef LCD_INFO_BELOW_LOGO
728         console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
729 #else
730         console_row = 1;        /* leave 1 blank line below logo */
731 #endif
732         lcd_is_enabled = 1;
733
734         return 0;
735 }
736
737
738 /************************************************************************/
739 /* ** ROM capable initialization part - needed to reserve FB memory     */
740 /************************************************************************/
741
742 /*
743  * This is called early in the system initialization to grab memory
744  * for the LCD controller.
745  * Returns new address for monitor, after reserving LCD buffer memory
746  *
747  * Note that this is running from ROM, so no write access to global data.
748  */
749 ulong lcd_setmem (ulong addr)
750 {
751         ulong size;
752         int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
753
754         debug ("LCD panel info: %d x %d, %d bit/pix\n",
755                 panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
756
757         size = line_length * panel_info.vl_row;
758
759         /* Round up to nearest full page */
760         size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
761
762         /* Allocate pages for the frame buffer. */
763         addr -= size;
764
765         debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
766
767         return (addr);
768 }
769
770
771 /************************************************************************/
772 /* ----------------- chipset specific functions ----------------------- */
773 /************************************************************************/
774
775 static void lcd_ctrl_init (void *lcdbase)
776 {
777         volatile immap_t *immr = (immap_t *) CFG_IMMR;
778         volatile lcd823_t *lcdp = &immr->im_lcd;
779
780         uint lccrtmp;
781
782         /* Initialize the LCD control register according to the LCD
783          * parameters defined.  We do everything here but enable
784          * the controller.
785          */
786
787         lccrtmp  = LCDBIT (LCCR_BNUM_BIT,
788                    (((panel_info.vl_row * panel_info.vl_col) * (1 << LCD_BPP)) / 128));
789
790         lccrtmp |= LCDBIT (LCCR_CLKP_BIT, panel_info.vl_clkp)   |
791                    LCDBIT (LCCR_OEP_BIT,  panel_info.vl_oep)    |
792                    LCDBIT (LCCR_HSP_BIT,  panel_info.vl_hsp)    |
793                    LCDBIT (LCCR_VSP_BIT,  panel_info.vl_vsp)    |
794                    LCDBIT (LCCR_DP_BIT,   panel_info.vl_dp)     |
795                    LCDBIT (LCCR_BPIX_BIT, panel_info.vl_bpix)   |
796                    LCDBIT (LCCR_LBW_BIT,  panel_info.vl_lbw)    |
797                    LCDBIT (LCCR_SPLT_BIT, panel_info.vl_splt)   |
798                    LCDBIT (LCCR_CLOR_BIT, panel_info.vl_clor)   |
799                    LCDBIT (LCCR_TFT_BIT,  panel_info.vl_tft);
800
801 #if 0
802         lccrtmp |= ((SIU_LEVEL5 / 2) << 12);
803         lccrtmp |= LCCR_EIEN;
804 #endif
805
806         lcdp->lcd_lccr = lccrtmp;
807         lcdp->lcd_lcsr = 0xFF;          /* Clear pending interrupts */
808
809         /* Initialize LCD controller bus priorities.
810          */
811         immr->im_siu_conf.sc_sdcr &= ~0x0f;     /* RAID = LAID = 0 */
812
813         /* set SHFT/CLOCK division factor 4
814          * This needs to be set based upon display type and processor
815          * speed.  The TFT displays run about 20 to 30 MHz.
816          * I was running 64 MHz processor speed.
817          * The value for this divider must be chosen so the result is
818          * an integer of the processor speed (i.e., divide by 3 with
819          * 64 MHz would be bad).
820          */
821         immr->im_clkrst.car_sccr &= ~0x1F;
822         immr->im_clkrst.car_sccr |= LCD_DF;     /* was 8 */
823
824 #ifndef CONFIG_EDT32F10
825         /* Enable LCD on port D.
826          */
827         immr->im_ioport.iop_pdpar |= 0x1FFF;
828         immr->im_ioport.iop_pddir |= 0x1FFF;
829
830         /* Enable LCD_A/B/C on port B.
831          */
832         immr->im_cpm.cp_pbpar |= 0x00005001;
833         immr->im_cpm.cp_pbdir |= 0x00005001;
834 #else
835         /* Enable LCD on port D.
836          */
837         immr->im_ioport.iop_pdpar |= 0x1DFF;
838         immr->im_ioport.iop_pdpar &= ~0x0200;
839         immr->im_ioport.iop_pddir |= 0x1FFF;
840         immr->im_ioport.iop_pddat |= 0x0200;
841 #endif
842
843         /* Load the physical address of the linear frame buffer
844          * into the LCD controller.
845          * BIG NOTE:  This has to be modified to load A and B depending
846          * upon the split mode of the LCD.
847          */
848         lcdp->lcd_lcfaa = (ulong)lcd_base;
849         lcdp->lcd_lcfba = (ulong)lcd_base;
850
851         /* MORE HACKS...This must be updated according to 823 manual
852          * for different panels.
853          */
854 #ifndef CONFIG_EDT32F10
855         lcdp->lcd_lchcr = LCHCR_BO |
856                           LCDBIT (LCHCR_AT_BIT, 4) |
857                           LCDBIT (LCHCR_HPC_BIT, panel_info.vl_col) |
858                           panel_info.vl_wbl;
859 #else
860         lcdp->lcd_lchcr = LCHCR_BO |
861                           LCDBIT (LCHCR_AT_BIT, 4) |
862                           LCDBIT (LCHCR_HPC_BIT, panel_info.vl_col/4) |
863                           panel_info.vl_wbl;
864 #endif
865
866         lcdp->lcd_lcvcr = LCDBIT (LCVCR_VPW_BIT, panel_info.vl_vpw) |
867                           LCDBIT (LCVCR_LCD_AC_BIT, panel_info.vl_lcdac) |
868                           LCDBIT (LCVCR_VPC_BIT, panel_info.vl_row) |
869                           panel_info.vl_wbf;
870
871 }
872
873 /*----------------------------------------------------------------------*/
874
875 #ifdef  NOT_USED_SO_FAR
876 static void
877 lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue)
878 {
879         volatile immap_t *immr = (immap_t *) CFG_IMMR;
880         volatile cpm8xx_t *cp = &(immr->im_cpm);
881         unsigned short colreg, *cmap_ptr;
882
883         cmap_ptr = (unsigned short *)&cp->lcd_cmap[regno * 2];
884
885         colreg = *cmap_ptr;
886 #ifdef  CFG_INVERT_COLORS
887         colreg ^= 0x0FFF;
888 #endif
889
890         *red   = (colreg >> 8) & 0x0F;
891         *green = (colreg >> 4) & 0x0F;
892         *blue  =  colreg       & 0x0F;
893 }
894 #endif  /* NOT_USED_SO_FAR */
895
896 /*----------------------------------------------------------------------*/
897
898 #if LCD_BPP == LCD_COLOR8
899 static void
900 lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue)
901 {
902         volatile immap_t *immr = (immap_t *) CFG_IMMR;
903         volatile cpm8xx_t *cp = &(immr->im_cpm);
904         unsigned short colreg, *cmap_ptr;
905
906         cmap_ptr = (unsigned short *)&cp->lcd_cmap[regno * 2];
907
908         colreg = ((red   & 0x0F) << 8) |
909                  ((green & 0x0F) << 4) |
910                   (blue  & 0x0F) ;
911 #ifdef  CFG_INVERT_COLORS
912         colreg ^= 0x0FFF;
913 #endif
914         *cmap_ptr = colreg;
915
916         debug ("setcolreg: reg %2d @ %p: R=%02X G=%02X B=%02X => %02X%02X\n",
917                 regno, &(cp->lcd_cmap[regno * 2]),
918                 red, green, blue,
919                 cp->lcd_cmap[ regno * 2 ], cp->lcd_cmap[(regno * 2) + 1]);
920 }
921 #endif  /* LCD_COLOR8 */
922
923 /*----------------------------------------------------------------------*/
924
925 #if LCD_BPP == LCD_MONOCHROME
926 static
927 void lcd_initcolregs (void)
928 {
929         volatile immap_t *immr = (immap_t *) CFG_IMMR;
930         volatile cpm8xx_t *cp = &(immr->im_cpm);
931         ushort regno;
932
933         for (regno = 0; regno < 16; regno++) {
934                 cp->lcd_cmap[regno * 2] = 0;
935                 cp->lcd_cmap[(regno * 2) + 1] = regno & 0x0f;
936         }
937 }
938 #endif
939
940 /*----------------------------------------------------------------------*/
941
942 static void lcd_setfgcolor (int color)
943 {
944         lcd_color_fg = color & 0x0F;
945 }
946
947 /*----------------------------------------------------------------------*/
948
949 static void lcd_setbgcolor (int color)
950 {
951         lcd_color_bg = color & 0x0F;
952 }
953
954 /*----------------------------------------------------------------------*/
955
956 #ifdef  NOT_USED_SO_FAR
957 static int lcd_getfgcolor (void)
958 {
959         return lcd_color_fg;
960 }
961 #endif  /* NOT_USED_SO_FAR */
962
963 /*----------------------------------------------------------------------*/
964
965 static int lcd_getbgcolor (void)
966 {
967         return lcd_color_bg;
968 }
969
970 /*----------------------------------------------------------------------*/
971
972 static void lcd_enable (void)
973 {
974         volatile immap_t *immr = (immap_t *) CFG_IMMR;
975         volatile lcd823_t *lcdp = &immr->im_lcd;
976
977         /* Enable the LCD panel */
978         immr->im_siu_conf.sc_sdcr |= (1 << (31 - 25));          /* LAM = 1 */
979         lcdp->lcd_lccr |= LCCR_PON;
980
981 #ifdef CONFIG_V37
982         /* Turn on display backlight */
983         immr->im_cpm.cp_pbpar |= 0x00008000;
984         immr->im_cpm.cp_pbdir |= 0x00008000;
985 #endif
986
987 #if defined(CONFIG_LWMON)
988     {   uchar c = pic_read (0x60);
989 #if defined(CONFIG_LCD) && defined(CONFIG_LWMON) && (CONFIG_POST & CFG_POST_SYSMON)
990         c |= 0x04;      /* Chip Enable LCD */
991 #else
992         c |= 0x07;      /* Power on CCFL, Enable CCFL, Chip Enable LCD */
993 #endif
994         pic_write (0x60, c);
995     }
996 #endif /* CONFIG_LWMON */
997
998 #if defined(CONFIG_R360MPI)
999     {
1000         extern void r360_i2c_lcd_write (uchar data0, uchar data1);
1001
1002         r360_i2c_lcd_write(0x10, 0x01);
1003         r360_i2c_lcd_write(0x20, 0x01);
1004         r360_i2c_lcd_write(0x3F, 0xFF);
1005         r360_i2c_lcd_write(0x47, 0xFF);
1006     }
1007 #endif /* CONFIG_R360MPI */
1008 }
1009
1010 /*----------------------------------------------------------------------*/
1011
1012 #ifdef  NOT_USED_SO_FAR
1013 static void lcd_disable (void)
1014 {
1015         volatile immap_t *immr = (immap_t *) CFG_IMMR;
1016         volatile lcd823_t *lcdp = &immr->im_lcd;
1017
1018 #if defined(CONFIG_LWMON)
1019     {   uchar c = pic_read (0x60);
1020         c &= ~0x07;     /* Power off CCFL, Disable CCFL, Chip Disable LCD */
1021         pic_write (0x60, c);
1022     }
1023 #elif defined(CONFIG_R360MPI)
1024     {
1025         extern void r360_i2c_lcd_write (uchar data0, uchar data1);
1026
1027         r360_i2c_lcd_write(0x10, 0x00);
1028         r360_i2c_lcd_write(0x20, 0x00);
1029         r360_i2c_lcd_write(0x30, 0x00);
1030         r360_i2c_lcd_write(0x40, 0x00);
1031     }
1032 #endif /* CONFIG_LWMON */
1033         /* Disable the LCD panel */
1034         lcdp->lcd_lccr &= ~LCCR_PON;
1035         immr->im_siu_conf.sc_sdcr &= ~(1 << (31 - 25)); /* LAM = 0 */
1036 }
1037 #endif  /* NOT_USED_SO_FAR */
1038
1039
1040 /************************************************************************/
1041 /* ** Chipset depending Bitmap / Logo stuff...                          */
1042 /************************************************************************/
1043
1044
1045 #ifdef CONFIG_LCD_LOGO
1046 static void bitmap_plot (int x, int y)
1047 {
1048         volatile immap_t *immr = (immap_t *) CFG_IMMR;
1049         volatile cpm8xx_t *cp = &(immr->im_cpm);
1050         ushort *cmap;
1051         ushort i;
1052         uchar *bmap;
1053         uchar *fb;
1054
1055         debug ("Logo: width %d  height %d  colors %d  cmap %d\n",
1056                 BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
1057                 sizeof(bmp_logo_palette)/(sizeof(ushort))
1058         );
1059
1060         /* Leave room for default color map */
1061         cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
1062
1063         WATCHDOG_RESET();
1064
1065         /* Set color map */
1066         for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
1067                 ushort colreg = bmp_logo_palette[i];
1068 #ifdef  CFG_INVERT_COLORS
1069                 colreg ^= 0xFFF;
1070 #endif
1071                 *cmap++ = colreg;
1072         }
1073
1074         bmap = &bmp_logo_bitmap[0];
1075         fb   = (char *)(lcd_base + y * lcd_line_length + x);
1076
1077         WATCHDOG_RESET();
1078
1079         for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
1080                 memcpy (fb, bmap, BMP_LOGO_WIDTH);
1081                 bmap += BMP_LOGO_WIDTH;
1082                 fb   += panel_info.vl_col;
1083         }
1084
1085         WATCHDOG_RESET();
1086 }
1087 #endif /* CONFIG_LCD_LOGO */
1088
1089 #if (CONFIG_COMMANDS & CFG_CMD_BMP)
1090 /*
1091  * Display the BMP file located at address bmp_image.
1092  * Only uncompressed
1093  */
1094 int lcd_display_bitmap(ulong bmp_image)
1095 {
1096         volatile immap_t *immr = (immap_t *) CFG_IMMR;
1097         volatile cpm8xx_t *cp = &(immr->im_cpm);
1098         ushort *cmap;
1099         ushort i, j;
1100         uchar *fb;
1101         bmp_image_t *bmp=(bmp_image_t *)bmp_image;
1102         uchar *bmap;
1103         ushort padded_line;
1104         unsigned long width, height;
1105         unsigned colors,bpix;
1106         unsigned long compression;
1107
1108         WATCHDOG_RESET();
1109
1110         if (!((bmp->header.signature[0]=='B') &&
1111               (bmp->header.signature[1]=='M'))) {
1112                 printf ("Error: no valid bmp image at %lx\n", bmp_image);
1113                 return 1;
1114         }
1115
1116         width = le32_to_cpu (bmp->header.width);
1117         height = le32_to_cpu (bmp->header.height);
1118         colors = 1<<le16_to_cpu (bmp->header.bit_count);
1119         compression = le32_to_cpu (bmp->header.compression);
1120
1121         bpix = NBITS(panel_info.vl_bpix);
1122
1123         if ((bpix != 1) && (bpix != 8)) {
1124                 printf ("Error: %d bit/pixel mode not supported by U-Boot\n",
1125                         bpix);
1126                 return 1;
1127         }
1128
1129         if (bpix != le16_to_cpu(bmp->header.bit_count)) {
1130                 printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
1131                         bpix,
1132                         le16_to_cpu(bmp->header.bit_count));
1133                 return 1;
1134         }
1135
1136         if (compression!=BMP_BI_RGB) {
1137                 printf ("Error: compression type %ld not supported\n",
1138                         compression);
1139                 return 1;
1140         }
1141
1142         debug ("Display-bmp: %d x %d  with %d colors\n",
1143                width, height, colors);
1144
1145         if (bpix==8) {
1146                 /* Fill the entire color map */
1147                 cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
1148
1149                 /* Set color map */
1150                 for (i = 0; i < colors; ++i) {
1151                         bmp_color_table_entry_t cte = bmp->color_table[i];
1152                         ushort colreg =
1153                                 ((cte.red>>4)   << 8) |
1154                                 ((cte.green>>4) << 4) |
1155                                 (cte.blue>>4) ;
1156 #ifdef  CFG_INVERT_COLORS
1157                         colreg ^= 0xFFF;
1158 #endif
1159                         *cmap-- = colreg;
1160                 }
1161
1162                 WATCHDOG_RESET();
1163         }
1164
1165         padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);
1166         if (width>panel_info.vl_col)
1167                 width = panel_info.vl_col;
1168         if (height>panel_info.vl_row)
1169                 height = panel_info.vl_row;
1170
1171         bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);
1172         fb   = (uchar *)
1173                 (lcd_base +
1174                  (((height>=panel_info.vl_row) ? panel_info.vl_row : height)-1)
1175                  * lcd_line_length);
1176         for (i = 0; i < height; ++i) {
1177                 WATCHDOG_RESET();
1178                 for (j = 0; j < width ; j++)
1179                         *(fb++)=255-*(bmap++);
1180                 bmap += (width - padded_line);
1181                 fb   -= (width + lcd_line_length);
1182         }
1183
1184         return (0);
1185 }
1186 #endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) */
1187
1188 /*----------------------------------------------------------------------*/
1189
1190 static void *lcd_logo (void)
1191 {
1192 #ifdef LCD_INFO
1193         DECLARE_GLOBAL_DATA_PTR;
1194
1195         char info[80];
1196         char temp[32];
1197 #endif /* LCD_INFO */
1198
1199 #ifdef CONFIG_SPLASH_SCREEN
1200         char *s;
1201         ulong addr;
1202
1203         if ((s = getenv("splashimage")) != NULL) {
1204                 addr = simple_strtoul(s, NULL, 16);
1205
1206                 if (lcd_display_bitmap (addr) == 0) {
1207                         return ((void *)lcd_base);
1208                 }
1209         }
1210 #endif  /* CONFIG_SPLASH_SCREEN */
1211
1212 #ifdef CONFIG_LCD_LOGO
1213         bitmap_plot (0, 0);
1214 #endif /* CONFIG_LCD_LOGO */
1215
1216
1217 #ifdef LCD_INFO
1218         sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__);
1219         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, info, strlen(info));
1220
1221         sprintf (info, "(C) 2003 DENX Software Engineering");
1222         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT,
1223                                         info, strlen(info));
1224
1225         sprintf (info, "    Wolfgang DENK, wd@denx.de");
1226         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2,
1227                                         info, strlen(info));
1228 #ifdef LCD_INFO_BELOW_LOGO
1229         sprintf (info, "MPC823 CPU at %s MHz",
1230                 strmhz(temp, gd->cpu_clk));
1231         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3,
1232                                         info, strlen(info));
1233         sprintf (info, "  %ld MB RAM, %ld MB Flash",
1234                 gd->ram_size >> 20,
1235                 gd->bd->bi_flashsize >> 20 );
1236         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
1237                                         info, strlen(info));
1238 #else
1239         /* leave one blank line */
1240
1241         sprintf (info, "MPC823 CPU at %s MHz, %ld MB RAM, %ld MB Flash",
1242                 strmhz(temp, gd->cpu_clk),
1243                 gd->ram_size >> 20,
1244                 gd->bd->bi_flashsize >> 20 );
1245         lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
1246                                         info, strlen(info));
1247 #endif /* LCD_INFO_BELOW_LOGO */
1248 #endif /* LCD_INFO */
1249
1250 #if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)
1251         return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
1252 #else
1253         return ((void *)lcd_base);
1254 #endif  /* CONFIG_LCD_LOGO */
1255 }
1256
1257 /************************************************************************/
1258 /************************************************************************/
1259
1260 #endif /* CONFIG_LCD */