u-boot-brain/common/lcd.c
Stelian Pop 39cf480484 Add ATMEL LCD driver
This patch adds support for the ATMEL LCDC driver which is used on some
AT91 and AVR platforms.

Is has been tested with the AT91CAP9ADK, AT91SAM9261EK, AT91SAM9263EK and
AT91SAM9RLEK boards. Adaptation for AVR32 should probably be easy.

Signed-off-by: Stelian Pop <stelian@popies.net>
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
2008-05-10 11:44:55 +02:00

856 lines
22 KiB
C

/*
* Common LCD routines for supported CPUs
*
* (C) Copyright 2001-2002
* Wolfgang Denk, DENX Software Engineering -- wd@denx.de
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/************************************************************************/
/* ** HEADER FILES */
/************************************************************************/
/* #define DEBUG */
#include <config.h>
#include <common.h>
#include <command.h>
#include <version.h>
#include <stdarg.h>
#include <linux/types.h>
#include <devices.h>
#if defined(CONFIG_POST)
#include <post.h>
#endif
#include <lcd.h>
#include <watchdog.h>
#if defined(CONFIG_PXA250)
#include <asm/byteorder.h>
#endif
#if defined(CONFIG_MPC823)
#include <lcdvideo.h>
#endif
#if defined(CONFIG_ATMEL_LCD)
#include <atmel_lcdc.h>
#include <nand.h>
extern nand_info_t nand_info[];
#endif
#ifdef CONFIG_LCD
/************************************************************************/
/* ** FONT DATA */
/************************************************************************/
#include <video_font.h> /* Get font data, width and height */
/************************************************************************/
/* ** LOGO DATA */
/************************************************************************/
#ifdef CONFIG_LCD_LOGO
# include <bmp_logo.h> /* Get logo data, width and height */
# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)
# error Default Color Map overlaps with Logo Color Map
# endif
#endif
DECLARE_GLOBAL_DATA_PTR;
ulong lcd_setmem (ulong addr);
static void lcd_drawchars (ushort x, ushort y, uchar *str, int count);
static inline void lcd_puts_xy (ushort x, ushort y, uchar *s);
static inline void lcd_putc_xy (ushort x, ushort y, uchar c);
static int lcd_init (void *lcdbase);
static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
extern void lcd_ctrl_init (void *lcdbase);
extern void lcd_enable (void);
static void *lcd_logo (void);
#if LCD_BPP == LCD_COLOR8
extern void lcd_setcolreg (ushort regno,
ushort red, ushort green, ushort blue);
#endif
#if LCD_BPP == LCD_MONOCHROME
extern void lcd_initcolregs (void);
#endif
static int lcd_getbgcolor (void);
static void lcd_setfgcolor (int color);
static void lcd_setbgcolor (int color);
char lcd_is_enabled = 0;
extern vidinfo_t panel_info;
#ifdef NOT_USED_SO_FAR
static void lcd_getcolreg (ushort regno,
ushort *red, ushort *green, ushort *blue);
static int lcd_getfgcolor (void);
#endif /* NOT_USED_SO_FAR */
/************************************************************************/
/*----------------------------------------------------------------------*/
static void console_scrollup (void)
{
#if 1
/* Copy up rows ignoring the first one */
memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE);
/* Clear the last one */
memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);
#else
/*
* Poor attempt to optimize speed by moving "long"s.
* But the code is ugly, and not a bit faster :-(
*/
ulong *t = (ulong *)CONSOLE_ROW_FIRST;
ulong *s = (ulong *)CONSOLE_ROW_SECOND;
ulong l = CONSOLE_SCROLL_SIZE / sizeof(ulong);
uchar c = lcd_color_bg & 0xFF;
ulong val= (c<<24) | (c<<16) | (c<<8) | c;
while (l--)
*t++ = *s++;
t = (ulong *)CONSOLE_ROW_LAST;
l = CONSOLE_ROW_SIZE / sizeof(ulong);
while (l-- > 0)
*t++ = val;
#endif
}
/*----------------------------------------------------------------------*/
static inline void console_back (void)
{
if (--console_col < 0) {
console_col = CONSOLE_COLS-1 ;
if (--console_row < 0) {
console_row = 0;
}
}
lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
console_row * VIDEO_FONT_HEIGHT,
' ');
}
/*----------------------------------------------------------------------*/
static inline void console_newline (void)
{
++console_row;
console_col = 0;
/* Check if we need to scroll the terminal */
if (console_row >= CONSOLE_ROWS) {
/* Scroll everything up */
console_scrollup () ;
--console_row;
}
}
/*----------------------------------------------------------------------*/
void lcd_putc (const char c)
{
if (!lcd_is_enabled) {
serial_putc(c);
return;
}
switch (c) {
case '\r': console_col = 0;
return;
case '\n': console_newline();
return;
case '\t': /* Tab (8 chars alignment) */
console_col |= 8;
console_col &= ~7;
if (console_col >= CONSOLE_COLS) {
console_newline();
}
return;
case '\b': console_back();
return;
default: lcd_putc_xy (console_col * VIDEO_FONT_WIDTH,
console_row * VIDEO_FONT_HEIGHT,
c);
if (++console_col >= CONSOLE_COLS) {
console_newline();
}
return;
}
/* NOTREACHED */
}
/*----------------------------------------------------------------------*/
void lcd_puts (const char *s)
{
if (!lcd_is_enabled) {
serial_puts (s);
return;
}
while (*s) {
lcd_putc (*s++);
}
}
/************************************************************************/
/* ** Low-Level Graphics Routines */
/************************************************************************/
static void lcd_drawchars (ushort x, ushort y, uchar *str, int count)
{
uchar *dest;
ushort off, row;
dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
off = x * (1 << LCD_BPP) % 8;
for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
uchar *s = str;
uchar *d = dest;
int i;
#if LCD_BPP == LCD_MONOCHROME
uchar rest = *d & -(1 << (8-off));
uchar sym;
#endif
for (i=0; i<count; ++i) {
uchar c, bits;
c = *s++;
bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
#if LCD_BPP == LCD_MONOCHROME
sym = (COLOR_MASK(lcd_color_fg) & bits) |
(COLOR_MASK(lcd_color_bg) & ~bits);
*d++ = rest | (sym >> off);
rest = sym << (8-off);
#elif LCD_BPP == LCD_COLOR8
for (c=0; c<8; ++c) {
*d++ = (bits & 0x80) ?
lcd_color_fg : lcd_color_bg;
bits <<= 1;
}
#elif LCD_BPP == LCD_COLOR16
for (c=0; c<16; ++c) {
*d++ = (bits & 0x80) ?
lcd_color_fg : lcd_color_bg;
bits <<= 1;
}
#endif
}
#if LCD_BPP == LCD_MONOCHROME
*d = rest | (*d & ((1 << (8-off)) - 1));
#endif
}
}
/*----------------------------------------------------------------------*/
static inline void lcd_puts_xy (ushort x, ushort y, uchar *s)
{
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen ((char *)s));
#else
lcd_drawchars (x, y, s, strlen ((char *)s));
#endif
}
/*----------------------------------------------------------------------*/
static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
{
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
lcd_drawchars (x, y+BMP_LOGO_HEIGHT, &c, 1);
#else
lcd_drawchars (x, y, &c, 1);
#endif
}
/************************************************************************/
/** Small utility to check that you got the colours right */
/************************************************************************/
#ifdef LCD_TEST_PATTERN
#define N_BLK_VERT 2
#define N_BLK_HOR 3
static int test_colors[N_BLK_HOR*N_BLK_VERT] = {
CONSOLE_COLOR_RED, CONSOLE_COLOR_GREEN, CONSOLE_COLOR_YELLOW,
CONSOLE_COLOR_BLUE, CONSOLE_COLOR_MAGENTA, CONSOLE_COLOR_CYAN,
};
static void test_pattern (void)
{
ushort v_max = panel_info.vl_row;
ushort h_max = panel_info.vl_col;
ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
ushort h_step = (h_max + N_BLK_HOR - 1) / N_BLK_HOR;
ushort v, h;
uchar *pix = (uchar *)lcd_base;
printf ("[LCD] Test Pattern: %d x %d [%d x %d]\n",
h_max, v_max, h_step, v_step);
/* WARNING: Code silently assumes 8bit/pixel */
for (v=0; v<v_max; ++v) {
uchar iy = v / v_step;
for (h=0; h<h_max; ++h) {
uchar ix = N_BLK_HOR * iy + (h/h_step);
*pix++ = test_colors[ix];
}
}
}
#endif /* LCD_TEST_PATTERN */
/************************************************************************/
/* ** GENERIC Initialization Routines */
/************************************************************************/
int drv_lcd_init (void)
{
device_t lcddev;
int rc;
lcd_base = (void *)(gd->fb_base);
lcd_line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
lcd_init (lcd_base); /* LCD initialization */
/* Device initialization */
memset (&lcddev, 0, sizeof (lcddev));
strcpy (lcddev.name, "lcd");
lcddev.ext = 0; /* No extensions */
lcddev.flags = DEV_FLAGS_OUTPUT; /* Output only */
lcddev.putc = lcd_putc; /* 'putc' function */
lcddev.puts = lcd_puts; /* 'puts' function */
rc = device_register (&lcddev);
return (rc == 0) ? 1 : rc;
}
/*----------------------------------------------------------------------*/
static int lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
#if LCD_BPP == LCD_MONOCHROME
/* Setting the palette */
lcd_initcolregs();
#elif LCD_BPP == LCD_COLOR8
/* Setting the palette */
lcd_setcolreg (CONSOLE_COLOR_BLACK, 0, 0, 0);
lcd_setcolreg (CONSOLE_COLOR_RED, 0xFF, 0, 0);
lcd_setcolreg (CONSOLE_COLOR_GREEN, 0, 0xFF, 0);
lcd_setcolreg (CONSOLE_COLOR_YELLOW, 0xFF, 0xFF, 0);
lcd_setcolreg (CONSOLE_COLOR_BLUE, 0, 0, 0xFF);
lcd_setcolreg (CONSOLE_COLOR_MAGENTA, 0xFF, 0, 0xFF);
lcd_setcolreg (CONSOLE_COLOR_CYAN, 0, 0xFF, 0xFF);
lcd_setcolreg (CONSOLE_COLOR_GREY, 0xAA, 0xAA, 0xAA);
lcd_setcolreg (CONSOLE_COLOR_WHITE, 0xFF, 0xFF, 0xFF);
#endif
#ifndef CFG_WHITE_ON_BLACK
lcd_setfgcolor (CONSOLE_COLOR_BLACK);
lcd_setbgcolor (CONSOLE_COLOR_WHITE);
#else
lcd_setfgcolor (CONSOLE_COLOR_WHITE);
lcd_setbgcolor (CONSOLE_COLOR_BLACK);
#endif /* CFG_WHITE_ON_BLACK */
#ifdef LCD_TEST_PATTERN
test_pattern();
#else
/* set framebuffer to background color */
memset ((char *)lcd_base,
COLOR_MASK(lcd_getbgcolor()),
lcd_line_length*panel_info.vl_row);
#endif
/* Paint the logo and retrieve LCD base address */
debug ("[LCD] Drawing the logo...\n");
lcd_console_address = lcd_logo ();
console_col = 0;
console_row = 0;
return (0);
}
U_BOOT_CMD(
cls, 1, 1, lcd_clear,
"cls - clear screen\n",
NULL
);
/*----------------------------------------------------------------------*/
static int lcd_init (void *lcdbase)
{
/* Initialize the lcd controller */
debug ("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
lcd_ctrl_init (lcdbase);
lcd_clear (NULL, 1, 1, NULL); /* dummy args */
lcd_enable ();
/* Initialize the console */
console_col = 0;
#ifdef CONFIG_LCD_INFO_BELOW_LOGO
console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
#else
console_row = 1; /* leave 1 blank line below logo */
#endif
lcd_is_enabled = 1;
return 0;
}
/************************************************************************/
/* ** ROM capable initialization part - needed to reserve FB memory */
/************************************************************************/
/*
* This is called early in the system initialization to grab memory
* for the LCD controller.
* Returns new address for monitor, after reserving LCD buffer memory
*
* Note that this is running from ROM, so no write access to global data.
*/
ulong lcd_setmem (ulong addr)
{
ulong size;
int line_length = (panel_info.vl_col * NBITS (panel_info.vl_bpix)) / 8;
debug ("LCD panel info: %d x %d, %d bit/pix\n",
panel_info.vl_col, panel_info.vl_row, NBITS (panel_info.vl_bpix) );
size = line_length * panel_info.vl_row;
/* Round up to nearest full page */
size = (size + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
/* Allocate pages for the frame buffer. */
addr -= size;
debug ("Reserving %ldk for LCD Framebuffer at: %08lx\n", size>>10, addr);
return (addr);
}
/*----------------------------------------------------------------------*/
static void lcd_setfgcolor (int color)
{
#ifdef CONFIG_ATMEL_LCD
lcd_color_fg = color;
#else
lcd_color_fg = color & 0x0F;
#endif
}
/*----------------------------------------------------------------------*/
static void lcd_setbgcolor (int color)
{
#ifdef CONFIG_ATMEL_LCD
lcd_color_bg = color;
#else
lcd_color_bg = color & 0x0F;
#endif
}
/*----------------------------------------------------------------------*/
#ifdef NOT_USED_SO_FAR
static int lcd_getfgcolor (void)
{
return lcd_color_fg;
}
#endif /* NOT_USED_SO_FAR */
/*----------------------------------------------------------------------*/
static int lcd_getbgcolor (void)
{
return lcd_color_bg;
}
/*----------------------------------------------------------------------*/
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
#ifdef CONFIG_LCD_LOGO
void bitmap_plot (int x, int y)
{
#ifdef CONFIG_ATMEL_LCD
uint *cmap;
#else
ushort *cmap;
#endif
ushort i, j;
uchar *bmap;
uchar *fb;
ushort *fb16;
#if defined(CONFIG_PXA250)
struct pxafb_info *fbi = &panel_info.pxa;
#elif defined(CONFIG_MPC823)
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile cpm8xx_t *cp = &(immr->im_cpm);
#endif
debug ("Logo: width %d height %d colors %d cmap %d\n",
BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS,
sizeof(bmp_logo_palette)/(sizeof(ushort)));
bmap = &bmp_logo_bitmap[0];
fb = (uchar *)(lcd_base + y * lcd_line_length + x);
if (NBITS(panel_info.vl_bpix) < 12) {
/* Leave room for default color map */
#if defined(CONFIG_PXA250)
cmap = (ushort *)fbi->palette;
#elif defined(CONFIG_MPC823)
cmap = (ushort *)&(cp->lcd_cmap[BMP_LOGO_OFFSET*sizeof(ushort)]);
#elif defined(CONFIG_ATMEL_LCD)
cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
#endif
WATCHDOG_RESET();
/* Set color map */
for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
ushort colreg = bmp_logo_palette[i];
#ifdef CONFIG_ATMEL_LCD
uint lut_entry;
#ifdef CONFIG_ATMEL_LCD_BGR555
lut_entry = ((colreg & 0x000F) << 11) |
((colreg & 0x00F0) << 2) |
((colreg & 0x0F00) >> 7);
#else /* CONFIG_ATMEL_LCD_RGB565 */
lut_entry = ((colreg & 0x000F) << 1) |
((colreg & 0x00F0) << 3) |
((colreg & 0x0F00) << 4);
#endif
*(cmap + BMP_LOGO_OFFSET) = lut_entry;
cmap++;
#else /* !CONFIG_ATMEL_LCD */
#ifdef CFG_INVERT_COLORS
*cmap++ = 0xffff - colreg;
#else
*cmap++ = colreg;
#endif
#endif /* CONFIG_ATMEL_LCD */
}
WATCHDOG_RESET();
for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
memcpy (fb, bmap, BMP_LOGO_WIDTH);
bmap += BMP_LOGO_WIDTH;
fb += panel_info.vl_col;
}
}
else { /* true color mode */
fb16 = (ushort *)(lcd_base + y * lcd_line_length + x);
for (i=0; i<BMP_LOGO_HEIGHT; ++i) {
for (j=0; j<BMP_LOGO_WIDTH; j++) {
fb16[j] = bmp_logo_palette[(bmap[j])];
}
bmap += BMP_LOGO_WIDTH;
fb16 += panel_info.vl_col;
}
}
WATCHDOG_RESET();
}
#endif /* CONFIG_LCD_LOGO */
/*----------------------------------------------------------------------*/
#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
/*
* Display the BMP file located at address bmp_image.
* Only uncompressed.
*/
int lcd_display_bitmap(ulong bmp_image, int x, int y)
{
#ifdef CONFIG_ATMEL_LCD
uint *cmap;
#elif !defined(CONFIG_MCC200)
ushort *cmap;
#endif
ushort i, j;
uchar *fb;
bmp_image_t *bmp=(bmp_image_t *)bmp_image;
uchar *bmap;
ushort padded_line;
unsigned long width, height;
unsigned long pwidth = panel_info.vl_col;
unsigned colors,bpix;
unsigned long compression;
#if defined(CONFIG_PXA250)
struct pxafb_info *fbi = &panel_info.pxa;
#elif defined(CONFIG_MPC823)
volatile immap_t *immr = (immap_t *) CFG_IMMR;
volatile cpm8xx_t *cp = &(immr->im_cpm);
#endif
if (!((bmp->header.signature[0]=='B') &&
(bmp->header.signature[1]=='M'))) {
printf ("Error: no valid bmp image at %lx\n", bmp_image);
return 1;
}
width = le32_to_cpu (bmp->header.width);
height = le32_to_cpu (bmp->header.height);
colors = 1<<le16_to_cpu (bmp->header.bit_count);
compression = le32_to_cpu (bmp->header.compression);
bpix = NBITS(panel_info.vl_bpix);
if ((bpix != 1) && (bpix != 8)) {
printf ("Error: %d bit/pixel mode not supported by U-Boot\n",
bpix);
return 1;
}
if (bpix != le16_to_cpu(bmp->header.bit_count)) {
printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
bpix,
le16_to_cpu(bmp->header.bit_count));
return 1;
}
debug ("Display-bmp: %d x %d with %d colors\n",
(int)width, (int)height, (int)colors);
#if !defined(CONFIG_MCC200)
/* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */
if (bpix==8) {
#if defined(CONFIG_PXA250)
cmap = (ushort *)fbi->palette;
#elif defined(CONFIG_MPC823)
cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
#elif defined(CONFIG_ATMEL_LCD)
cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0));
#else
# error "Don't know location of color map"
#endif
/* Set color map */
for (i=0; i<colors; ++i) {
bmp_color_table_entry_t cte = bmp->color_table[i];
ushort colreg =
( ((cte.red) << 8) & 0xf800) |
( ((cte.green) << 3) & 0x07e0) |
( ((cte.blue) >> 3) & 0x001f) ;
#ifdef CFG_INVERT_COLORS
*cmap = 0xffff - colreg;
#else
*cmap = colreg;
#endif
#if defined(CONFIG_PXA250)
cmap++;
#elif defined(CONFIG_MPC823)
cmap--;
#endif
}
}
#endif
/*
* BMP format for Monochrome assumes that the state of a
* pixel is described on a per Bit basis, not per Byte.
* So, in case of Monochrome BMP we should align widths
* on a byte boundary and convert them from Bit to Byte
* units.
* Probably, PXA250 and MPC823 process 1bpp BMP images in
* their own ways, so make the converting to be MCC200
* specific.
*/
#if defined(CONFIG_MCC200)
if (bpix==1)
{
width = ((width + 7) & ~7) >> 3;
x = ((x + 7) & ~7) >> 3;
pwidth= ((pwidth + 7) & ~7) >> 3;
}
#endif
padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);
if ((x + width)>pwidth)
width = pwidth - x;
if ((y + height)>panel_info.vl_row)
height = panel_info.vl_row - y;
bmap = (uchar *)bmp + le32_to_cpu (bmp->header.data_offset);
fb = (uchar *) (lcd_base +
(y + height - 1) * lcd_line_length + x);
for (i = 0; i < height; ++i) {
WATCHDOG_RESET();
for (j = 0; j < width ; j++)
#if defined(CONFIG_PXA250)
*(fb++)=*(bmap++);
#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200)
*(fb++)=255-*(bmap++);
#endif
bmap += (width - padded_line);
fb -= (width + lcd_line_length);
}
return (0);
}
#endif
static void *lcd_logo (void)
{
#ifdef CONFIG_LCD_INFO
char info[80];
char temp[32];
#ifdef CONFIG_ATMEL_LCD
int i;
ulong dram_size, nand_size;
#endif
#endif /* CONFIG_LCD_INFO */
#ifdef CONFIG_SPLASH_SCREEN
char *s;
ulong addr;
static int do_splash = 1;
if (do_splash && (s = getenv("splashimage")) != NULL) {
addr = simple_strtoul(s, NULL, 16);
do_splash = 0;
if (lcd_display_bitmap (addr, 0, 0) == 0) {
return ((void *)lcd_base);
}
}
#endif /* CONFIG_SPLASH_SCREEN */
#ifdef CONFIG_LCD_LOGO
bitmap_plot (0, 0);
#endif /* CONFIG_LCD_LOGO */
#ifdef CONFIG_MPC823
# ifdef CONFIG_LCD_INFO
sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__);
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, (uchar *)info, strlen(info));
sprintf (info, "(C) 2004 DENX Software Engineering");
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT,
(uchar *)info, strlen(info));
sprintf (info, " Wolfgang DENK, wd@denx.de");
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2,
(uchar *)info, strlen(info));
# ifdef CONFIG_LCD_INFO_BELOW_LOGO
sprintf (info, "MPC823 CPU at %s MHz",
strmhz(temp, gd->cpu_clk));
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3,
info, strlen(info));
sprintf (info, " %ld MB RAM, %ld MB Flash",
gd->ram_size >> 20,
gd->bd->bi_flashsize >> 20 );
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
info, strlen(info));
# else
/* leave one blank line */
sprintf (info, "MPC823 CPU at %s MHz, %ld MB RAM, %ld MB Flash",
strmhz(temp, gd->cpu_clk),
gd->ram_size >> 20,
gd->bd->bi_flashsize >> 20 );
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
(uchar *)info, strlen(info));
# endif /* CONFIG_LCD_INFO_BELOW_LOGO */
# endif /* CONFIG_LCD_INFO */
#endif /* CONFIG_MPC823 */
#ifdef CONFIG_ATMEL_LCD
# ifdef CONFIG_LCD_INFO
sprintf (info, "%s", U_BOOT_VERSION);
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, (uchar *)info, strlen(info));
sprintf (info, "(C) 2008 ATMEL Corp");
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT,
(uchar *)info, strlen(info));
sprintf (info, "at91support@atmel.com");
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2,
(uchar *)info, strlen(info));
sprintf (info, "%s CPU at %s MHz",
AT91_CPU_NAME,
strmhz(temp, AT91_MAIN_CLOCK));
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 3,
(uchar *)info, strlen(info));
dram_size = 0;
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
dram_size += gd->bd->bi_dram[i].size;
nand_size = 0;
for (i = 0; i < CFG_MAX_NAND_DEVICE; i++)
nand_size += nand_info[i].size;
sprintf (info, " %ld MB SDRAM, %ld MB NAND",
dram_size >> 20,
nand_size >> 20 );
lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 4,
(uchar *)info, strlen(info));
# endif /* CONFIG_LCD_INFO */
#endif /* CONFIG_ATMEL_LCD */
#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
#else
return ((void *)lcd_base);
#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
}
/************************************************************************/
/************************************************************************/
#endif /* CONFIG_LCD */