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