* Clean up tools/bmp_logo.c to not add trailing white space

* Patch by Hinko Kocevar, 21 Aug 2004:
  - Group common framebuffer functions in common/lcd.c
  - Group common framebuffer macros and #defines in include/lcd.h
  - Provide calc_fbsize() for video ATAG
diff --git a/common/Makefile b/common/Makefile
index 943da5e..7d92cab 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -27,7 +27,7 @@
 
 AOBJS	=
 
-COBJS	= main.o ACEX1K.o altera.o bedbug.o \
+COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o \
 	  cmd_ace.o cmd_autoscript.o \
 	  cmd_bdinfo.o cmd_bedbug.o cmd_bmp.o cmd_boot.o cmd_bootm.o \
 	  cmd_cache.o cmd_console.o \
@@ -44,10 +44,11 @@
 	  environment.o env_common.o \
 	  env_nand.o env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
 	  flash.o fpga.o \
-	  hush.o kgdb.o lists.o lynxkdi.o memsize.o miiphybb.o miiphyutil.o \
+	  hush.o kgdb.o lcd.o lists.o lynxkdi.o \
+	  memsize.o miiphybb.o miiphyutil.o \
 	  s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o \
 	  usb.o usb_kbd.o usb_storage.o \
-	  virtex2.o xilinx.o circbuf.o
+	  virtex2.o xilinx.o
 
 OBJS	= $(AOBJS) $(COBJS)
 
diff --git a/common/cmd_bmp.c b/common/cmd_bmp.c
index 3a97133..daa54e7 100644
--- a/common/cmd_bmp.c
+++ b/common/cmd_bmp.c
@@ -28,6 +28,7 @@
 #include <common.h>
 #include <bmp_layout.h>
 #include <command.h>
+#include <asm/byteorder.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_BMP)
 
diff --git a/common/lcd.c b/common/lcd.c
new file mode 100644
index 0000000..85b44ca
--- /dev/null
+++ b/common/lcd.c
@@ -0,0 +1,740 @@
+/*
+ * 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>
+
+#if defined(CONFIG_PXA250)
+#include <asm/byteorder.h>
+#endif
+
+#if defined(CONFIG_MPC823)
+#include <watchdog.h>
+#include <lcdvideo.h>
+#endif
+
+
+#ifdef CONFIG_LCD
+
+/************************************************************************/
+/* ** FONT DATA								*/
+/************************************************************************/
+#include <video_font.h>		/* Get font data, width and height	*/
+
+
+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(LCD_INFO_BELOW_LOGO)
+	lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen (s));
+#else
+	lcd_drawchars (x, y, s, strlen (s));
+#endif
+}
+
+/*----------------------------------------------------------------------*/
+
+static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
+{
+#if defined(CONFIG_LCD_LOGO) && !defined(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)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	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 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)
+{
+	lcd_color_fg = color & 0x0F;
+}
+
+/*----------------------------------------------------------------------*/
+
+static void lcd_setbgcolor (int color)
+{
+	lcd_color_bg = color & 0x0F;
+}
+
+/*----------------------------------------------------------------------*/
+
+#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)
+{
+	ushort *cmap;
+	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   = (char *)(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)]);
+#endif
+
+		WATCHDOG_RESET();
+
+		/* Set color map */
+		for (i=0; i<(sizeof(bmp_logo_palette)/(sizeof(ushort))); ++i) {
+			ushort colreg = bmp_logo_palette[i];
+#ifdef  CFG_INVERT_COLORS
+			*cmap++ = 0xffff - colreg;
+#else
+			*cmap++ = colreg;
+#endif
+		}
+
+		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 (CONFIG_COMMANDS & CFG_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)
+{
+	ushort *cmap;
+	ushort i, j;
+	uchar *fb;
+	bmp_image_t *bmp=(bmp_image_t *)bmp_image;
+	uchar *bmap;
+	ushort padded_line;
+	unsigned long width, height;
+	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 (bpix==8) {
+#if defined(CONFIG_PXA250)
+		cmap = (ushort *)fbi->palette;
+#elif defined(CONFIG_MPC823)
+		cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]);
+#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) << 4) & 0x07e0) |
+				( (cte.blue) & 0x001f) ;
+
+#ifdef CFG_INVERT_COLORS
+			*cmap++ = 0xffff - colreg;
+#else
+			*cmap++ = colreg;
+#endif
+		}
+	}
+
+	padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);
+	if ((x + width)>panel_info.vl_col)
+		width = panel_info.vl_col - 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) {
+		for (j = 0; j < width ; j++)
+#if defined(CONFIG_PXA250)
+			*(fb++)=*(bmap++);
+#elif defined(CONFIG_MPC823)
+			*(fb++)=255-*(bmap++);
+#endif
+		bmap += (width - padded_line);
+		fb   -= (width + lcd_line_length);
+	}
+
+	return (0);
+}
+#endif /* (CONFIG_COMMANDS & CFG_CMD_BMP) || CONFIG_SPLASH_SCREEN */
+
+
+static void *lcd_logo (void)
+{
+#ifdef LCD_INFO
+	DECLARE_GLOBAL_DATA_PTR;
+
+	char info[80];
+	char temp[32];
+#endif /* 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 LCD_INFO
+	sprintf (info, "%s (%s - %s) ", U_BOOT_VERSION, __DATE__, __TIME__);
+	lcd_drawchars (LCD_INFO_X, LCD_INFO_Y, info, strlen(info));
+
+	sprintf (info, "(C) 2004 DENX Software Engineering");
+	lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT,
+					info, strlen(info));
+
+	sprintf (info, "    Wolfgang DENK, wd@denx.de");
+	lcd_drawchars (LCD_INFO_X, LCD_INFO_Y + VIDEO_FONT_HEIGHT * 2,
+					info, strlen(info));
+#ifdef 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,
+					info, strlen(info));
+
+#endif /* CONFIG_MPC823 */
+#endif /* LCD_INFO_BELOW_LOGO */
+#endif /* LCD_INFO */
+
+#if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)
+	return ((void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length));
+#else
+	return ((void *)lcd_base);
+#endif /* CONFIG_LCD_LOGO */
+}
+
+/************************************************************************/
+/************************************************************************/
+
+#endif /* CONFIG_LCD */