drivers/video : move video drivers to drivers/video

Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
new file mode 100644
index 0000000..36611ec
--- /dev/null
+++ b/drivers/video/Makefile
@@ -0,0 +1,53 @@
+#
+# (C) Copyright 2000-2007
+# 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB 	:= $(obj)libvideo.a
+
+COBJS-y += ati_radeon_fb.o
+COBJS-y += cfb_console.o
+COBJS-y += ct69000.o
+COBJS-y += sed13806.o
+COBJS-y += sed156x.o
+COBJS-y += sm501.o
+COBJS-y += smiLynxEM.o
+COBJS-y += videomodes.o
+
+COBJS	:= $(COBJS-y)
+SRCS 	:= $(COBJS:.o=.c)
+OBJS 	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/video/ati_ids.h b/drivers/video/ati_ids.h
new file mode 100644
index 0000000..3e72a7d
--- /dev/null
+++ b/drivers/video/ati_ids.h
@@ -0,0 +1,211 @@
+/*
+ * ATI PCI IDs from XFree86, kept here to make sync'ing with
+ * XFree much simpler. Currently, this list is only used by
+ * radeonfb
+ */
+
+#define PCI_CHIP_RV380_3150             0x3150
+#define PCI_CHIP_RV380_3151             0x3151
+#define PCI_CHIP_RV380_3152             0x3152
+#define PCI_CHIP_RV380_3153             0x3153
+#define PCI_CHIP_RV380_3154             0x3154
+#define PCI_CHIP_RV380_3156             0x3156
+#define PCI_CHIP_RV380_3E50             0x3E50
+#define PCI_CHIP_RV380_3E51             0x3E51
+#define PCI_CHIP_RV380_3E52             0x3E52
+#define PCI_CHIP_RV380_3E53             0x3E53
+#define PCI_CHIP_RV380_3E54             0x3E54
+#define PCI_CHIP_RV380_3E56             0x3E56
+#define PCI_CHIP_RS100_4136		0x4136
+#define PCI_CHIP_RS200_4137		0x4137
+#define PCI_CHIP_R300_AD		0x4144
+#define PCI_CHIP_R300_AE		0x4145
+#define PCI_CHIP_R300_AF		0x4146
+#define PCI_CHIP_R300_AG		0x4147
+#define PCI_CHIP_R350_AH                0x4148
+#define PCI_CHIP_R350_AI                0x4149
+#define PCI_CHIP_R350_AJ                0x414A
+#define PCI_CHIP_R350_AK                0x414B
+#define PCI_CHIP_RV350_AP               0x4150
+#define PCI_CHIP_RV350_AQ               0x4151
+#define PCI_CHIP_RV360_AR               0x4152
+#define PCI_CHIP_RV350_AS               0x4153
+#define PCI_CHIP_RV350_AT               0x4154
+#define PCI_CHIP_RV350_AV               0x4156
+#define PCI_CHIP_MACH32		0x4158
+#define PCI_CHIP_RS250_4237		0x4237
+#define PCI_CHIP_R200_BB		0x4242
+#define PCI_CHIP_R200_BC		0x4243
+#define PCI_CHIP_RS100_4336		0x4336
+#define PCI_CHIP_RS200_4337		0x4337
+#define PCI_CHIP_MACH64CT		0x4354
+#define PCI_CHIP_MACH64CX		0x4358
+#define PCI_CHIP_RS250_4437		0x4437
+#define PCI_CHIP_MACH64ET		0x4554
+#define PCI_CHIP_MACH64GB		0x4742
+#define PCI_CHIP_MACH64GD		0x4744
+#define PCI_CHIP_MACH64GI		0x4749
+#define PCI_CHIP_MACH64GL		0x474C
+#define PCI_CHIP_MACH64GM		0x474D
+#define PCI_CHIP_MACH64GN		0x474E
+#define PCI_CHIP_MACH64GO		0x474F
+#define PCI_CHIP_MACH64GP		0x4750
+#define PCI_CHIP_MACH64GQ		0x4751
+#define PCI_CHIP_MACH64GR		0x4752
+#define PCI_CHIP_MACH64GS		0x4753
+#define PCI_CHIP_MACH64GT		0x4754
+#define PCI_CHIP_MACH64GU		0x4755
+#define PCI_CHIP_MACH64GV		0x4756
+#define PCI_CHIP_MACH64GW		0x4757
+#define PCI_CHIP_MACH64GX		0x4758
+#define PCI_CHIP_MACH64GY		0x4759
+#define PCI_CHIP_MACH64GZ		0x475A
+#define PCI_CHIP_RV250_Id		0x4964
+#define PCI_CHIP_RV250_Ie		0x4965
+#define PCI_CHIP_RV250_If		0x4966
+#define PCI_CHIP_RV250_Ig		0x4967
+#define PCI_CHIP_R420_JH                0x4A48
+#define PCI_CHIP_R420_JI                0x4A49
+#define PCI_CHIP_R420_JJ                0x4A4A
+#define PCI_CHIP_R420_JK                0x4A4B
+#define PCI_CHIP_R420_JL                0x4A4C
+#define PCI_CHIP_R420_JM                0x4A4D
+#define PCI_CHIP_R420_JN                0x4A4E
+#define PCI_CHIP_R420_JP                0x4A50
+#define PCI_CHIP_MACH64LB		0x4C42
+#define PCI_CHIP_MACH64LD		0x4C44
+#define PCI_CHIP_RAGE128LE		0x4C45
+#define PCI_CHIP_RAGE128LF		0x4C46
+#define PCI_CHIP_MACH64LG		0x4C47
+#define PCI_CHIP_MACH64LI		0x4C49
+#define PCI_CHIP_MACH64LM		0x4C4D
+#define PCI_CHIP_MACH64LN		0x4C4E
+#define PCI_CHIP_MACH64LP		0x4C50
+#define PCI_CHIP_MACH64LQ		0x4C51
+#define PCI_CHIP_MACH64LR		0x4C52
+#define PCI_CHIP_MACH64LS		0x4C53
+#define PCI_CHIP_MACH64LT		0x4C54
+#define PCI_CHIP_RADEON_LW		0x4C57
+#define PCI_CHIP_RADEON_LX		0x4C58
+#define PCI_CHIP_RADEON_LY		0x4C59
+#define PCI_CHIP_RADEON_LZ		0x4C5A
+#define PCI_CHIP_RV250_Ld		0x4C64
+#define PCI_CHIP_RV250_Le		0x4C65
+#define PCI_CHIP_RV250_Lf		0x4C66
+#define PCI_CHIP_RV250_Lg		0x4C67
+#define PCI_CHIP_RV250_Ln		0x4C6E
+#define PCI_CHIP_RAGE128MF		0x4D46
+#define PCI_CHIP_RAGE128ML		0x4D4C
+#define PCI_CHIP_R300_ND		0x4E44
+#define PCI_CHIP_R300_NE		0x4E45
+#define PCI_CHIP_R300_NF		0x4E46
+#define PCI_CHIP_R300_NG		0x4E47
+#define PCI_CHIP_R350_NH                0x4E48
+#define PCI_CHIP_R350_NI                0x4E49
+#define PCI_CHIP_R360_NJ                0x4E4A
+#define PCI_CHIP_R350_NK                0x4E4B
+#define PCI_CHIP_RV350_NP               0x4E50
+#define PCI_CHIP_RV350_NQ               0x4E51
+#define PCI_CHIP_RV350_NR               0x4E52
+#define PCI_CHIP_RV350_NS               0x4E53
+#define PCI_CHIP_RV350_NT               0x4E54
+#define PCI_CHIP_RV350_NV               0x4E56
+#define PCI_CHIP_RAGE128PA		0x5041
+#define PCI_CHIP_RAGE128PB		0x5042
+#define PCI_CHIP_RAGE128PC		0x5043
+#define PCI_CHIP_RAGE128PD		0x5044
+#define PCI_CHIP_RAGE128PE		0x5045
+#define PCI_CHIP_RAGE128PF		0x5046
+#define PCI_CHIP_RAGE128PG		0x5047
+#define PCI_CHIP_RAGE128PH		0x5048
+#define PCI_CHIP_RAGE128PI		0x5049
+#define PCI_CHIP_RAGE128PJ		0x504A
+#define PCI_CHIP_RAGE128PK		0x504B
+#define PCI_CHIP_RAGE128PL		0x504C
+#define PCI_CHIP_RAGE128PM		0x504D
+#define PCI_CHIP_RAGE128PN		0x504E
+#define PCI_CHIP_RAGE128PO		0x504F
+#define PCI_CHIP_RAGE128PP		0x5050
+#define PCI_CHIP_RAGE128PQ		0x5051
+#define PCI_CHIP_RAGE128PR		0x5052
+#define PCI_CHIP_RAGE128PS		0x5053
+#define PCI_CHIP_RAGE128PT		0x5054
+#define PCI_CHIP_RAGE128PU		0x5055
+#define PCI_CHIP_RAGE128PV		0x5056
+#define PCI_CHIP_RAGE128PW		0x5057
+#define PCI_CHIP_RAGE128PX		0x5058
+#define PCI_CHIP_RADEON_QD		0x5144
+#define PCI_CHIP_RADEON_QE		0x5145
+#define PCI_CHIP_RADEON_QF		0x5146
+#define PCI_CHIP_RADEON_QG		0x5147
+#define PCI_CHIP_R200_QH		0x5148
+#define PCI_CHIP_R200_QI		0x5149
+#define PCI_CHIP_R200_QJ		0x514A
+#define PCI_CHIP_R200_QK		0x514B
+#define PCI_CHIP_R200_QL		0x514C
+#define PCI_CHIP_R200_QM		0x514D
+#define PCI_CHIP_R200_QN		0x514E
+#define PCI_CHIP_R200_QO		0x514F
+#define PCI_CHIP_RV200_QW		0x5157
+#define PCI_CHIP_RV200_QX		0x5158
+#define PCI_CHIP_RV100_QY		0x5159
+#define PCI_CHIP_RV100_QZ		0x515A
+#define PCI_CHIP_RN50			0x515E
+#define PCI_CHIP_RAGE128RE		0x5245
+#define PCI_CHIP_RAGE128RF		0x5246
+#define PCI_CHIP_RAGE128RG		0x5247
+#define PCI_CHIP_RAGE128RK		0x524B
+#define PCI_CHIP_RAGE128RL		0x524C
+#define PCI_CHIP_RAGE128SE		0x5345
+#define PCI_CHIP_RAGE128SF		0x5346
+#define PCI_CHIP_RAGE128SG		0x5347
+#define PCI_CHIP_RAGE128SH		0x5348
+#define PCI_CHIP_RAGE128SK		0x534B
+#define PCI_CHIP_RAGE128SL		0x534C
+#define PCI_CHIP_RAGE128SM		0x534D
+#define PCI_CHIP_RAGE128SN		0x534E
+#define PCI_CHIP_RAGE128TF		0x5446
+#define PCI_CHIP_RAGE128TL		0x544C
+#define PCI_CHIP_RAGE128TR		0x5452
+#define PCI_CHIP_RAGE128TS		0x5453
+#define PCI_CHIP_RAGE128TT		0x5454
+#define PCI_CHIP_RAGE128TU		0x5455
+#define PCI_CHIP_RV370_5460             0x5460
+#define PCI_CHIP_RV370_5461             0x5461
+#define PCI_CHIP_RV370_5462             0x5462
+#define PCI_CHIP_RV370_5463             0x5463
+#define PCI_CHIP_RV370_5464             0x5464
+#define PCI_CHIP_RV370_5465             0x5465
+#define PCI_CHIP_RV370_5466             0x5466
+#define PCI_CHIP_RV370_5467             0x5467
+#define PCI_CHIP_R423_UH                0x5548
+#define PCI_CHIP_R423_UI                0x5549
+#define PCI_CHIP_R423_UJ                0x554A
+#define PCI_CHIP_R423_UK                0x554B
+#define PCI_CHIP_R423_UQ                0x5551
+#define PCI_CHIP_R423_UR                0x5552
+#define PCI_CHIP_R423_UT                0x5554
+#define PCI_CHIP_MACH64VT		0x5654
+#define PCI_CHIP_MACH64VU		0x5655
+#define PCI_CHIP_MACH64VV		0x5656
+#define PCI_CHIP_RS300_5834		0x5834
+#define PCI_CHIP_RS300_5835		0x5835
+#define PCI_CHIP_RS300_5836		0x5836
+#define PCI_CHIP_RS300_5837		0x5837
+#define PCI_CHIP_RV370_5B60             0x5B60
+#define PCI_CHIP_RV370_5B61             0x5B61
+#define PCI_CHIP_RV370_5B62             0x5B62
+#define PCI_CHIP_RV370_5B63             0x5B63
+#define PCI_CHIP_RV370_5B64             0x5B64
+#define PCI_CHIP_RV370_5B65             0x5B65
+#define PCI_CHIP_RV370_5B66             0x5B66
+#define PCI_CHIP_RV370_5B67             0x5B67
+#define PCI_CHIP_RV280_5960		0x5960
+#define PCI_CHIP_RV280_5961		0x5961
+#define PCI_CHIP_RV280_5962		0x5962
+#define PCI_CHIP_RV280_5964		0x5964
+#define PCI_CHIP_RV280_5C61		0x5C61
+#define PCI_CHIP_RV280_5C63		0x5C63
+#define PCI_CHIP_R423_5D57              0x5D57
+#define PCI_CHIP_RS350_7834             0x7834
+#define PCI_CHIP_RS350_7835             0x7835
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c
new file mode 100644
index 0000000..0bdaa1c
--- /dev/null
+++ b/drivers/video/ati_radeon_fb.c
@@ -0,0 +1,488 @@
+/*
+ * ATI Radeon Video card Framebuffer driver.
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc.
+ * Zhang Wei <wei.zhang@freescale.com>
+ * Jason Jin <jason.jin@freescale.com>
+ *
+ * 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
+ *
+ * Some codes of this file is partly ported from Linux kernel
+ * ATI video framebuffer driver.
+ *
+ * Now the driver is tested on below ATI chips:
+ *   9200
+ *   X300
+ *   X700
+ *
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_ATI_RADEON_FB
+
+#include <command.h>
+#include <pci.h>
+#include <asm/processor.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <video_fb.h>
+
+#include <radeon.h>
+#include "ati_ids.h"
+#include "ati_radeon_fb.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DPRINT(x...) printf(x)
+#else
+#define DPRINT(x...) do{}while(0)
+#endif
+
+#ifndef min_t
+#define min_t(type,x,y) \
+	({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#endif
+
+#define MAX_MAPPED_VRAM	(2048*2048*4)
+#define MIN_MAPPED_VRAM	(1024*768*1)
+
+/*#define PCI_VENDOR_ID_ATI*/
+#define PCI_CHIP_RV280_5960		0x5960
+#define PCI_CHIP_RV280_5961		0x5961
+#define PCI_CHIP_RV280_5962		0x5962
+#define PCI_CHIP_RV280_5964		0x5964
+#define PCI_CHIP_RV370_5B60		0x5B60
+#define PCI_CHIP_RV380_5657		0x5657
+#define PCI_CHIP_R420_554d		0x554d
+
+static struct pci_device_id ati_radeon_pci_ids[] = {
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657},
+	{PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d},
+	{0, 0}
+};
+
+static u16 ati_radeon_id_family_table[][2] = {
+	{PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280},
+	{PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280},
+	{PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280},
+	{PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280},
+	{PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380},
+	{PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380},
+	{PCI_CHIP_R420_554d,  CHIP_FAMILY_R420},
+	{0, 0}
+};
+
+u16 get_radeon_id_family(u16 device)
+{
+	int i;
+	for (i=0; ati_radeon_id_family_table[0][i]; i+=2)
+		if (ati_radeon_id_family_table[0][i] == device)
+			return ati_radeon_id_family_table[0][i + 1];
+	return 0;
+}
+
+struct radeonfb_info *rinfo;
+
+static void radeon_identify_vram(struct radeonfb_info *rinfo)
+{
+	u32 tmp;
+
+	/* framebuffer size */
+	if ((rinfo->family == CHIP_FAMILY_RS100) ||
+		(rinfo->family == CHIP_FAMILY_RS200) ||
+		(rinfo->family == CHIP_FAMILY_RS300)) {
+		u32 tom = INREG(NB_TOM);
+		tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
+
+		radeon_fifo_wait(6);
+		OUTREG(MC_FB_LOCATION, tom);
+		OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
+		OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16);
+
+		/* This is supposed to fix the crtc2 noise problem. */
+		OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000);
+
+		if ((rinfo->family == CHIP_FAMILY_RS100) ||
+			(rinfo->family == CHIP_FAMILY_RS200)) {
+		/* This is to workaround the asic bug for RMX, some versions
+		   of BIOS dosen't have this register initialized correctly.
+		*/
+			OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN,
+				~CRTC_H_CUTOFF_ACTIVE_EN);
+		}
+	} else {
+		tmp = INREG(CONFIG_MEMSIZE);
+	}
+
+	/* mem size is bits [28:0], mask off the rest */
+	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+	/*
+	 * Hack to get around some busted production M6's
+	 * reporting no ram
+	 */
+	if (rinfo->video_ram == 0) {
+		switch (rinfo->pdev.device) {
+		case PCI_CHIP_RADEON_LY:
+		case PCI_CHIP_RADEON_LZ:
+			rinfo->video_ram = 8192 * 1024;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/*
+	 * Now try to identify VRAM type
+	 */
+	if ((rinfo->family >= CHIP_FAMILY_R300) ||
+	    (INREG(MEM_SDRAM_MODE_REG) & (1<<30)))
+		rinfo->vram_ddr = 1;
+	else
+		rinfo->vram_ddr = 0;
+
+	tmp = INREG(MEM_CNTL);
+	if (IS_R300_VARIANT(rinfo)) {
+		tmp &=  R300_MEM_NUM_CHANNELS_MASK;
+		switch (tmp) {
+		case 0:  rinfo->vram_width = 64; break;
+		case 1:  rinfo->vram_width = 128; break;
+		case 2:  rinfo->vram_width = 256; break;
+		default: rinfo->vram_width = 128; break;
+		}
+	} else if ((rinfo->family == CHIP_FAMILY_RV100) ||
+		   (rinfo->family == CHIP_FAMILY_RS100) ||
+		   (rinfo->family == CHIP_FAMILY_RS200)){
+		if (tmp & RV100_MEM_HALF_MODE)
+			rinfo->vram_width = 32;
+		else
+			rinfo->vram_width = 64;
+	} else {
+		if (tmp & MEM_NUM_CHANNELS_MASK)
+			rinfo->vram_width = 128;
+		else
+			rinfo->vram_width = 64;
+	}
+
+	/* This may not be correct, as some cards can have half of channel disabled
+	 * ToDo: identify these cases
+	 */
+
+	DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
+	       rinfo->video_ram / 1024,
+	       rinfo->vram_ddr ? "DDR" : "SDRAM",
+	       rinfo->vram_width);
+
+}
+
+static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
+{
+	int i;
+
+	radeon_fifo_wait(20);
+
+#if 0
+	/* Workaround from XFree */
+	if (rinfo->is_mobility) {
+		/* A temporal workaround for the occational blanking on certain laptop
+		 * panels. This appears to related to the PLL divider registers
+		 * (fail to lock?). It occurs even when all dividers are the same
+		 * with their old settings. In this case we really don't need to
+		 * fiddle with PLL registers. By doing this we can avoid the blanking
+		 * problem with some panels.
+		 */
+		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
+		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
+					  (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) {
+			/* We still have to force a switch to selected PPLL div thanks to
+			 * an XFree86 driver bug which will switch it away in some cases
+			 * even when using UseFDev */
+			OUTREGP(CLOCK_CNTL_INDEX,
+				mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+				~PPLL_DIV_SEL_MASK);
+			radeon_pll_errata_after_index(rinfo);
+			radeon_pll_errata_after_data(rinfo);
+			return;
+		}
+	}
+#endif
+	if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return;
+
+	/* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
+	OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
+
+	/* Reset PPLL & enable atomic update */
+	OUTPLLP(PPLL_CNTL,
+		PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
+		~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
+
+	/* Switch to selected PPLL divider */
+	OUTREGP(CLOCK_CNTL_INDEX,
+		mode->clk_cntl_index & PPLL_DIV_SEL_MASK,
+		~PPLL_DIV_SEL_MASK);
+
+	/* Set PPLL ref. div */
+	if (rinfo->family == CHIP_FAMILY_R300 ||
+	    rinfo->family == CHIP_FAMILY_RS300 ||
+	    rinfo->family == CHIP_FAMILY_R350 ||
+	    rinfo->family == CHIP_FAMILY_RV350) {
+		if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
+			/* When restoring console mode, use saved PPLL_REF_DIV
+			 * setting.
+			 */
+			OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
+		} else {
+			/* R300 uses ref_div_acc field as real ref divider */
+			OUTPLLP(PPLL_REF_DIV,
+				(mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
+				~R300_PPLL_REF_DIV_ACC_MASK);
+		}
+	} else
+		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+
+	/* Set PPLL divider 3 & post divider*/
+	OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+	OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+
+	/* Write update */
+	while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R)
+		;
+	OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
+
+	/* Wait read update complete */
+	/* FIXME: Certain revisions of R300 can't recover here.  Not sure of
+	   the cause yet, but this workaround will mask the problem for now.
+	   Other chips usually will pass at the very first test, so the
+	   workaround shouldn't have any effect on them. */
+	for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++)
+		;
+
+	OUTPLL(HTOTAL_CNTL, 0);
+
+	/* Clear reset & atomic update */
+	OUTPLLP(PPLL_CNTL, 0,
+		~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
+
+	/* We may want some locking ... oh well */
+	udelay(5000);
+
+	/* Switch back VCLK source to PPLL */
+	OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
+}
+
+typedef struct {
+	u16 reg;
+	u32 val;
+} reg_val;
+
+#if 0	/* unused ? -> scheduled for removal */
+/* these common regs are cleared before mode setting so they do not
+ * interfere with anything
+ */
+static reg_val common_regs[] = {
+	{ OVR_CLR, 0 },
+	{ OVR_WID_LEFT_RIGHT, 0 },
+	{ OVR_WID_TOP_BOTTOM, 0 },
+	{ OV0_SCALE_CNTL, 0 },
+	{ SUBPIC_CNTL, 0 },
+	{ VIPH_CONTROL, 0 },
+	{ I2C_CNTL_1, 0 },
+	{ GEN_INT_CNTL, 0 },
+	{ CAP0_TRIG_CNTL, 0 },
+	{ CAP1_TRIG_CNTL, 0 },
+};
+#endif /* 0 */
+
+void radeon_setmode(void)
+{
+	struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
+
+	mode->crtc_gen_cntl = 0x03000200;
+	mode->crtc_ext_cntl = 0x00008048;
+	mode->dac_cntl = 0xff002100;
+	mode->crtc_h_total_disp = 0x4f0063;
+	mode->crtc_h_sync_strt_wid = 0x8c02a2;
+	mode->crtc_v_total_disp = 0x01df020c;
+	mode->crtc_v_sync_strt_wid = 0x8201ea;
+	mode->crtc_pitch = 0x00500050;
+
+	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+		~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS));
+	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+	OUTREG(CRTC_OFFSET, 0);
+	OUTREG(CRTC_OFFSET_CNTL, 0);
+	OUTREG(CRTC_PITCH, mode->crtc_pitch);
+
+	mode->clk_cntl_index = 0x300;
+	mode->ppll_ref_div = 0xc;
+	mode->ppll_div_3 = 0x00030059;
+
+	radeon_write_pll_regs(rinfo, mode);
+}
+
+#include "../bios_emulator/include/biosemu.h"
+extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
+
+int radeon_probe(struct radeonfb_info *rinfo)
+{
+	pci_dev_t pdev;
+	u16 did;
+
+	pdev = pci_find_devices(ati_radeon_pci_ids, 0);
+
+	if (pdev != -1) {
+		pci_read_config_word(pdev, PCI_DEVICE_ID, &did);
+		printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n",
+				PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff,
+				(pdev >> 11) & 0x1f, (pdev >> 8) & 0x7);
+
+		strcpy(rinfo->name, "ATI Radeon");
+		rinfo->pdev.vendor = PCI_VENDOR_ID_ATI;
+		rinfo->pdev.device = did;
+		rinfo->family = get_radeon_id_family(rinfo->pdev.device);
+		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
+				&rinfo->fb_base_phys);
+		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
+				&rinfo->mmio_base_phys);
+		rinfo->fb_base_phys &= 0xfffff000;
+		rinfo->mmio_base_phys &= ~0x04;
+
+		rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
+		DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
+		rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+		DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
+		/* PostBIOS with x86 emulater */
+		BootVideoCardBIOS(pdev, NULL, 0);
+
+		/*
+		 * Check for errata
+		 * (These will be added in the future for the chipfamily
+		 * R300, RV200, RS200, RV100, RS100.)
+		 */
+
+		/* Get VRAM size and type */
+		radeon_identify_vram(rinfo);
+
+		rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
+				rinfo->video_ram);
+		rinfo->fb_base = (void *)rinfo->fb_base_phys;
+
+		DPRINT("Radeon: framebuffer base phy address 0x%08x," \
+		      "MMIO base phy address 0x%08x," \
+		      "framebuffer local base 0x%08x.\n ",
+		      rinfo->fb_base_phys, rinfo->mmio_base_phys,
+		      rinfo->fb_local_base);
+
+		return 0;
+	}
+	return -1;
+}
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+#define CURSOR_SIZE	0x1000	/* in KByte for HW Cursor */
+#define PATTERN_ADR	(pGD->dprBase + CURSOR_SIZE)	/* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE	8*8*4	/* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY	(CURSOR_SIZE + PATTERN_SIZE)	/* reserved Memory for BITBlt and hw cursor */
+
+void *video_hw_init(void)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	int i;
+	u32 *vm;
+
+	rinfo = malloc(sizeof(struct radeonfb_info));
+
+	if(radeon_probe(rinfo)) {
+		printf("No radeon video card found!\n");
+		return NULL;
+	}
+
+	/* fill in Graphic device struct */
+	sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640,
+		 480, 16, (1000 / 1000),
+		 (2000 / 1000));
+	printf ("%s\n", pGD->modeIdent);
+
+	pGD->winSizeX = 640;
+	pGD->winSizeY = 480;
+	pGD->plnSizeX = 640;
+	pGD->plnSizeY = 480;
+
+	pGD->gdfBytesPP = 1;
+	pGD->gdfIndex = GDF__8BIT_INDEX;
+
+	pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+	pGD->pciBase = rinfo->fb_base_phys;
+	pGD->frameAdrs = rinfo->fb_base_phys;
+	pGD->memSize = 64 * 1024 * 1024;
+
+	/* Cursor Start Address */
+	pGD->dprBase =
+	    (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
+	if ((pGD->dprBase & 0x0fff) != 0) {
+		/* allign it */
+		pGD->dprBase &= 0xfffff000;
+		pGD->dprBase += 0x00001000;
+	}
+	DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+		PATTERN_ADR);
+	pGD->vprBase = rinfo->fb_base_phys;	/* Dummy */
+	pGD->cprBase = rinfo->fb_base_phys;	/* Dummy */
+	/* set up Hardware */
+
+	/* Clear video memory */
+	i = pGD->memSize / 4;
+	vm = (unsigned int *) pGD->pciBase;
+	while (i--)
+		*vm++ = 0;
+	/*SetDrawingEngine (bits_per_pixel);*/
+
+	radeon_setmode();
+
+	return ((void *) pGD);
+}
+
+void video_set_lut (unsigned int index,	/* color number */
+	       unsigned char r,	/* red */
+	       unsigned char g,	/* green */
+	       unsigned char b	/* blue */
+	       )
+{
+	OUTREG(PALETTE_INDEX, index);
+	OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b);
+}
+#endif
diff --git a/drivers/video/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h
new file mode 100644
index 0000000..b5c4b8b
--- /dev/null
+++ b/drivers/video/ati_radeon_fb.h
@@ -0,0 +1,282 @@
+#ifndef __ATI_RADEON_FB_H
+#define __ATI_RADEON_FB_H
+
+/***************************************************************
+ * Most of the definitions here are adapted right from XFree86 *
+ ***************************************************************/
+
+/*
+ * Chip families. Must fit in the low 16 bits of a long word
+ */
+enum radeon_family {
+	CHIP_FAMILY_UNKNOW,
+	CHIP_FAMILY_LEGACY,
+	CHIP_FAMILY_RADEON,
+	CHIP_FAMILY_RV100,
+	CHIP_FAMILY_RS100,    /* U1 (IGP320M) or A3 (IGP320)*/
+	CHIP_FAMILY_RV200,
+	CHIP_FAMILY_RS200,    /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350),
+				 RS250 (IGP 7000) */
+	CHIP_FAMILY_R200,
+	CHIP_FAMILY_RV250,
+	CHIP_FAMILY_RS300,    /* Radeon 9000 IGP */
+	CHIP_FAMILY_RV280,
+	CHIP_FAMILY_R300,
+	CHIP_FAMILY_R350,
+	CHIP_FAMILY_RV350,
+	CHIP_FAMILY_RV380,    /* RV370/RV380/M22/M24 */
+	CHIP_FAMILY_R420,     /* R420/R423/M18 */
+	CHIP_FAMILY_LAST,
+};
+
+#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV200)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS100)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS200)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV250)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RV280)  || \
+				 ((rinfo)->family == CHIP_FAMILY_RS300))
+
+#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300)  || \
+				((rinfo)->family == CHIP_FAMILY_RV350) || \
+				((rinfo)->family == CHIP_FAMILY_R350)  || \
+				((rinfo)->family == CHIP_FAMILY_RV380) || \
+				((rinfo)->family == CHIP_FAMILY_R420))
+
+struct radeonfb_info {
+	char name[20];
+
+	struct pci_device_id	pdev;
+	u16 			family;
+
+	u32 			fb_base_phys;
+	u32 			mmio_base_phys;
+
+	void 			*mmio_base;
+	void 			*fb_base;
+
+	u32			video_ram;
+	u32			mapped_vram;
+	int			vram_width;
+	int			vram_ddr;
+
+	u32 			fb_local_base;
+};
+
+#define INREG8(addr)		readb((rinfo->mmio_base)+addr)
+#define OUTREG8(addr,val)	writeb(val, (rinfo->mmio_base)+addr)
+#define INREG16(addr)		readw((rinfo->mmio_base)+addr)
+#define OUTREG16(addr,val)	writew(val, (rinfo->mmio_base)+addr)
+#define INREG(addr)		readl((rinfo->mmio_base)+addr)
+#define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
+
+static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
+		       u32 val, u32 mask)
+{
+	unsigned int tmp;
+
+	tmp = INREG(addr);
+	tmp &= (mask);
+	tmp |= (val);
+	OUTREG(addr, tmp);
+}
+
+#define OUTREGP(addr,val,mask)	_OUTREGP(rinfo, addr, val,mask)
+
+/*
+ * 2D Engine helper routines
+ */
+static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
+{
+	int i;
+
+	/* initiate flush */
+	OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+	        ~RB2D_DC_FLUSH_ALL);
+
+	for (i=0; i < 2000000; i++) {
+		if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+			return;
+		udelay(1);
+	}
+	printf("radeonfb: Flush Timeout !\n");
+}
+
+static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
+{
+	int i;
+
+	for (i=0; i<2000000; i++) {
+		if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
+			return;
+		udelay(1);
+	}
+	printf("radeonfb: FIFO Timeout !\n");
+}
+
+static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
+{
+	int i;
+
+	/* ensure FIFO is empty before waiting for idle */
+	_radeon_fifo_wait (rinfo, 64);
+
+	for (i=0; i<2000000; i++) {
+		if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+			radeon_engine_flush (rinfo);
+			return;
+		}
+		udelay(1);
+	}
+	printf("radeonfb: Idle Timeout !\n");
+}
+
+#define radeon_engine_idle()		_radeon_engine_idle(rinfo)
+#define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
+#define radeon_msleep(ms)		_radeon_msleep(rinfo,ms)
+
+/*
+ * This structure contains the various registers manipulated by this
+ * driver for setting or restoring a mode. It's mostly copied from
+ * XFree's RADEONSaveRec structure. A few chip settings might still be
+ * tweaked without beeing reflected or saved in these registers though
+ */
+struct radeon_regs {
+	/* Common registers */
+	u32		ovr_clr;
+	u32		ovr_wid_left_right;
+	u32		ovr_wid_top_bottom;
+	u32		ov0_scale_cntl;
+	u32		mpp_tb_config;
+	u32		mpp_gp_config;
+	u32		subpic_cntl;
+	u32		viph_control;
+	u32		i2c_cntl_1;
+	u32		gen_int_cntl;
+	u32		cap0_trig_cntl;
+	u32		cap1_trig_cntl;
+	u32		bus_cntl;
+	u32		surface_cntl;
+	u32		bios_5_scratch;
+
+	/* Other registers to save for VT switches or driver load/unload */
+	u32		dp_datatype;
+	u32		rbbm_soft_reset;
+	u32		clock_cntl_index;
+	u32		amcgpio_en_reg;
+	u32		amcgpio_mask;
+
+	/* Surface/tiling registers */
+	u32		surf_lower_bound[8];
+	u32		surf_upper_bound[8];
+	u32		surf_info[8];
+
+	/* CRTC registers */
+	u32		crtc_gen_cntl;
+	u32		crtc_ext_cntl;
+	u32		dac_cntl;
+	u32		crtc_h_total_disp;
+	u32		crtc_h_sync_strt_wid;
+	u32		crtc_v_total_disp;
+	u32		crtc_v_sync_strt_wid;
+	u32		crtc_offset;
+	u32		crtc_offset_cntl;
+	u32		crtc_pitch;
+	u32		disp_merge_cntl;
+	u32		grph_buffer_cntl;
+	u32		crtc_more_cntl;
+
+	/* CRTC2 registers */
+	u32		crtc2_gen_cntl;
+	u32		dac2_cntl;
+	u32		disp_output_cntl;
+	u32		disp_hw_debug;
+	u32		disp2_merge_cntl;
+	u32		grph2_buffer_cntl;
+	u32		crtc2_h_total_disp;
+	u32		crtc2_h_sync_strt_wid;
+	u32		crtc2_v_total_disp;
+	u32		crtc2_v_sync_strt_wid;
+	u32		crtc2_offset;
+	u32		crtc2_offset_cntl;
+	u32		crtc2_pitch;
+
+	/* Flat panel regs */
+	u32 		fp_crtc_h_total_disp;
+	u32		fp_crtc_v_total_disp;
+	u32		fp_gen_cntl;
+	u32		fp2_gen_cntl;
+	u32		fp_h_sync_strt_wid;
+	u32		fp2_h_sync_strt_wid;
+	u32		fp_horz_stretch;
+	u32		fp_panel_cntl;
+	u32		fp_v_sync_strt_wid;
+	u32		fp2_v_sync_strt_wid;
+	u32		fp_vert_stretch;
+	u32		lvds_gen_cntl;
+	u32		lvds_pll_cntl;
+	u32		tmds_crc;
+	u32		tmds_transmitter_cntl;
+
+	/* Computed values for PLL */
+	u32		dot_clock_freq;
+	int		feedback_div;
+	int		post_div;
+
+	/* PLL registers */
+	u32		ppll_div_3;
+	u32		ppll_ref_div;
+	u32		vclk_ecp_cntl;
+	u32		clk_cntl_index;
+
+	/* Computed values for PLL2 */
+	u32		dot_clock_freq_2;
+	int		feedback_div_2;
+	int		post_div_2;
+
+	/* PLL2 registers */
+	u32		p2pll_ref_div;
+	u32		p2pll_div_0;
+	u32		htotal_cntl2;
+
+	/* Palette */
+	int		palette_valid;
+};
+
+static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr)
+{
+	u32 data;
+
+	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
+	/* radeon_pll_errata_after_index(rinfo); */
+	data = INREG(CLOCK_CNTL_DATA);
+	/* radeon_pll_errata_after_data(rinfo); */
+	return data;
+}
+
+static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index,
+			    u32 val)
+{
+
+	OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080);
+	/* radeon_pll_errata_after_index(rinfo); */
+	OUTREG(CLOCK_CNTL_DATA, val);
+	/* radeon_pll_errata_after_data(rinfo); */
+}
+
+static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index,
+			     u32 val, u32 mask)
+{
+	unsigned int tmp;
+
+	tmp  = __INPLL(rinfo, index);
+	tmp &= (mask);
+	tmp |= (val);
+	__OUTPLL(rinfo, index, tmp);
+}
+
+#define INPLL(addr)			__INPLL(rinfo, addr)
+#define OUTPLL(index, val)		__OUTPLL(rinfo, index, val)
+#define OUTPLLP(index, val, mask)	__OUTPLLP(rinfo, index, val, mask)
+
+#endif
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
new file mode 100644
index 0000000..bcf8771
--- /dev/null
+++ b/drivers/video/cfb_console.c
@@ -0,0 +1,1274 @@
+/*
+ * (C) Copyright 2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * cfb_console.c
+ *
+ * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
+ *
+ * At the moment only the 8x16 font is tested and the font fore- and
+ * background color is limited to black/white/gray colors. The Linux
+ * logo can be placed in the upper left corner and additional board
+ * information strings (that normaly goes to serial port) can be drawed.
+ *
+ * The console driver can use the standard PC keyboard interface (i8042)
+ * for character input. Character output goes to a memory mapped video
+ * framebuffer with little or big-endian organisation.
+ * With environment setting 'console=serial' the console i/o can be
+ * forced to serial port.
+
+ The driver uses graphic specific defines/parameters/functions:
+
+ (for SMI LynxE graphic chip)
+
+ CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
+ VIDEO_FB_LITTLE_ENDIAN	 - framebuffer organisation default: big endian
+ VIDEO_HW_RECTFILL	 - graphic driver supports hardware rectangle fill
+ VIDEO_HW_BITBLT	 - graphic driver supports hardware bit blt
+
+ Console Parameters are set by graphic drivers global struct:
+
+ VIDEO_VISIBLE_COLS	     - x resolution
+ VIDEO_VISIBLE_ROWS	     - y resolution
+ VIDEO_PIXEL_SIZE	     - storage size in byte per pixel
+ VIDEO_DATA_FORMAT	     - graphical data format GDF
+ VIDEO_FB_ADRS		     - start of video memory
+
+ CONFIG_I8042_KBD	     - AT Keyboard driver for i8042
+ VIDEO_KBD_INIT_FCT	     - init function for keyboard
+ VIDEO_TSTC_FCT		     - keyboard_tstc function
+ VIDEO_GETC_FCT		     - keyboard_getc function
+
+ CONFIG_CONSOLE_CURSOR	     - on/off drawing cursor is done with delay
+			       loop in VIDEO_TSTC_FCT (i8042)
+ CFG_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
+ CONFIG_CONSOLE_TIME	     - display time/date in upper right corner,
+			       needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR
+ CONFIG_VIDEO_LOGO	     - display Linux Logo in upper left corner
+ CONFIG_VIDEO_BMP_LOGO	     - use bmp_logo instead of linux_logo
+ CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
+			       that normaly goes to serial port. This define
+			       requires a board specific function:
+			       video_drawstring (VIDEO_INFO_X,
+						 VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
+						 info);
+			       that fills a info buffer at i=row.
+			       s.a: board/eltec/bab7xx.
+CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
+			       as an output only device. The Keyboard driver
+			       will not be set-up. This may be used, if you
+			       have none or more than one Keyboard devices
+			       (USB Keyboard, AT Keyboard).
+
+CONFIG_VIDEO_SW_CURSOR:	     - Draws a cursor after the last character. No
+			       blinking is provided. Uses the macros CURSOR_SET
+			       and CURSOR_OFF.
+CONFIG_VIDEO_HW_CURSOR:	     - Uses the hardware cursor capability of the
+			       graphic chip. Uses the macro CURSOR_SET.
+			       ATTENTION: If booting an OS, the display driver
+			       must disable the hardware register of the graphic
+			       chip. Otherwise a blinking field is displayed
+*/
+
+#include <common.h>
+
+#ifdef CONFIG_CFB_CONSOLE
+
+#include <malloc.h>
+
+/*****************************************************************************/
+/* Console device defines with SMI graphic				     */
+/* Any other graphic must change this section				     */
+/*****************************************************************************/
+
+#ifdef	CONFIG_VIDEO_SMI_LYNXEM
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the CT69000 driver					     */
+/*****************************************************************************/
+#ifdef	CONFIG_VIDEO_CT69000
+
+#define VIDEO_FB_LITTLE_ENDIAN
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the SED13806 driver					     */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_SED13806
+
+#ifndef CONFIG_TOTAL5200
+#define VIDEO_FB_LITTLE_ENDIAN
+#endif
+#define VIDEO_HW_RECTFILL
+#define VIDEO_HW_BITBLT
+#endif
+
+/*****************************************************************************/
+/* Defines for the SED13806 driver					     */
+/*****************************************************************************/
+#ifdef CONFIG_VIDEO_SM501
+
+#ifdef CONFIG_HH405
+#define VIDEO_FB_LITTLE_ENDIAN
+#endif
+#endif
+
+/*****************************************************************************/
+/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc	     */
+/*****************************************************************************/
+#include <video_fb.h>
+
+/*****************************************************************************/
+/* some Macros								     */
+/*****************************************************************************/
+#define VIDEO_VISIBLE_COLS	(pGD->winSizeX)
+#define VIDEO_VISIBLE_ROWS	(pGD->winSizeY)
+#define VIDEO_PIXEL_SIZE	(pGD->gdfBytesPP)
+#define VIDEO_DATA_FORMAT	(pGD->gdfIndex)
+#define VIDEO_FB_ADRS		(pGD->frameAdrs)
+
+/*****************************************************************************/
+/* Console device defines with i8042 keyboard controller		     */
+/* Any other keyboard controller must change this section		     */
+/*****************************************************************************/
+
+#ifdef	CONFIG_I8042_KBD
+#include <i8042.h>
+
+#define VIDEO_KBD_INIT_FCT	i8042_kbd_init()
+#define VIDEO_TSTC_FCT		i8042_tstc
+#define VIDEO_GETC_FCT		i8042_getc
+#endif
+
+/*****************************************************************************/
+/* Console device							     */
+/*****************************************************************************/
+
+#include <version.h>
+#include <linux/types.h>
+#include <devices.h>
+#include <video_font.h>
+
+#if defined(CONFIG_CMD_DATE)
+#include <rtc.h>
+#endif
+
+#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
+#include <watchdog.h>
+#include <bmp_layout.h>
+#endif
+
+/*****************************************************************************/
+/* Cursor definition:							     */
+/* CONFIG_CONSOLE_CURSOR:  Uses a timer function (see drivers/i8042.c) to    */
+/*			   let the cursor blink. Uses the macros CURSOR_OFF  */
+/*			   and CURSOR_ON.				     */
+/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No	     */
+/*			   blinking is provided. Uses the macros CURSOR_SET  */
+/*			   and CURSOR_OFF.				     */
+/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the	     */
+/*			   graphic chip. Uses the macro CURSOR_SET.	     */
+/*			   ATTENTION: If booting an OS, the display driver   */
+/*			   must disable the hardware register of the graphic */
+/*			   chip. Otherwise a blinking field is displayed     */
+/*****************************************************************************/
+#if !defined(CONFIG_CONSOLE_CURSOR) && \
+    !defined(CONFIG_VIDEO_SW_CURSOR) && \
+    !defined(CONFIG_VIDEO_HW_CURSOR)
+/* no Cursor defined */
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET
+#endif
+
+#ifdef	CONFIG_CONSOLE_CURSOR
+#ifdef	CURSOR_ON
+#error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+void	console_cursor (int state);
+#define CURSOR_ON  console_cursor(1);
+#define CURSOR_OFF console_cursor(0);
+#define CURSOR_SET
+#ifndef CONFIG_I8042_KBD
+#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c
+#endif
+#else
+#ifdef	CONFIG_CONSOLE_TIME
+#error	CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME
+#endif
+#endif /* CONFIG_CONSOLE_CURSOR */
+
+#ifdef	CONFIG_VIDEO_SW_CURSOR
+#ifdef	CURSOR_ON
+#error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\
+				 console_row * VIDEO_FONT_HEIGHT, ' ');
+#define CURSOR_SET video_set_cursor();
+#endif /* CONFIG_VIDEO_SW_CURSOR */
+
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+#ifdef	CURSOR_ON
+#error	only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined
+#endif
+#define CURSOR_ON
+#define CURSOR_OFF
+#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \
+		  (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT);
+#endif	/* CONFIG_VIDEO_HW_CURSOR */
+
+#ifdef	CONFIG_VIDEO_LOGO
+#ifdef	CONFIG_VIDEO_BMP_LOGO
+#include <bmp_logo.h>
+#define VIDEO_LOGO_WIDTH	BMP_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT	BMP_LOGO_HEIGHT
+#define VIDEO_LOGO_LUT_OFFSET	BMP_LOGO_OFFSET
+#define VIDEO_LOGO_COLORS	BMP_LOGO_COLORS
+
+#else	/* CONFIG_VIDEO_BMP_LOGO */
+#define LINUX_LOGO_WIDTH	80
+#define LINUX_LOGO_HEIGHT	80
+#define LINUX_LOGO_COLORS	214
+#define LINUX_LOGO_LUT_OFFSET	0x20
+#define __initdata
+#include <linux_logo.h>
+#define VIDEO_LOGO_WIDTH	LINUX_LOGO_WIDTH
+#define VIDEO_LOGO_HEIGHT	LINUX_LOGO_HEIGHT
+#define VIDEO_LOGO_LUT_OFFSET	LINUX_LOGO_LUT_OFFSET
+#define VIDEO_LOGO_COLORS	LINUX_LOGO_COLORS
+#endif	/* CONFIG_VIDEO_BMP_LOGO */
+#define VIDEO_INFO_X		(VIDEO_LOGO_WIDTH)
+#define VIDEO_INFO_Y		(VIDEO_FONT_HEIGHT/2)
+#else	/* CONFIG_VIDEO_LOGO */
+#define VIDEO_LOGO_WIDTH	0
+#define VIDEO_LOGO_HEIGHT	0
+#endif	/* CONFIG_VIDEO_LOGO */
+
+#define VIDEO_COLS		VIDEO_VISIBLE_COLS
+#define VIDEO_ROWS		VIDEO_VISIBLE_ROWS
+#define VIDEO_SIZE		(VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_PIX_BLOCKS	(VIDEO_SIZE >> 2)
+#define VIDEO_LINE_LEN		(VIDEO_COLS*VIDEO_PIXEL_SIZE)
+#define VIDEO_BURST_LEN		(VIDEO_COLS/8)
+
+#ifdef	CONFIG_VIDEO_LOGO
+#define CONSOLE_ROWS		((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT)
+#else
+#define CONSOLE_ROWS		(VIDEO_ROWS / VIDEO_FONT_HEIGHT)
+#endif
+
+#define CONSOLE_COLS		(VIDEO_COLS / VIDEO_FONT_WIDTH)
+#define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
+#define CONSOLE_ROW_FIRST	(video_console_address)
+#define CONSOLE_ROW_SECOND	(video_console_address + CONSOLE_ROW_SIZE)
+#define CONSOLE_ROW_LAST	(video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+#define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * CONSOLE_ROWS)
+#define CONSOLE_SCROLL_SIZE	(CONSOLE_SIZE - CONSOLE_ROW_SIZE)
+
+/* Macros */
+#ifdef	VIDEO_FB_LITTLE_ENDIAN
+#define SWAP16(x)	 ((((x) & 0x00ff) << 8) | ( (x) >> 8))
+#define SWAP32(x)	 ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
+			  (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
+#define SHORTSWAP32(x)	 ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
+			  (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
+#else
+#define SWAP16(x)	 (x)
+#define SWAP32(x)	 (x)
+#define SHORTSWAP32(x)	 (x)
+#endif
+
+#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
+#define PRINTD(x)	  printf(x)
+#else
+#define PRINTD(x)
+#endif
+
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+extern void video_get_info_str (    /* setup a board string: type, speed, etc. */
+    int line_number,	    /* location to place info string beside logo */
+    char *info		    /* buffer for info string */
+    );
+
+#endif
+
+/* Locals */
+static GraphicDevice *pGD;	/* Pointer to Graphic array */
+
+static void *video_fb_address;		/* frame buffer address */
+static void *video_console_address;	/* console buffer start address */
+
+static int console_col = 0; /* cursor col */
+static int console_row = 0; /* cursor row */
+
+static u32 eorx, fgx, bgx;  /* color pats */
+
+static const int video_font_draw_table8[] = {
+	    0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
+	    0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
+	    0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
+	    0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff };
+
+static const int video_font_draw_table15[] = {
+	    0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff };
+
+static const int video_font_draw_table16[] = {
+	    0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff };
+
+static const int video_font_draw_table24[16][3] = {
+	    { 0x00000000, 0x00000000, 0x00000000 },
+	    { 0x00000000, 0x00000000, 0x00ffffff },
+	    { 0x00000000, 0x0000ffff, 0xff000000 },
+	    { 0x00000000, 0x0000ffff, 0xffffffff },
+	    { 0x000000ff, 0xffff0000, 0x00000000 },
+	    { 0x000000ff, 0xffff0000, 0x00ffffff },
+	    { 0x000000ff, 0xffffffff, 0xff000000 },
+	    { 0x000000ff, 0xffffffff, 0xffffffff },
+	    { 0xffffff00, 0x00000000, 0x00000000 },
+	    { 0xffffff00, 0x00000000, 0x00ffffff },
+	    { 0xffffff00, 0x0000ffff, 0xff000000 },
+	    { 0xffffff00, 0x0000ffff, 0xffffffff },
+	    { 0xffffffff, 0xffff0000, 0x00000000 },
+	    { 0xffffffff, 0xffff0000, 0x00ffffff },
+	    { 0xffffffff, 0xffffffff, 0xff000000 },
+	    { 0xffffffff, 0xffffffff, 0xffffffff } };
+
+static const int video_font_draw_table32[16][4] = {
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
+	    { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
+	    { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
+	    { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
+	    { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
+	    { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
+	    { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
+	    { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
+	    { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
+	    { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
+	    { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
+	    { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
+	    { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
+	    { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
+	    { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } };
+
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+
+/******************************************************************************/
+
+static void video_drawchars (int xx, int yy, unsigned char *s, int count)
+{
+	u8 *cdat, *dest, *dest0;
+	int rows, offset, c;
+
+	offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
+	dest0 = video_fb_address + offset;
+
+	switch (VIDEO_DATA_FORMAT) {
+	case GDF__8BIT_INDEX:
+	case GDF__8BIT_332RGB:
+		while (count--) {
+			c = *s;
+			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+			     rows--;
+			     dest += VIDEO_LINE_LEN) {
+				u8 bits = *cdat++;
+
+				((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx;
+				((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx;
+			}
+			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+			s++;
+		}
+		break;
+
+	case GDF_15BIT_555RGB:
+		while (count--) {
+			c = *s;
+			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+			     rows--;
+			     dest += VIDEO_LINE_LEN) {
+				u8 bits = *cdat++;
+
+				((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx);
+				((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx);
+				((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx);
+				((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx);
+			}
+			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+			s++;
+		}
+		break;
+
+	case GDF_16BIT_565RGB:
+		while (count--) {
+			c = *s;
+			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+			     rows--;
+			     dest += VIDEO_LINE_LEN) {
+				u8 bits = *cdat++;
+
+				((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx);
+				((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx);
+				((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx);
+				((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx);
+			}
+			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+			s++;
+		}
+		break;
+
+	case GDF_32BIT_X888RGB:
+		while (count--) {
+			c = *s;
+			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+			     rows--;
+			     dest += VIDEO_LINE_LEN) {
+				u8 bits = *cdat++;
+
+				((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx);
+				((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx);
+				((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx);
+				((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx);
+				((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx);
+				((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx);
+				((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx);
+				((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx);
+			}
+			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+			s++;
+		}
+		break;
+
+	case GDF_24BIT_888RGB:
+		while (count--) {
+			c = *s;
+			cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
+			for (rows = VIDEO_FONT_HEIGHT, dest = dest0;
+			     rows--;
+			     dest += VIDEO_LINE_LEN) {
+				u8 bits = *cdat++;
+
+				((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx;
+				((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx;
+				((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx;
+				((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx;
+				((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx;
+				((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx;
+			}
+			dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
+			s++;
+		}
+		break;
+	}
+}
+
+/*****************************************************************************/
+
+static inline void video_drawstring (int xx, int yy, unsigned char *s)
+{
+	video_drawchars (xx, yy, s, strlen ((char *)s));
+}
+
+/*****************************************************************************/
+
+static void video_putchar (int xx, int yy, unsigned char c)
+{
+	video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1);
+}
+
+/*****************************************************************************/
+#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR)
+static void video_set_cursor (void)
+{
+	/* swap drawing colors */
+	eorx = fgx;
+	fgx = bgx;
+	bgx = eorx;
+	eorx = fgx ^ bgx;
+	/* draw cursor */
+	video_putchar (console_col * VIDEO_FONT_WIDTH,
+		       console_row * VIDEO_FONT_HEIGHT,
+		       ' ');
+	/* restore drawing colors */
+	eorx = fgx;
+	fgx = bgx;
+	bgx = eorx;
+	eorx = fgx ^ bgx;
+}
+#endif
+/*****************************************************************************/
+#ifdef CONFIG_CONSOLE_CURSOR
+void console_cursor (int state)
+{
+	static int last_state = 0;
+
+#ifdef CONFIG_CONSOLE_TIME
+	struct rtc_time tm;
+	char info[16];
+
+	/* time update only if cursor is on (faster scroll) */
+	if (state) {
+		rtc_get (&tm);
+
+		sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min,
+			 tm.tm_sec);
+		video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+				  VIDEO_INFO_Y, (uchar *)info);
+
+		sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon,
+			 tm.tm_year);
+		video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH,
+				  VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info);
+	}
+#endif
+
+	if (state && (last_state != state)) {
+		video_set_cursor ();
+	}
+
+	if (!state && (last_state != state)) {
+		/* clear cursor */
+		video_putchar (console_col * VIDEO_FONT_WIDTH,
+			       console_row * VIDEO_FONT_HEIGHT,
+			       ' ');
+	}
+
+	last_state = state;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_RECTFILL
+static void memsetl (int *p, int c, int v)
+{
+	while (c--)
+		*(p++) = v;
+}
+#endif
+
+/*****************************************************************************/
+
+#ifndef VIDEO_HW_BITBLT
+static void memcpyl (int *d, int *s, int c)
+{
+	while (c--)
+		*(d++) = *(s++);
+}
+#endif
+
+/*****************************************************************************/
+
+static void console_scrollup (void)
+{
+	/* copy up rows ignoring the first one */
+
+#ifdef VIDEO_HW_BITBLT
+	video_hw_bitblt (VIDEO_PIXEL_SIZE,	/* bytes per pixel */
+			 0,	/* source pos x */
+			 VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */
+			 0,	/* dest pos x */
+			 VIDEO_LOGO_HEIGHT,	/* dest pos y */
+			 VIDEO_VISIBLE_COLS,	/* frame width */
+			 VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT	/* frame height */
+		);
+#else
+	memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
+		 CONSOLE_SCROLL_SIZE >> 2);
+#endif
+
+	/* clear the last one */
+#ifdef VIDEO_HW_RECTFILL
+	video_hw_rectfill (VIDEO_PIXEL_SIZE,	/* bytes per pixel */
+			   0,	/* dest pos x */
+			   VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,	/* dest pos y */
+			   VIDEO_VISIBLE_COLS,	/* frame width */
+			   VIDEO_FONT_HEIGHT,	/* frame height */
+			   CONSOLE_BG_COL	/* fill color */
+		);
+#else
+	memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL);
+#endif
+}
+
+/*****************************************************************************/
+
+static void console_back (void)
+{
+	CURSOR_OFF console_col--;
+
+	if (console_col < 0) {
+		console_col = CONSOLE_COLS - 1;
+		console_row--;
+		if (console_row < 0)
+			console_row = 0;
+	}
+	video_putchar (console_col * VIDEO_FONT_WIDTH,
+		       console_row * VIDEO_FONT_HEIGHT,
+		       ' ');
+}
+
+/*****************************************************************************/
+
+static void console_newline (void)
+{
+	CURSOR_OFF console_row++;
+	console_col = 0;
+
+	/* Check if we need to scroll the terminal */
+	if (console_row >= CONSOLE_ROWS) {
+		/* Scroll everything up */
+		console_scrollup ();
+
+		/* Decrement row number */
+		console_row--;
+	}
+}
+
+/*****************************************************************************/
+
+void video_putc (const char c)
+{
+	switch (c) {
+	case 13:		/* ignore */
+		break;
+
+	case '\n':		/* next line */
+		console_newline ();
+		break;
+
+	case 9:		/* tab 8 */
+		CURSOR_OFF console_col |= 0x0008;
+		console_col &= ~0x0007;
+
+		if (console_col >= CONSOLE_COLS)
+			console_newline ();
+		break;
+
+	case 8:		/* backspace */
+		console_back ();
+		break;
+
+	default:		/* draw the char */
+		video_putchar (console_col * VIDEO_FONT_WIDTH,
+			       console_row * VIDEO_FONT_HEIGHT,
+			       c);
+		console_col++;
+
+		/* check for newline */
+		if (console_col >= CONSOLE_COLS)
+			console_newline ();
+	}
+CURSOR_SET}
+
+
+/*****************************************************************************/
+
+void video_puts (const char *s)
+{
+	int count = strlen (s);
+
+	while (count--)
+		video_putc (*s++);
+}
+
+/*****************************************************************************/
+
+#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN)
+
+#define FILL_8BIT_332RGB(r,g,b)	{			\
+	*fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6);	\
+	fb ++;						\
+}
+
+#define FILL_15BIT_555RGB(r,g,b) {			\
+	*(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \
+	fb += 2;					\
+}
+
+#define FILL_16BIT_565RGB(r,g,b) {			\
+	*(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \
+	fb += 2;					\
+}
+
+#define FILL_32BIT_X888RGB(r,g,b) {			\
+	*(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \
+	fb += 4;					\
+}
+
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+#define FILL_24BIT_888RGB(r,g,b) {			\
+	fb[0] = b;					\
+	fb[1] = g;					\
+	fb[2] = r;					\
+	fb += 3;					\
+}
+#else
+#define FILL_24BIT_888RGB(r,g,b) {			\
+	fb[0] = r;					\
+	fb[1] = g;					\
+	fb[2] = b;					\
+	fb += 3;					\
+}
+#endif
+
+
+/*
+ * Display the BMP file located at address bmp_image.
+ * Only uncompressed
+ */
+int video_display_bitmap (ulong bmp_image, int x, int y)
+{
+	ushort xcount, ycount;
+	uchar *fb;
+	bmp_image_t *bmp = (bmp_image_t *) bmp_image;
+	uchar *bmap;
+	ushort padded_line;
+	unsigned long width, height, bpp;
+	unsigned colors;
+	unsigned long compression;
+	bmp_color_table_entry_t cte;
+#ifdef CONFIG_VIDEO_BMP_GZIP
+	unsigned char *dst = NULL;
+	ulong len;
+#endif
+
+	WATCHDOG_RESET ();
+
+	if (!((bmp->header.signature[0] == 'B') &&
+	      (bmp->header.signature[1] == 'M'))) {
+
+#ifdef CONFIG_VIDEO_BMP_GZIP
+		/*
+		 * Could be a gzipped bmp image, try to decrompress...
+		 */
+		len = CFG_VIDEO_LOGO_MAX_SIZE;
+		dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE);
+		if (dst == NULL) {
+			printf("Error: malloc in gunzip failed!\n");
+			return(1);
+		}
+		if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) {
+			printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image);
+			free(dst);
+			return 1;
+		}
+		if (len == CFG_VIDEO_LOGO_MAX_SIZE) {
+			printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n");
+		}
+
+		/*
+		 * Set addr to decompressed image
+		 */
+		bmp = (bmp_image_t *)dst;
+
+		if (!((bmp->header.signature[0] == 'B') &&
+		      (bmp->header.signature[1] == 'M'))) {
+			printf ("Error: no valid bmp.gz image at %lx\n", bmp_image);
+			return 1;
+		}
+#else
+		printf ("Error: no valid bmp image at %lx\n", bmp_image);
+		return 1;
+#endif /* CONFIG_VIDEO_BMP_GZIP */
+	}
+
+	width = le32_to_cpu (bmp->header.width);
+	height = le32_to_cpu (bmp->header.height);
+	bpp = le16_to_cpu (bmp->header.bit_count);
+	colors = le32_to_cpu (bmp->header.colors_used);
+	compression = le32_to_cpu (bmp->header.compression);
+
+	debug ("Display-bmp: %d x %d  with %d colors\n",
+	       width, height, colors);
+
+	if (compression != BMP_BI_RGB) {
+		printf ("Error: compression type %ld not supported\n",
+			compression);
+		return 1;
+	}
+
+	padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3;
+
+	if ((x + width) > VIDEO_VISIBLE_COLS)
+		width = VIDEO_VISIBLE_COLS - x;
+	if ((y + height) > VIDEO_VISIBLE_ROWS)
+		height = VIDEO_VISIBLE_ROWS - y;
+
+	bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset);
+	fb = (uchar *) (video_fb_address +
+			((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
+			x * VIDEO_PIXEL_SIZE);
+
+	/* We handle only 8bpp or 24 bpp bitmap */
+	switch (le16_to_cpu (bmp->header.bit_count)) {
+	case 8:
+		padded_line -= width;
+		if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
+			/* Copy colormap					     */
+			for (xcount = 0; xcount < colors; ++xcount) {
+				cte = bmp->color_table[xcount];
+				video_set_lut (xcount, cte.red, cte.green, cte.blue);
+			}
+		}
+		ycount = height;
+		switch (VIDEO_DATA_FORMAT) {
+		case GDF__8BIT_INDEX:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					*fb++ = *bmap++;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF__8BIT_332RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					cte = bmp->color_table[*bmap++];
+					FILL_8BIT_332RGB (cte.red, cte.green, cte.blue);
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_15BIT_555RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					cte = bmp->color_table[*bmap++];
+					FILL_15BIT_555RGB (cte.red, cte.green, cte.blue);
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_16BIT_565RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					cte = bmp->color_table[*bmap++];
+					FILL_16BIT_565RGB (cte.red, cte.green, cte.blue);
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_32BIT_X888RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					cte = bmp->color_table[*bmap++];
+					FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue);
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_24BIT_888RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					cte = bmp->color_table[*bmap++];
+					FILL_24BIT_888RGB (cte.red, cte.green, cte.blue);
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		}
+		break;
+	case 24:
+		padded_line -= 3 * width;
+		ycount = height;
+		switch (VIDEO_DATA_FORMAT) {
+		case GDF__8BIT_332RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]);
+					bmap += 3;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_15BIT_555RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]);
+					bmap += 3;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_16BIT_565RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]);
+					bmap += 3;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_32BIT_X888RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]);
+					bmap += 3;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		case GDF_24BIT_888RGB:
+			while (ycount--) {
+				WATCHDOG_RESET ();
+				xcount = width;
+				while (xcount--) {
+					FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]);
+					bmap += 3;
+				}
+				bmap += padded_line;
+				fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE;
+			}
+			break;
+		default:
+			printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n");
+			break;
+		}
+		break;
+	default:
+		printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n",
+			le16_to_cpu (bmp->header.bit_count));
+		break;
+	}
+
+#ifdef CONFIG_VIDEO_BMP_GZIP
+	if (dst) {
+		free(dst);
+	}
+#endif
+
+	return (0);
+}
+#endif
+
+/*****************************************************************************/
+
+#ifdef CONFIG_VIDEO_LOGO
+void logo_plot (void *screen, int width, int x, int y)
+{
+
+	int xcount, i;
+	int skip   = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE;
+	int ycount = VIDEO_LOGO_HEIGHT;
+	unsigned char r, g, b, *logo_red, *logo_blue, *logo_green;
+	unsigned char *source;
+	unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x);
+
+#ifdef CONFIG_VIDEO_BMP_LOGO
+	source = bmp_logo_bitmap;
+
+	/* Allocate temporary space for computing colormap			 */
+	logo_red = malloc (BMP_LOGO_COLORS);
+	logo_green = malloc (BMP_LOGO_COLORS);
+	logo_blue = malloc (BMP_LOGO_COLORS);
+	/* Compute color map							 */
+	for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
+		logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4;
+		logo_green[i] = (bmp_logo_palette[i] & 0x00f0);
+		logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4;
+	}
+#else
+	source = linux_logo;
+	logo_red = linux_logo_red;
+	logo_green = linux_logo_green;
+	logo_blue = linux_logo_blue;
+#endif
+
+	if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) {
+		for (i = 0; i < VIDEO_LOGO_COLORS; i++) {
+			video_set_lut (i + VIDEO_LOGO_LUT_OFFSET,
+				       logo_red[i], logo_green[i], logo_blue[i]);
+		}
+	}
+
+	while (ycount--) {
+		xcount = VIDEO_LOGO_WIDTH;
+		while (xcount--) {
+			r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET];
+			g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET];
+			b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET];
+
+			switch (VIDEO_DATA_FORMAT) {
+			case GDF__8BIT_INDEX:
+				*dest = *source;
+				break;
+			case GDF__8BIT_332RGB:
+				*dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
+				break;
+			case GDF_15BIT_555RGB:
+				*(unsigned short *) dest =
+					SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3)));
+				break;
+			case GDF_16BIT_565RGB:
+				*(unsigned short *) dest =
+					SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)));
+				break;
+			case GDF_32BIT_X888RGB:
+				*(unsigned long *) dest =
+					SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b));
+				break;
+			case GDF_24BIT_888RGB:
+#ifdef VIDEO_FB_LITTLE_ENDIAN
+				dest[0] = b;
+				dest[1] = g;
+				dest[2] = r;
+#else
+				dest[0] = r;
+				dest[1] = g;
+				dest[2] = b;
+#endif
+				break;
+			}
+			source++;
+			dest += VIDEO_PIXEL_SIZE;
+		}
+		dest += skip;
+	}
+#ifdef CONFIG_VIDEO_BMP_LOGO
+	free (logo_red);
+	free (logo_green);
+	free (logo_blue);
+#endif
+}
+
+/*****************************************************************************/
+
+static void *video_logo (void)
+{
+	char info[128];
+	extern char version_string;
+
+#ifdef CONFIG_SPLASH_SCREEN
+	char *s;
+	ulong addr;
+
+	if ((s = getenv ("splashimage")) != NULL) {
+		addr = simple_strtoul (s, NULL, 16);
+
+		if (video_display_bitmap (addr, 0, 0) == 0) {
+			return ((void *) (video_fb_address));
+		}
+	}
+#endif /* CONFIG_SPLASH_SCREEN */
+
+	logo_plot (video_fb_address, VIDEO_COLS, 0, 0);
+
+	sprintf (info, " %s", &version_string);
+	video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info);
+
+#ifdef CONFIG_CONSOLE_EXTRA_INFO
+	{
+		int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT);
+
+		for (i = 1; i < n; i++) {
+			video_get_info_str (i, info);
+			if (*info)
+				video_drawstring (VIDEO_INFO_X,
+						  VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT,
+						  (uchar *)info);
+		}
+	}
+#endif
+
+	return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN);
+}
+#endif
+
+
+/*****************************************************************************/
+
+static int video_init (void)
+{
+	unsigned char color8;
+
+	if ((pGD = video_hw_init ()) == NULL)
+		return -1;
+
+	video_fb_address = (void *) VIDEO_FB_ADRS;
+#ifdef CONFIG_VIDEO_HW_CURSOR
+	video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT);
+#endif
+
+	/* Init drawing pats */
+	switch (VIDEO_DATA_FORMAT) {
+	case GDF__8BIT_INDEX:
+		video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+		video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL);
+		fgx = 0x01010101;
+		bgx = 0x00000000;
+		break;
+	case GDF__8BIT_332RGB:
+		color8 = ((CONSOLE_FG_COL & 0xe0) |
+			  ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6);
+		fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+		color8 = ((CONSOLE_BG_COL & 0xe0) |
+			  ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6);
+		bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8;
+		break;
+	case GDF_15BIT_555RGB:
+		fgx = (((CONSOLE_FG_COL >> 3) << 26) |
+		       ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
+		       ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) |
+		       (CONSOLE_FG_COL >> 3));
+		bgx = (((CONSOLE_BG_COL >> 3) << 26) |
+		       ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
+		       ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) |
+		       (CONSOLE_BG_COL >> 3));
+		break;
+	case GDF_16BIT_565RGB:
+		fgx = (((CONSOLE_FG_COL >> 3) << 27) |
+		       ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) |
+		       ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) |
+		       (CONSOLE_FG_COL >> 3));
+		bgx = (((CONSOLE_BG_COL >> 3) << 27) |
+		       ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) |
+		       ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) |
+		       (CONSOLE_BG_COL >> 3));
+		break;
+	case GDF_32BIT_X888RGB:
+		fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
+		bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+		break;
+	case GDF_24BIT_888RGB:
+		fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) |
+			(CONSOLE_FG_COL << 8) | CONSOLE_FG_COL;
+		bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) |
+			(CONSOLE_BG_COL << 8) | CONSOLE_BG_COL;
+		break;
+	}
+	eorx = fgx ^ bgx;
+
+#ifdef CONFIG_VIDEO_LOGO
+	/* Plot the logo and get start point of console */
+	PRINTD ("Video: Drawing the logo ...\n");
+	video_console_address = video_logo ();
+#else
+	video_console_address = video_fb_address;
+#endif
+
+	/* Initialize the console */
+	console_col = 0;
+	console_row = 0;
+
+	return 0;
+}
+
+
+/*****************************************************************************/
+
+int drv_video_init (void)
+{
+	int skip_dev_init;
+	device_t console_dev;
+
+	skip_dev_init = 0;
+
+	/* Init video chip - returns with framebuffer cleared */
+	if (video_init () == -1)
+		skip_dev_init = 1;
+
+#ifdef CONFIG_VGA_AS_SINGLE_DEVICE
+	/* Devices VGA and Keyboard will be assigned seperately */
+	/* Init vga device */
+	if (!skip_dev_init) {
+		memset (&console_dev, 0, sizeof (console_dev));
+		strcpy (console_dev.name, "vga");
+		console_dev.ext = DEV_EXT_VIDEO;	/* Video extensions */
+		console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM;
+		console_dev.putc = video_putc;	/* 'putc' function */
+		console_dev.puts = video_puts;	/* 'puts' function */
+		console_dev.tstc = NULL;	/* 'tstc' function */
+		console_dev.getc = NULL;	/* 'getc' function */
+
+		if (device_register (&console_dev) == 0)
+			return 1;
+	}
+#else
+	PRINTD ("KBD: Keyboard init ...\n");
+	if (VIDEO_KBD_INIT_FCT == -1)
+		skip_dev_init = 1;
+
+	/* Init console device */
+	if (!skip_dev_init) {
+		memset (&console_dev, 0, sizeof (console_dev));
+		strcpy (console_dev.name, "vga");
+		console_dev.ext = DEV_EXT_VIDEO;	/* Video extensions */
+		console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+		console_dev.putc = video_putc;	/* 'putc' function */
+		console_dev.puts = video_puts;	/* 'puts' function */
+		console_dev.tstc = VIDEO_TSTC_FCT;	/* 'tstc' function */
+		console_dev.getc = VIDEO_GETC_FCT;	/* 'getc' function */
+
+		if (device_register (&console_dev) == 0)
+			return 1;
+	}
+#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
+	/* No console dev available */
+	return 0;
+}
+#endif /* CONFIG_CFB_CONSOLE */
diff --git a/drivers/video/ct69000.c b/drivers/video/ct69000.c
new file mode 100644
index 0000000..29d82e4
--- /dev/null
+++ b/drivers/video/ct69000.c
@@ -0,0 +1,1286 @@
+/* ported from ctfb.c (linux kernel):
+ * Created in Jan - July 2000 by Thomas Höhenleitner <th@visuelle-maschinen.de>
+ *
+ * Ported to U-Boot:
+ * (C) Copyright 2002 Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO
+
+#include <pci.h>
+#include <video_fb.h>
+#include "videomodes.h"
+
+#ifdef CONFIG_VIDEO_CT69000
+
+/* debug */
+#undef VGA_DEBUG
+#undef VGA_DUMP_REG
+#ifdef VGA_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+/* Macros */
+#ifndef min
+#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b )
+#endif
+#ifndef max
+#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b )
+#endif
+#ifdef minmax
+#error "term minmax already used."
+#endif
+#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) )
+#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) )
+
+/* CT Register Offsets */
+#define CT_AR_O			0x3c0	/* Index and Data write port of the attribute Registers */
+#define CT_GR_O			0x3ce	/* Index port of the Graphic Controller Registers */
+#define CT_SR_O			0x3c4	/* Index port of the Sequencer Controller */
+#define CT_CR_O			0x3d4	/* Index port of the CRT Controller */
+#define CT_XR_O			0x3d6	/* Extended Register index */
+#define CT_MSR_W_O		0x3c2	/* Misc. Output Register (write only) */
+#define CT_LUT_MASK_O		0x3c6	/* Color Palette Mask */
+#define CT_LUT_START_O		0x3c8	/* Color Palette Write Mode Index */
+#define CT_LUT_RGB_O		0x3c9	/* Color Palette Data Port */
+#define CT_STATUS_REG0_O	0x3c2	/* Status Register 0 (read only) */
+#define CT_STATUS_REG1_O	0x3da	/* Input Status Register 1 (read only) */
+
+#define CT_FP_O			0x3d0	/* Index port of the Flat panel Registers */
+#define CT_MR_O			0x3d2	/* Index Port of the Multimedia Extension */
+
+/* defines for the memory mapped registers */
+#define BR00_o		0x400000	/* Source and Destination Span Register */
+#define BR01_o		0x400004	/* Pattern/Source Expansion Background Color & Transparency Key Register */
+#define BR02_o		0x400008	/* Pattern/Source Expansion Foreground Color Register */
+#define BR03_o		0x40000C	/* Monochrome Source Control Register */
+#define BR04_o		0x400010	/* BitBLT Control Register */
+#define BR05_o		0x400014	/* Pattern Address Registe */
+#define BR06_o		0x400018	/* Source Address Register */
+#define BR07_o		0x40001C	/* Destination Address Register */
+#define BR08_o		0x400020	/* Destination Width & Height Register */
+#define BR09_o		0x400024	/* Source Expansion Background Color & Transparency Key Register */
+#define BR0A_o		0x400028	/* Source Expansion Foreground Color Register */
+
+#define CURSOR_SIZE	0x1000	/* in KByte for HW Cursor */
+#define PATTERN_ADR	(pGD->dprBase + CURSOR_SIZE)	/* pattern Memory after Cursor Memory */
+#define PATTERN_SIZE	8*8*4	/* 4 Bytes per Pixel 8 x 8 Pixel */
+#define ACCELMEMORY	(CURSOR_SIZE + PATTERN_SIZE)	/* reserved Memory for BITBlt and hw cursor */
+
+/* Some Mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active  */
+#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active    */
+#define FB_SYNC_EXT		4	/* external sync                */
+#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active   */
+#define FB_SYNC_BROADCAST	16	/* broadcast video timings      */
+					/* vtotal = 144d/288n/576i => PAL  */
+					/* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN	32	/* sync on green */
+
+#define FB_VMODE_NONINTERLACED  0	/* non interlaced */
+#define FB_VMODE_INTERLACED	1	/* interlaced   */
+#define FB_VMODE_DOUBLE		2	/* double scan */
+#define FB_VMODE_MASK		255
+
+#define FB_VMODE_YWRAP		256	/* ywrap instead of panning     */
+#define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset       */
+
+#define text			0
+#define fntwidth		8
+
+/* table for VGA Initialization  */
+typedef struct {
+	const unsigned char reg;
+	const unsigned char val;
+} CT_CFG_TABLE;
+
+/* this table provides some basic initialisations such as Memory Clock etc */
+static CT_CFG_TABLE xreg[] = {
+	{0x09, 0x01},		/* CRT Controller Extensions Enable */
+	{0x0A, 0x02},		/* Frame Buffer Mapping */
+	{0x0B, 0x01},		/* PCI Write Burst support */
+	{0x20, 0x00},		/* BitBLT Configuration */
+	{0x40, 0x03},		/* Memory Access Control */
+	{0x60, 0x00},		/* Video Pin Control */
+	{0x61, 0x00},		/* DPMS Synch control */
+	{0x62, 0x00},		/* GPIO Pin Control */
+	{0x63, 0xBD},		/* GPIO Pin Data */
+	{0x67, 0x00},		/* Pin Tri-State */
+	{0x80, 0x80},		/* Pixel Pipeline Config 0 register */
+	{0xA0, 0x00},		/* Cursor 1 Control Reg */
+	{0xA1, 0x00},		/* Cursor 1 Vertical Extension Reg */
+	{0xA2, 0x00},		/* Cursor 1 Base Address Low */
+	{0xA3, 0x00},		/* Cursor 1 Base Address High */
+	{0xA4, 0x00},		/* Cursor 1 X-Position Low */
+	{0xA5, 0x00},		/* Cursor 1 X-Position High */
+	{0xA6, 0x00},		/* Cursor 1 Y-Position Low */
+	{0xA7, 0x00},		/* Cursor 1 Y-Position High */
+	{0xA8, 0x00},		/* Cursor 2 Control Reg */
+	{0xA9, 0x00},		/* Cursor 2 Vertical Extension Reg */
+	{0xAA, 0x00},		/* Cursor 2 Base Address Low */
+	{0xAB, 0x00},		/* Cursor 2 Base Address High */
+	{0xAC, 0x00},		/* Cursor 2 X-Position Low */
+	{0xAD, 0x00},		/* Cursor 2 X-Position High */
+	{0xAE, 0x00},		/* Cursor 2 Y-Position Low */
+	{0xAF, 0x00},		/* Cursor 2 Y-Position High */
+	{0xC0, 0x7D},		/* Dot Clock 0 VCO M-Divisor */
+	{0xC1, 0x07},		/* Dot Clock 0 VCO N-Divisor */
+	{0xC3, 0x34},		/* Dot Clock 0 Divisor select */
+	{0xC4, 0x55},		/* Dot Clock 1 VCO M-Divisor */
+	{0xC5, 0x09},		/* Dot Clock 1 VCO N-Divisor */
+	{0xC7, 0x24},		/* Dot Clock 1 Divisor select */
+	{0xC8, 0x7D},		/* Dot Clock 2 VCO M-Divisor */
+	{0xC9, 0x07},		/* Dot Clock 2 VCO N-Divisor */
+	{0xCB, 0x34},		/* Dot Clock 2 Divisor select */
+	{0xCC, 0x38},		/* Memory Clock 0 VCO M-Divisor */
+	{0xCD, 0x03},		/* Memory Clock 0 VCO N-Divisor */
+	{0xCE, 0x90},		/* Memory Clock 0 Divisor select */
+	{0xCF, 0x06},		/* Clock Config */
+	{0xD0, 0x0F},		/* Power Down */
+	{0xD1, 0x01},		/* Power Down BitBLT */
+	{0xFF, 0xFF}		/* end of table */
+};
+/* Clock Config:
+ * =============
+ *
+ * PD Registers:
+ * -------------
+ * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor.
+ * They are encoded as follows:
+ *
+ * +---+--------------+
+ * | 2 | Loop Divisor |
+ * +---+--------------+
+ * | 1 | 1            |
+ * +---+--------------+
+ * | 0 | 4            |
+ * +---+--------------+
+ * Note: The Memory Clock does not have a Loop Divisor.
+ * +---+---+---+--------------+
+ * | 6 | 5 | 4 | Post Divisor |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 0 | 1            |
+ * +---+---+---+--------------+
+ * | 0 | 0 | 1 | 2            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 0 | 4            |
+ * +---+---+---+--------------+
+ * | 0 | 1 | 1 | 8            |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 0 | 16           |
+ * +---+---+---+--------------+
+ * | 1 | 0 | 1 | 32           |
+ * +---+---+---+--------------+
+ * | 1 | 1 | X | reserved     |
+ * +---+---+---+--------------+
+ *
+ * All other bits are reserved in these registers.
+ *
+ * Clock VCO M Registers:
+ * ----------------------
+ * These Registers contain the M Value -2.
+ *
+ * Clock VCO N Registers:
+ * ----------------------
+ * These Registers contain the N Value -2.
+ *
+ * Formulas:
+ * ---------
+ * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz
+ * Fout = Fvco / Post Divisor
+ *
+ * Dot Clk0 (default 25MHz):
+ * -------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC0 = (M - 2) = 125 = 0x7D
+ * XRC1 = (N - 2) = 7   = 0x07
+ * XRC3 =                 0x34
+ *
+ * Dot Clk1 (default 28MHz):
+ * -------------------------
+ * Fvco = 14.318 * 87 / 11 = 113.24MHz
+ * Fout = 113.24MHz / 4 = 28.31MHz
+ * Post Divisor = 4
+ * Loop Divisor = 1
+ * XRC4 = (M - 2) = 85 = 0x55
+ * XRC5 = (N - 2) = 9  = 0x09
+ * XRC7 =                0x24
+ *
+ * Dot Clk2 (variable for extended modes set to 25MHz):
+ * ----------------------------------------------------
+ * Fvco = 14.318 * 127 / 9 = 202.045MHz
+ * Fout = 202.045MHz / 8 = 25.25MHz
+ * Post Divisor = 8
+ * Loop Divisor = 1
+ * XRC8 = (M - 2) = 125 = 0x7D
+ * XRC9 = (N - 2) = 7   = 0x07
+ * XRCB =                 0x34
+ *
+ * Memory Clk for most modes >50MHz:
+ * ----------------------------------
+ * Fvco = 14.318 * 58 / 5 = 166MHz
+ * Fout = 166MHz / 2      = 83MHz
+ * Post Divisor = 2
+ * XRCC = (M - 2) = 57  = 0x38
+ * XRCD = (N - 2) = 3   = 0x03
+ * XRCE =                 0x90
+ *
+ * Note Bit7 enables the clock source from the VCO
+ *
+ */
+
+/*******************************************************************
+ * Chips struct
+ *******************************************************************/
+struct ctfb_chips_properties {
+	int device_id;		/* PCI Device ID */
+	unsigned long max_mem;	/* memory for frame buffer */
+	int vld_set;		/* value of VLD if bit2 in clock control is set */
+	int vld_not_set;	/* value of VLD if bit2 in clock control is set */
+	int mn_diff;		/* difference between M/N Value + mn_diff = M/N Register */
+	int mn_min;		/* min value of M/N Value */
+	int mn_max;		/* max value of M/N Value */
+	int vco_min;		/* VCO Min in MHz */
+	int vco_max;		/* VCO Max in MHz */
+};
+
+static const struct ctfb_chips_properties chips[] = {
+	{PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220},
+#ifdef CONFIG_USE_CPCIDVI
+	{PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220},
+#endif
+	{PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220},	/* NOT TESTED */
+	{0, 0, 0, 0, 0, 0, 0, 0, 0}	/* Terminator */
+};
+
+/*
+ * The Graphic Device
+ */
+GraphicDevice ctfb;
+
+/*******************************************************************************
+*
+* Low Level Routines
+*/
+
+/*******************************************************************************
+*
+* Read CT ISA register
+*/
+#ifdef VGA_DEBUG
+static unsigned char
+ctRead (unsigned short index)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O)
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+
+	return (in8 (pGD->isaBase + index));
+}
+#endif
+/*******************************************************************************
+*
+* Write CT ISA register
+*/
+static void
+ctWrite (unsigned short index, unsigned char val)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	out8 ((pGD->isaBase + index), val);
+}
+
+/*******************************************************************************
+*
+* Read CT ISA register indexed
+*/
+static unsigned char
+ctRead_i (unsigned short index, char reg)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O)
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+	out8 ((pGD->isaBase + index), reg);
+	return (in8 (pGD->isaBase + index + 1));
+}
+
+/*******************************************************************************
+*
+* Write CT ISA register indexed
+*/
+static void
+ctWrite_i (unsigned short index, char reg, char val)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	if (index == CT_AR_O) {
+		/* synch the Flip Flop */
+		in8 (pGD->isaBase + CT_STATUS_REG1_O);
+		out8 ((pGD->isaBase + index), reg);
+		out8 ((pGD->isaBase + index), val);
+	} else {
+		out8 ((pGD->isaBase + index), reg);
+		out8 ((pGD->isaBase + index + 1), val);
+	}
+}
+
+/*******************************************************************************
+*
+* Write a table of CT ISA register
+*/
+static void
+ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab)
+{
+	while (regTab->reg != 0xFF) {
+		ctWrite_i (index, regTab->reg, regTab->val);
+		regTab++;
+	}
+}
+
+/*****************************************************************************/
+static void
+SetArRegs (void)
+{
+	int i, tmp;
+
+	for (i = 0; i < 0x10; i++)
+		ctWrite_i (CT_AR_O, i, i);
+	if (text)
+		tmp = 0x04;
+	else
+		tmp = 0x41;
+
+	ctWrite_i (CT_AR_O, 0x10, tmp);	/* Mode Control Register */
+	ctWrite_i (CT_AR_O, 0x11, 0x00);	/* Overscan Color Register */
+	ctWrite_i (CT_AR_O, 0x12, 0x0f);	/* Memory Plane Enable Register */
+	if (fntwidth == 9)
+		tmp = 0x08;
+	else
+		tmp = 0x00;
+	ctWrite_i (CT_AR_O, 0x13, tmp);	/* Horizontal Pixel Panning */
+	ctWrite_i (CT_AR_O, 0x14, 0x00);	/* Color Select Register    */
+	ctWrite (CT_AR_O, 0x20);	/* enable video             */
+}
+
+/*****************************************************************************/
+static void
+SetGrRegs (void)
+{				/* Set Graphics Mode */
+	int i;
+
+	for (i = 0; i < 0x05; i++)
+		ctWrite_i (CT_GR_O, i, 0);
+	if (text) {
+		ctWrite_i (CT_GR_O, 0x05, 0x10);
+		ctWrite_i (CT_GR_O, 0x06, 0x02);
+	} else {
+		ctWrite_i (CT_GR_O, 0x05, 0x40);
+		ctWrite_i (CT_GR_O, 0x06, 0x05);
+	}
+	ctWrite_i (CT_GR_O, 0x07, 0x0f);
+	ctWrite_i (CT_GR_O, 0x08, 0xff);
+}
+
+/*****************************************************************************/
+static void
+SetSrRegs (void)
+{
+	int tmp = 0;
+
+	ctWrite_i (CT_SR_O, 0x00, 0x00);	/* reset */
+	/*rr( sr, 0x01, tmp );
+	   if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01;
+	   wr( sr, 0x01, tmp );  */
+	if (fntwidth == 8)
+		ctWrite_i (CT_SR_O, 0x01, 0x01);	/* Clocking Mode Register */
+	else
+		ctWrite_i (CT_SR_O, 0x01, 0x00);	/* Clocking Mode Register */
+	ctWrite_i (CT_SR_O, 0x02, 0x0f);	/* Enable CPU wr access to given memory plane */
+	ctWrite_i (CT_SR_O, 0x03, 0x00);	/* Character Map Select Register */
+	if (text)
+		tmp = 0x02;
+	else
+		tmp = 0x0e;
+	ctWrite_i (CT_SR_O, 0x04, tmp);	/* Enable CPU accesses to the rest of the 256KB
+					   total VGA memory beyond the first 64KB and set
+					   fb mapping mode. */
+	ctWrite_i (CT_SR_O, 0x00, 0x03);	/* enable */
+}
+
+/*****************************************************************************/
+static void
+SetBitsPerPixelIntoXrRegs (int bpp)
+{
+	unsigned int n = (bpp >> 3), tmp;	/* only for 15, 8, 16, 24 bpp */
+	static char md[4] = { 0x04, 0x02, 0x05, 0x06 };	/* DisplayColorMode */
+	static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 };	/* mask */
+	static char on[4] = { 0x10, 0x00, 0x10, 0x20 };	/* mask */
+	if (bpp == 15)
+		n = 0;
+	tmp = ctRead_i (CT_XR_O, 0x20);
+	tmp &= off[n];
+	tmp |= on[n];
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	ctWrite_i (CT_XR_O, 0x81, md[n]);
+}
+
+/*****************************************************************************/
+static void
+SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel)
+{				/* he -le-   ht|0    hd -ri- hs     -h-      he */
+	unsigned char cr[0x7a];
+	int i, tmp;
+	unsigned int hd, hs, he, ht, hbe;	/* Horizontal.  */
+	unsigned int vd, vs, ve, vt;	/* vertical */
+	unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine;
+	unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay;
+	unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl;
+	unsigned int HorizontalEqualizationPulses;
+	unsigned int HorizontalSerration1Start, HorizontalSerration2Start;
+
+	const int LineCompare = 0x3ff;
+	unsigned int TextScanLines = 1;	/* this is in fact a vertical zoom factor   */
+	unsigned int RAMDAC_BlankPedestalEnable = 0;	/* 1=en-, 0=disable, see XR82 */
+
+	hd = (var->xres) / 8;	/* HDisp.  */
+	hs = (var->xres + var->right_margin) / 8;	/* HsStrt  */
+	he = (var->xres + var->right_margin + var->hsync_len) / 8;	/* HsEnd   */
+	ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;	/* HTotal  */
+	hbe = ht - 1;		/* HBlankEnable todo docu wants ht here, but it does not work */
+	/* ve -up-  vt|0    vd -lo- vs     -v-      ve */
+	vd = var->yres;		/* VDisplay   */
+	vs = var->yres + var->lower_margin;	/* VSyncStart */
+	ve = var->yres + var->lower_margin + var->vsync_len;	/* VSyncEnd */
+	vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;	/* VTotal  */
+	bpp = bits_per_pixel;
+	dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+	interlaced = var->vmode & FB_VMODE_INTERLACED;
+	bcast = var->sync & FB_SYNC_BROADCAST;
+	CrtHalfLine = bcast ? (hd >> 1) : 0;
+	BlDelayCtrl = bcast ? 1 : 0;
+	CompSyncCharClkDelay = 0;	/* 2 bit */
+	CompSyncPixelClkDelay = 0;	/* 3 bit */
+	if (bcast) {
+		NTSC_PAL_HorizontalPulseWidth = 7;	/*( var->hsync_len >> 1 ) + 1 */
+		HorizontalEqualizationPulses = 0;	/* inverse value */
+		HorizontalSerration1Start = 31;	/* ( ht >> 1 ) */
+		HorizontalSerration2Start = 89;	/* ( ht >> 1 ) */
+	} else {
+		NTSC_PAL_HorizontalPulseWidth = 0;
+		/* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] )
+		 * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */
+		HorizontalEqualizationPulses = 1;	/* inverse value */
+		HorizontalSerration1Start = 0;	/* ( ht >> 1 ) */
+		HorizontalSerration2Start = 0;	/* ( ht >> 1 ) */
+	}
+
+	if (bpp == 15)
+		bpp = 16;
+	wd = var->xres * bpp / 64;	/* double words per line */
+	if (interlaced) {	/* we divide all vertical timings, exept vd */
+		vs >>= 1;
+		ve >>= 1;
+		vt >>= 1;
+	}
+	memset (cr, 0, sizeof (cr));
+	cr[0x00] = 0xff & (ht - 5);
+	cr[0x01] = hd - 1;	/* soll:4f ist 59 */
+	cr[0x02] = hd;
+	cr[0x03] = (hbe & 0x1F) | 0x80;	/* hd + ht - hd  */
+	cr[0x04] = hs;
+	cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+	cr[0x06] = (vt - 2) & 0xFF;
+	cr[0x30] = (vt - 2) >> 8;
+	cr[0x07] = ((vt & 0x100) >> 8)
+	    | ((vd & 0x100) >> 7)
+	    | ((vs & 0x100) >> 6)
+	    | ((vs & 0x100) >> 5)
+	    | ((LineCompare & 0x100) >> 4)
+	    | ((vt & 0x200) >> 4)
+	    | ((vd & 0x200) >> 3)
+	    | ((vs & 0x200) >> 2);
+	cr[0x08] = 0x00;
+	cr[0x09] = (dblscan << 7)
+	    | ((LineCompare & 0x200) >> 3)
+	    | ((vs & 0x200) >> 4)
+	    | (TextScanLines - 1);
+	cr[0x10] = vs & 0xff;	/* VSyncPulseStart */
+	cr[0x32] = (vs & 0xf00) >> 8;	/* VSyncPulseStart */
+	cr[0x11] = (ve & 0x0f);	/* | 0x20;      */
+	cr[0x12] = (vd - 1) & 0xff;	/* LineCount  */
+	cr[0x31] = ((vd - 1) & 0xf00) >> 8;	/* LineCount */
+	cr[0x13] = wd & 0xff;
+	cr[0x41] = (wd & 0xf00) >> 8;
+	cr[0x15] = vs & 0xff;
+	cr[0x33] = (vs & 0xf00) >> 8;
+	cr[0x38] = (0x100 & (ht - 5)) >> 8;
+	cr[0x3C] = 0xc0 & hbe;
+	cr[0x16] = (vt - 1) & 0xff;	/* vbe - docu wants vt here, */
+	cr[0x17] = 0xe3;	/* but it does not work */
+	cr[0x18] = 0xff & LineCompare;
+	cr[0x22] = 0xff;	/* todo? */
+	cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00;	/* check:0xa6  */
+	cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6)
+	    | (BlDelayCtrl << 5)
+	    | ((0x03 & CompSyncCharClkDelay) << 3)
+	    | (0x07 & CompSyncPixelClkDelay);	/* todo: see XR82 */
+	cr[0x72] = HorizontalSerration1Start;
+	cr[0x73] = HorizontalSerration2Start;
+	cr[0x74] = (HorizontalEqualizationPulses << 5)
+	    | NTSC_PAL_HorizontalPulseWidth;
+	/* todo: ct69000 has also 0x75-79 */
+	/* now set the registers */
+	for (i = 0; i <= 0x0d; i++) {	/*CR00 .. CR0D */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	for (i = 0x10; i <= 0x18; i++) {	/*CR10 .. CR18 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	i = 0x22;		/*CR22 */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	for (i = 0x30; i <= 0x33; i++) {	/*CR30 .. CR33 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	i = 0x38;		/*CR38 */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	i = 0x3C;		/*CR3C */
+	ctWrite_i (CT_CR_O, i, cr[i]);
+	for (i = 0x40; i <= 0x41; i++) {	/*CR40 .. CR41 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	for (i = 0x70; i <= 0x74; i++) {	/*CR70 .. CR74 */
+		ctWrite_i (CT_CR_O, i, cr[i]);
+	}
+	tmp = ctRead_i (CT_CR_O, 0x40);
+	tmp &= 0x0f;
+	tmp |= 0x80;
+	ctWrite_i (CT_CR_O, 0x40, tmp);	/* StartAddressEnable */
+}
+
+/* pixelclock control */
+
+/*****************************************************************************
+ We have a rational number p/q and need an m/n which is very close to p/q
+ but has m and n within mnmin and mnmax. We have no floating point in the
+ kernel. We can use long long without divide. And we have time to compute...
+******************************************************************************/
+static unsigned int
+FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin,
+		     unsigned int mnmax, unsigned int *pm, unsigned int *pn)
+{
+	/* this code is not for general purpose usable but good for our number ranges */
+	unsigned int n = mnmin, m = 0;
+	long long int L = 0, P = p, Q = q, H = P >> 1;
+	long long int D = 0x7ffffffffffffffLL;
+	for (n = mnmin; n <= mnmax; n++) {
+		m = mnmin;	/* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */
+		L = P * n - m * Q;	/* n * vco - m * fref should be near 0 */
+		while (L > 0 && m < mnmax) {
+			L -= q;	/* difference is greater as 0 subtract fref */
+			m++;	/* and increment m */
+		}
+		/* difference is less or equal than 0 or m > maximum */
+		if (m > mnmax)
+			break;	/* no solution: if we increase n we get the same situation */
+		/* L is <= 0 now */
+		if (-L > H && m > mnmin) {	/* if difference > the half fref */
+			L += q;	/* we take the situation before */
+			m--;	/* because its closer to 0 */
+		}
+		L = (L < 0) ? -L : +L;	/* absolute value */
+		if (D < L)	/* if last difference was better take next n */
+			continue;
+		D = L;
+		*pm = m;
+		*pn = n;	/*  keep improved data */
+		if (D == 0)
+			break;	/* best result we can get */
+	}
+	return (unsigned int) (0xffffffff & D);
+}
+
+/* that is the hardware < 69000 we have to manage
+ +---------+  +-------------------+  +----------------------+  +--+
+ | REFCLK  |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__
+ | 14.3MHz |  |(NTSCDS) (÷1, ÷5)  |  |Select (RDS) (÷1, ÷4) |  |  |  |
+ +---------+  +-------------------+  +----------------------+  +--+  |
+  ___________________________________________________________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷4, ÷16) |
+      +--+   +---------------+
+****************************************************************************
+  that is the hardware >= 69000 we have to manage
+ +---------+  +--+
+ | REFCLK  |__|÷N|__
+ | 14.3MHz |  |  |  |
+ +---------+  +--+  |
+  __________________|
+ |
+ |                                    fvco                      fout
+ | +--------+  +------------+  +-----+     +-------------------+   +----+
+ +-| Phase  |__|Charge Pump |__| VCO |_____|Post Divisor (PD)  |___|CLK |--->
+ +-| Detect |  |& Filter VCO|  |     |  |  |÷1, 2, 4, 8, 16, 32|   |    |
+ | +--------+  +------------+  +-----+  |  +-------------------+   +----+
+ |                                      |
+ |    +--+   +---------------+          |
+ |____|÷M|___|VCO Loop Divide|__________|
+      |  |   |(VLD)(÷1, ÷4)  |
+      +--+   +---------------+
+
+
+*/
+
+#define VIDEO_FREF 14318180;	/* Hz  */
+/*****************************************************************************/
+static int
+ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param)
+{
+	unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock;
+	i = 0;
+	pixclock = -1;
+	fref = VIDEO_FREF;
+	m = ctRead_i (CT_XR_O, 0xc8);
+	n = ctRead_i (CT_XR_O, 0xc9);
+	m -= param->mn_diff;
+	n -= param->mn_diff;
+	xr_cb = ctRead_i (CT_XR_O, 0xcb);
+	PD = (0x70 & xr_cb) >> 4;
+	pd = 1;
+	for (i = 0; i < PD; i++) {
+		pd *= 2;
+	}
+	vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set;
+	if (n * vld * m) {
+		unsigned long long p = 1000000000000LL * pd * n;
+		unsigned long long q = (long long) fref * vld * m;
+		while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) {
+			p >>= 1;	/* can't divide with long long so we scale down */
+			q >>= 1;
+		}
+		pixclock = (unsigned) p / (unsigned) q;
+	} else
+		printf ("Invalid data in xr regs.\n");
+	return pixclock;
+}
+
+/*****************************************************************************/
+static void
+FindAndSetPllParamIntoXrRegs (unsigned int pixelclock,
+			      struct ctfb_chips_properties *param)
+{
+	unsigned int m, n, vld, pd, PD, fref, xr_cb;
+	unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk;
+	unsigned int pfreq, fvco, new_pixclock;
+	unsigned int D,nback,mback;
+
+	fref = VIDEO_FREF;
+	pd = 1;
+	PD = 0;
+	fvcomin = param->vco_min;
+	fvcomax = param->vco_max;	/* MHz */
+	pclckmin = 1000000 / fvcomax + 1;	/*   4546 */
+	pclckmax = 32000000 / fvcomin - 1;	/* 666665 */
+	pclk = minmax (pclckmin, pixelclock, pclckmax);	/* ps pp */
+	pfreq = 250 * (4000000000U / pclk);
+	fvco = pfreq;		/* Hz */
+	new_pixclock = 0;
+	while (fvco < fvcomin * 1000000) {
+		/* double VCO starting with the pixelclock frequency
+		 * as long as it is lower than the minimal VCO frequency */
+		fvco *= 2;
+		pd *= 2;
+		PD++;
+	}
+	/* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */
+	/* first try */
+	vld = param->vld_set;
+	D=FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */
+	mback=m;
+	nback=n;
+	/* second try */
+	vld = param->vld_not_set;
+	if(D<FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n)) {    /* rds = 1 */
+		/* first try was better */
+		m=mback;
+		n=nback;
+		vld = param->vld_set;
+	}
+	m += param->mn_diff;
+	n += param->mn_diff;
+	PRINTF ("VCO %d, pd %d, m %d n %d vld %d \n", fvco, pd, m, n, vld);
+	xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0);
+	/* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be
+	 * written, and in order from XRC8 to XRCB, before the hardware will
+	 * update the synthesizer s settings.
+	 */
+	ctWrite_i (CT_XR_O, 0xc8, m);
+	ctWrite_i (CT_XR_O, 0xc9, n);	/* xrca does not exist in CT69000 and CT69030 */
+	ctWrite_i (CT_XR_O, 0xca, 0);	/* because of a hw bug I guess, but we write */
+	ctWrite_i (CT_XR_O, 0xcb, xr_cb);	/* 0 to it for savety */
+	new_pixclock = ReadPixClckFromXrRegsBack (param);
+	PRINTF ("pixelclock.set = %d, pixelclock.real = %d \n",
+		pixelclock, new_pixclock);
+}
+
+/*****************************************************************************/
+static void
+SetMsrRegs (struct ctfb_res_modes *mode)
+{
+	unsigned char h_synch_high, v_synch_high;
+
+	h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;	/* horizontal Synch High active */
+	v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80;	/* vertical Synch High active */
+	ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29));
+	/* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+	 * Selects the upper 64KB page.Bit5=1
+	 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+	 * Disables CPU access to frame buffer. Bit1=0
+	 * Sets the I/O address decode for ST01, FCR, and all CR registers
+	 * to the 3Dx I/O address range (CGA emulation). Bit0=1
+	 */
+}
+
+/************************************************************************************/
+#ifdef VGA_DUMP_REG
+
+static void
+ctDispRegs (unsigned short index, int from, int to)
+{
+	unsigned char status;
+	int i;
+
+	for (i = from; i < to; i++) {
+		status = ctRead_i (index, i);
+		printf ("%02X: is %02X\n", i, status);
+	}
+}
+
+void
+video_dump_reg (void)
+{
+	int i;
+
+	printf ("Extended Regs:\n");
+	ctDispRegs (CT_XR_O, 0, 0xC);
+	ctDispRegs (CT_XR_O, 0xe, 0xf);
+	ctDispRegs (CT_XR_O, 0x20, 0x21);
+	ctDispRegs (CT_XR_O, 0x40, 0x50);
+	ctDispRegs (CT_XR_O, 0x60, 0x64);
+	ctDispRegs (CT_XR_O, 0x67, 0x68);
+	ctDispRegs (CT_XR_O, 0x70, 0x72);
+	ctDispRegs (CT_XR_O, 0x80, 0x83);
+	ctDispRegs (CT_XR_O, 0xA0, 0xB0);
+	ctDispRegs (CT_XR_O, 0xC0, 0xD3);
+	printf ("Sequencer Regs:\n");
+	ctDispRegs (CT_SR_O, 0, 0x8);
+	printf ("Graphic Regs:\n");
+	ctDispRegs (CT_GR_O, 0, 0x9);
+	printf ("CRT Regs:\n");
+	ctDispRegs (CT_CR_O, 0, 0x19);
+	ctDispRegs (CT_CR_O, 0x22, 0x23);
+	ctDispRegs (CT_CR_O, 0x30, 0x34);
+	ctDispRegs (CT_CR_O, 0x38, 0x39);
+	ctDispRegs (CT_CR_O, 0x3C, 0x3D);
+	ctDispRegs (CT_CR_O, 0x40, 0x42);
+	ctDispRegs (CT_CR_O, 0x70, 0x80);
+	/* don't display the attributes */
+}
+
+#endif
+
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/***************************************************************
+ * Set Hardware Cursor in Pixel
+ */
+void
+video_set_hw_cursor (int x, int y)
+{
+	int sig_x = 0, sig_y = 0;
+	if (x < 0) {
+		x *= -1;
+		sig_x = 1;
+	}
+	if (y < 0) {
+		y *= -1;
+		sig_y = 1;
+	}
+	ctWrite_i (CT_XR_O, 0xa4, x & 0xff);
+	ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7);
+	ctWrite_i (CT_XR_O, 0xa6, y & 0xff);
+	ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7);
+}
+
+/***************************************************************
+ * Init Hardware Cursor. To know the size of the Cursor,
+ * we have to know the Font size.
+ */
+void
+video_init_hw_cursor (int font_width, int font_height)
+{
+	unsigned char xr_80;
+	unsigned long *curs, pattern;
+	int i;
+	int cursor_start;
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	cursor_start = pGD->dprBase;
+	xr_80 = ctRead_i (CT_XR_O, 0x80);
+	/* set start address */
+	ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0);
+	ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f);
+	/* set cursor shape */
+	curs = (unsigned long *) cursor_start;
+	i = 0;
+	while (i < 0x400) {
+		curs[i++] = 0xffffffff;	/* AND mask */
+		curs[i++] = 0xffffffff;	/* AND mask */
+		curs[i++] = 0;	/* XOR mask */
+		curs[i++] = 0;	/* XOR mask */
+		/* Transparent */
+	}
+	pattern = 0xffffffff >> font_width;
+	i = 0;
+	while (i < (font_height * 2)) {
+		curs[i++] = pattern;	/* AND mask */
+		curs[i++] = pattern;	/* AND mask */
+		curs[i++] = 0;	/* XOR mask */
+		curs[i++] = 0;	/* XOR mask */
+		/* Cursor Color 0 */
+	}
+	/* set blink rate */
+	ctWrite_i (CT_FP_O, 0x19, 0xf);
+
+	/* set cursors colors */
+	xr_80 = ctRead_i (CT_XR_O, 0x80);
+	xr_80 |= 0x1;		/* alternate palette select */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL);
+	/* position 4 is color 0 cursor 0 */
+	xr_80 &= 0xfe;		/* normal palette select */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	/* cursor enable */
+	ctWrite_i (CT_XR_O, 0xa0, 0x91);
+	xr_80 |= 0x10;		/* enable hwcursor */
+	ctWrite_i (CT_XR_O, 0x80, xr_80);
+	video_set_hw_cursor (0, 0);
+}
+#endif				/* CONFIG_VIDEO_HW_CURSOR */
+
+/***************************************************************
+ * Wait for BitBlt ready
+ */
+static int
+video_wait_bitblt (unsigned long addr)
+{
+	unsigned long br04;
+	int i = 0;
+	br04 = in32r (addr);
+	while (br04 & 0x80000000) {
+		udelay (1);
+		br04 = in32r (addr);
+		if (i++ > 1000000) {
+			printf ("ERROR Timeout %lx\n", br04);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/***************************************************************
+ * Set up BitBlt Registrs
+ */
+static void
+SetDrawingEngine (int bits_per_pixel)
+{
+	unsigned long br04, br00;
+	unsigned char tmp;
+
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+
+	tmp = ctRead_i (CT_XR_O, 0x20);	/* BitBLT Configuration */
+	tmp |= 0x02;		/* reset BitBLT */
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	udelay (10);
+	tmp &= 0xfd;		/* release reset BitBLT */
+	ctWrite_i (CT_XR_O, 0x20, tmp);	/* BitBLT Configuration */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+
+	/* set pattern Address */
+	out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8);
+	br04 = 0;
+	if (bits_per_pixel == 1) {
+		br04 |= 0x00040000;	/* monochome Pattern */
+		br04 |= 0x00001000;	/* monochome source */
+	}
+	br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP);	/* bytes per scanline */
+	out32r (pGD->pciBase + BR00_o, br00);	/* */
+	out32r (pGD->pciBase + BR08_o, (10 << 16) + 10);	/* dummy */
+	out32r (pGD->pciBase + BR04_o, br04);	/* write all 0 */
+	out32r (pGD->pciBase + BR07_o, 0);	/* destination */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/****************************************************************************
+* supported Video Chips
+*/
+static struct pci_device_id supported[] = {
+	{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000},
+#ifdef CONFIG_USE_CPCIDVI
+	{PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030},
+#endif
+	{}
+};
+
+/*******************************************************************************
+*
+* Init video chip
+*/
+void *
+video_hw_init (void)
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned short device_id;
+	pci_dev_t devbusfn;
+	int videomode;
+	unsigned long t1, hsynch, vsynch;
+	unsigned int pci_mem_base, *vm;
+	int tmp, i, bits_per_pixel;
+	char *penv;
+	struct ctfb_res_modes *res_mode;
+	struct ctfb_res_modes var_mode;
+	struct ctfb_chips_properties *chips_param;
+	/* Search for video chip */
+
+	if ((devbusfn = pci_find_devices (supported, 0)) < 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+		printf ("Video: Controller not found !\n");
+#endif
+		return (NULL);
+	}
+
+	/* PCI setup */
+	pci_write_config_dword (devbusfn, PCI_COMMAND,
+				(PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+	pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+	pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+	/* get chips params */
+	for (chips_param = (struct ctfb_chips_properties *) &chips[0];
+	     chips_param->device_id != 0; chips_param++) {
+		if (chips_param->device_id == device_id)
+			break;
+	}
+	if (chips_param->device_id == 0) {
+#ifdef CONFIG_VIDEO_ONBOARD
+		printf ("Video: controller 0x%X not supported\n", device_id);
+#endif
+		return NULL;
+	}
+	/* supported Video controller found */
+	printf ("Video: ");
+
+	tmp = 0;
+	videomode = 0x301;
+	/* get video mode via environment */
+	if ((penv = getenv ("videomode")) != NULL) {
+		/* deceide if it is a string */
+		if (penv[0] <= '9') {
+			videomode = (int) simple_strtoul (penv, NULL, 16);
+			tmp = 1;
+		}
+	} else {
+		tmp = 1;
+	}
+	if (tmp) {
+		/* parameter are vesa modes */
+		/* search params */
+		for (i = 0; i < VESA_MODES_COUNT; i++) {
+			if (vesa_modes[i].vesanr == videomode)
+				break;
+		}
+		if (i == VESA_MODES_COUNT) {
+			printf ("no VESA Mode found, switching to mode 0x301 ");
+			i = 0;
+		}
+		res_mode =
+		    (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+							     resindex];
+		bits_per_pixel = vesa_modes[i].bits_per_pixel;
+	} else {
+
+		res_mode = (struct ctfb_res_modes *) &var_mode;
+		bits_per_pixel = video_get_params (res_mode, penv);
+	}
+
+	/* calculate available color depth for controller memory */
+	if (bits_per_pixel == 15)
+		tmp = 2;
+	else
+		tmp = bits_per_pixel >> 3;	/* /8 */
+	if (((chips_param->max_mem -
+	      ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) {
+		tmp =
+		    ((chips_param->max_mem -
+		      ACCELMEMORY) / (res_mode->xres * res_mode->yres));
+		if (tmp == 0) {
+			printf
+			    ("No matching videomode found .-> reduce resolution\n");
+			return NULL;
+		} else {
+			printf ("Switching back to %d Bits per Pixel ",
+				tmp << 3);
+			bits_per_pixel = tmp << 3;
+		}
+	}
+
+	/* calculate hsynch and vsynch freq (info only) */
+	t1 = (res_mode->left_margin + res_mode->xres +
+	      res_mode->right_margin + res_mode->hsync_len) / 8;
+	t1 *= 8;
+	t1 *= res_mode->pixclock;
+	t1 /= 1000;
+	hsynch = 1000000000L / t1;
+	t1 *=
+	    (res_mode->upper_margin + res_mode->yres +
+	     res_mode->lower_margin + res_mode->vsync_len);
+	t1 /= 1000;
+	vsynch = 1000000000L / t1;
+
+	/* fill in Graphic device struct */
+	sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+		 res_mode->yres, bits_per_pixel, (hsynch / 1000),
+		 (vsynch / 1000));
+	printf ("%s\n", pGD->modeIdent);
+	pGD->winSizeX = res_mode->xres;
+	pGD->winSizeY = res_mode->yres;
+	pGD->plnSizeX = res_mode->xres;
+	pGD->plnSizeY = res_mode->yres;
+	switch (bits_per_pixel) {
+	case 8:
+		pGD->gdfBytesPP = 1;
+		pGD->gdfIndex = GDF__8BIT_INDEX;
+		break;
+	case 15:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_15BIT_555RGB;
+		break;
+	case 16:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_16BIT_565RGB;
+		break;
+	case 24:
+		pGD->gdfBytesPP = 3;
+		pGD->gdfIndex = GDF_24BIT_888RGB;
+		break;
+	}
+	pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS;
+	pGD->pciBase = pci_mem_base;
+	pGD->frameAdrs = pci_mem_base;
+	pGD->memSize = chips_param->max_mem;
+	/* Cursor Start Address */
+	pGD->dprBase =
+	    (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base;
+	if ((pGD->dprBase & 0x0fff) != 0) {
+		/* allign it */
+		pGD->dprBase &= 0xfffff000;
+		pGD->dprBase += 0x00001000;
+	}
+	PRINTF ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
+		PATTERN_ADR);
+	pGD->vprBase = pci_mem_base;	/* Dummy */
+	pGD->cprBase = pci_mem_base;	/* Dummy */
+	/* set up Hardware */
+
+#ifdef CONFIG_USE_CPCIDVI
+	if (device_id == PCI_DEVICE_ID_CT_69030) {
+		ctWrite (CT_MSR_W_O, 0x0b);
+		ctWrite (0x3cd, 0x13);
+		ctWrite_i (CT_FP_O, 0x02, 0x00);
+		ctWrite_i (CT_FP_O, 0x05, 0x00);
+		ctWrite_i (CT_FP_O, 0x06, 0x00);
+		ctWrite (0x3c2, 0x0b);
+		ctWrite_i (CT_FP_O, 0x02, 0x10);
+		ctWrite_i (CT_FP_O, 0x01, 0x09);
+	} else {
+		ctWrite (CT_MSR_W_O, 0x01);
+	}
+#else
+	ctWrite (CT_MSR_W_O, 0x01);
+#endif
+
+	/* set the extended Registers */
+	ctLoadRegs (CT_XR_O, xreg);
+	/* set atribute registers */
+	SetArRegs ();
+	/* set Graphics register */
+	SetGrRegs ();
+	/* set sequencer */
+	SetSrRegs ();
+
+	/* set msr */
+	SetMsrRegs (res_mode);
+
+	/* set CRT Registers */
+	SetCrRegs (res_mode, bits_per_pixel);
+	/* set color mode */
+	SetBitsPerPixelIntoXrRegs (bits_per_pixel);
+
+	/* set PLL */
+	FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param);
+
+	ctWrite_i (CT_SR_O, 0, 0x03);	/* clear synchronous reset */
+	/* Clear video memory */
+	i = pGD->memSize / 4;
+	vm = (unsigned int *) pGD->pciBase;
+	while (i--)
+		*vm++ = 0;
+	SetDrawingEngine (bits_per_pixel);
+#ifdef VGA_DUMP_REG
+	video_dump_reg ();
+#endif
+
+	return ((void *) &ctfb);
+}
+
+ /*******************************************************************************
+*
+* Set a RGB color in the LUT (8 bit index)
+*/
+void
+video_set_lut (unsigned int index,	/* color number */
+	       unsigned char r,	/* red */
+	       unsigned char g,	/* green */
+	       unsigned char b	/* blue */
+    )
+{
+
+	ctWrite (CT_LUT_MASK_O, 0xff);
+
+	ctWrite (CT_LUT_START_O, (char) index);
+
+	ctWrite (CT_LUT_RGB_O, r);	/* red */
+	ctWrite (CT_LUT_RGB_O, g);	/* green */
+	ctWrite (CT_LUT_RGB_O, b);	/* blue */
+	udelay (1);
+	ctWrite (CT_LUT_MASK_O, 0xff);
+}
+
+/*******************************************************************************
+*
+* Drawing engine fill on screen region
+*/
+void
+video_hw_rectfill (unsigned int bpp,	/* bytes per pixel */
+		   unsigned int dst_x,	/* dest pos x */
+		   unsigned int dst_y,	/* dest pos y */
+		   unsigned int dim_x,	/* frame width */
+		   unsigned int dim_y,	/* frame height */
+		   unsigned int color	/* fill color */
+    )
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned long *p, br04;
+
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+
+	p = (unsigned long *) PATTERN_ADR;
+	dim_x *= bpp;
+	if (bpp == 3)
+		bpp++;		/* 24Bit needs a 32bit pattern */
+	memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8));	/* 8 x 8 pattern data */
+	out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);	/* destination */
+	br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00;
+	br04 |= 0xF0;		/* write Pattern P -> D */
+	out32r (pGD->pciBase + BR04_o, br04);	/* */
+	out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);	/* starts the BITBlt */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+/*******************************************************************************
+*
+* Drawing engine bitblt with screen region
+*/
+void
+video_hw_bitblt (unsigned int bpp,	/* bytes per pixel */
+		 unsigned int src_x,	/* source pos x */
+		 unsigned int src_y,	/* source pos y */
+		 unsigned int dst_x,	/* dest pos x */
+		 unsigned int dst_y,	/* dest pos y */
+		 unsigned int dim_x,	/* frame width */
+		 unsigned int dim_y	/* frame height */
+    )
+{
+	GraphicDevice *pGD = (GraphicDevice *) & ctfb;
+	unsigned long br04;
+
+	br04 = in32r (pGD->pciBase + BR04_o);
+
+	/* to prevent data corruption due to overlap, we have to
+	 * find out if, and how the frames overlaps */
+	if (src_x < dst_x) {
+		/* src is more left than dest
+		 * the frame may overlap -> start from right to left */
+		br04 |= 0x00000100;	/* set bit 8 */
+		src_x += dim_x;
+		dst_x += dim_x;
+	} else {
+		br04 &= 0xfffffeff;	/* clear bit 8 left to right */
+	}
+	if (src_y < dst_y) {
+		/* src is higher than dst
+		 * the frame may overlap => start from bottom */
+		br04 |= 0x00000200;	/* set bit 9 */
+		src_y += dim_y;
+		dst_y += dim_y;
+	} else {
+		br04 &= 0xfffffdff;	/* clear bit 9 top to bottom */
+	}
+	dim_x *= bpp;
+	out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP);	/* source */
+	out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP);	/* destination */
+	br04 &= 0xffffff00;
+	br04 |= 0x000000CC;	/* S -> D */
+	out32r (pGD->pciBase + BR04_o, br04);	/* */
+	out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x);	/* start the BITBlt */
+	video_wait_bitblt (pGD->pciBase + BR04_o);
+}
+
+#endif				/* CONFIG_CT69000 */
+
+#endif				/* CONFIG_VIDEO */
diff --git a/drivers/video/sed13806.c b/drivers/video/sed13806.c
new file mode 100644
index 0000000..6996ca8
--- /dev/null
+++ b/drivers/video/sed13806.c
@@ -0,0 +1,310 @@
+/*
+ * (C) Copyright 2002
+ * Stäubli Faverges - <www.staubli.com>
+ * Pierre AUBERT  p.aubert@staubli.com
+ *
+ * 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
+ */
+/* Video support for Epson SED13806 chipset                                  */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO_SED13806
+
+#include <video_fb.h>
+#include <sed13806.h>
+
+#define readByte(ptrReg)                \
+    *(volatile unsigned char *)(sed13806.isaBase + ptrReg)
+
+#define writeByte(ptrReg,value) \
+    *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value
+
+#ifdef CONFIG_TOTAL5200
+#define writeWord(ptrReg,value) \
+    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = value)
+#else
+#define writeWord(ptrReg,value) \
+    (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00))
+#endif
+
+GraphicDevice sed13806;
+
+/*-----------------------------------------------------------------------------
+ * EpsonSetRegs --
+ *-----------------------------------------------------------------------------
+ */
+static void EpsonSetRegs (void)
+{
+    /* the content of the chipset register depends on the board (clocks, ...)*/
+    const S1D_REGS *preg = board_get_regs ();
+    while (preg -> Index) {
+	writeByte (preg -> Index, preg -> Value);
+	preg ++;
+    }
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_init --
+ *-----------------------------------------------------------------------------
+ */
+void *video_hw_init (void)
+{
+    unsigned int *vm, i;
+
+    memset (&sed13806, 0, sizeof (GraphicDevice));
+
+    /* Initialization of the access to the graphic chipset
+       Retreive base address of the chipset
+       (see board/RPXClassic/eccx.c)                                         */
+    if ((sed13806.isaBase = board_video_init ()) == 0) {
+	return (NULL);
+    }
+
+    sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET;
+    sed13806.winSizeX = board_get_width ();
+    sed13806.winSizeY = board_get_height ();
+
+#if defined(CONFIG_VIDEO_SED13806_8BPP)
+    sed13806.gdfIndex = GDF__8BIT_INDEX;
+    sed13806.gdfBytesPP = 1;
+
+#elif defined(CONFIG_VIDEO_SED13806_16BPP)
+    sed13806.gdfIndex = GDF_16BIT_565RGB;
+    sed13806.gdfBytesPP = 2;
+
+#else
+#error Unsupported SED13806 BPP
+#endif
+
+    sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP;
+
+    /* Load SED registers                                                    */
+    EpsonSetRegs ();
+
+    /* (see board/RPXClassic/RPXClassic.c)                                   */
+    board_validate_screen (sed13806.isaBase);
+
+    /* Clear video memory */
+    i = sed13806.memSize/4;
+    vm = (unsigned int *)sed13806.frameAdrs;
+    while(i--)
+	*vm++ = 0;
+
+
+    return (&sed13806);
+}
+/*-----------------------------------------------------------------------------
+ * Epson_wait_idle -- Wait for hardware to become idle
+ *-----------------------------------------------------------------------------
+ */
+static void Epson_wait_idle (void)
+{
+    while (readByte (BLT_CTRL0) & 0x80);
+
+    /* Read a word in the BitBLT memory area to shutdown the BitBLT engine   */
+    *(volatile unsigned short *)(sed13806.isaBase + BLT_REG);
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_bitblt --
+ *-----------------------------------------------------------------------------
+ */
+void video_hw_bitblt (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int src_x,           /* source pos x */
+    unsigned int src_y,           /* source pos y */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y            /* frame height */
+    )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
+    unsigned long	srcAddr, dstAddr;
+    unsigned int stride = bpp * pGD -> winSizeX;
+
+    srcAddr = (src_y * stride) + (src_x * bpp);
+    dstAddr = (dst_y * stride) + (dst_x * bpp);
+
+    Epson_wait_idle ();
+
+    writeByte(BLT_ROP,0x0C);	/* source */
+    writeByte(BLT_OP,0x02);/* move blit in positive direction with ROP */
+    writeWord(BLT_MEM_OFF0, stride / 2);
+    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
+	writeByte(BLT_CTRL1,0x00);
+    }
+    else {
+	writeByte(BLT_CTRL1,0x01);
+    }
+
+    writeWord(BLT_WIDTH0,(dim_x - 1));
+    writeWord(BLT_HEIGHT0,(dim_y - 1));
+
+    /* set up blit registers                                                 */
+    writeByte(BLT_SRC_ADDR0,srcAddr);
+    writeByte(BLT_SRC_ADDR1,srcAddr>>8);
+    writeByte(BLT_SRC_ADDR2,srcAddr>>16);
+
+    writeByte(BLT_DST_ADDR0,dstAddr);
+    writeByte(BLT_DST_ADDR1,dstAddr>>8);
+    writeByte(BLT_DST_ADDR2,dstAddr>>16);
+
+    /* Engage the blt engine                                                 */
+    /* rectangular region for src and dst                                    */
+    writeByte(BLT_CTRL0,0x80);
+
+    /* wait untill current blits finished                                    */
+    Epson_wait_idle ();
+}
+/*-----------------------------------------------------------------------------
+ * video_hw_rectfill --
+ *-----------------------------------------------------------------------------
+ */
+void video_hw_rectfill (
+    unsigned int bpp,             /* bytes per pixel */
+    unsigned int dst_x,           /* dest pos x */
+    unsigned int dst_y,           /* dest pos y */
+    unsigned int dim_x,           /* frame width */
+    unsigned int dim_y,           /* frame height */
+    unsigned int color            /* fill color */
+     )
+{
+    register GraphicDevice *pGD = (GraphicDevice *)&sed13806;
+    unsigned long	dstAddr;
+    unsigned int stride = bpp * pGD -> winSizeX;
+
+    dstAddr = (dst_y * stride) + (dst_x * bpp);
+
+    Epson_wait_idle ();
+
+    /* set up blit registers                                                 */
+    writeByte(BLT_DST_ADDR0,dstAddr);
+    writeByte(BLT_DST_ADDR1,dstAddr>>8);
+    writeByte(BLT_DST_ADDR2,dstAddr>>16);
+
+    writeWord(BLT_WIDTH0,(dim_x - 1));
+    writeWord(BLT_HEIGHT0,(dim_y - 1));
+    writeWord(BLT_FGCOLOR0,color);
+
+    writeByte(BLT_OP,0x0C);  /* solid fill                                   */
+    writeWord(BLT_MEM_OFF0,stride / 2);
+
+    if (pGD -> gdfIndex == GDF__8BIT_INDEX) {
+	writeByte(BLT_CTRL1,0x00);
+    }
+    else {
+	writeByte(BLT_CTRL1,0x01);
+    }
+
+    /* Engage the blt engine                                                 */
+    /* rectangular region for src and dst                                    */
+    writeByte(BLT_CTRL0,0x80);
+
+    /* wait untill current blits finished                                    */
+    Epson_wait_idle ();
+}
+
+/*-----------------------------------------------------------------------------
+ * video_set_lut --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_lut (
+    unsigned int index,           /* color number */
+    unsigned char r,              /* red */
+    unsigned char g,              /* green */
+    unsigned char b               /* blue */
+    )
+{
+    writeByte(REG_LUT_ADDR, index );
+    writeByte(REG_LUT_DATA, r);
+    writeByte(REG_LUT_DATA, g);
+    writeByte(REG_LUT_DATA, b);
+}
+#ifdef CONFIG_VIDEO_HW_CURSOR
+/*-----------------------------------------------------------------------------
+ * video_set_hw_cursor --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_hw_cursor (int x, int y)
+{
+    writeByte (LCD_CURSOR_XL, (x & 0xff));
+    writeByte (LCD_CURSOR_XM, (x >> 8));
+    writeByte (LCD_CURSOR_YL, (y & 0xff));
+    writeByte (LCD_CURSOR_YM, (y >> 8));
+}
+
+/*-----------------------------------------------------------------------------
+ * video_init_hw_cursor --
+ *-----------------------------------------------------------------------------
+ */
+void video_init_hw_cursor (int font_width, int font_height)
+{
+    volatile unsigned char *ptr;
+    unsigned char pattern;
+    int i;
+
+
+    /* Init cursor content
+       Cursor size is 64x64 pixels
+       Start of the cursor memory depends on panel type (dual panel ...)     */
+    if ((i = readByte (LCD_CURSOR_START)) == 0) {
+	ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE);
+    }
+    else {
+	ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192));
+    }
+
+    /* Fill the first line and the first empty line after cursor             */
+    for (i = 0, pattern = 0; i < 64; i++) {
+	if (i < font_width) {
+	    /* Invert background                                             */
+	    pattern |= 0x3;
+
+	}
+	else {
+	    /* Background                                                    */
+	    pattern |= 0x2;
+	}
+	if ((i & 3) == 3) {
+	    *ptr = pattern;
+	    *(ptr + font_height * 16) = 0xaa;
+	    ptr ++;
+	    pattern = 0;
+	}
+	pattern <<= 2;
+    }
+
+    /* Duplicate this line                                                   */
+    for (i = 1; i < font_height; i++) {
+	memcpy ((void *)ptr, (void *)(ptr - 16), 16);
+	ptr += 16;
+    }
+
+    for (; i < 64; i++) {
+	memcpy ((void *)(ptr + 16), (void *)ptr, 16);
+	ptr += 16;
+    }
+
+    /* Select cursor mode                                                    */
+    writeByte (LCD_CURSOR_CNTL, 1);
+}
+#endif
+#endif
diff --git a/drivers/video/sed156x.c b/drivers/video/sed156x.c
new file mode 100644
index 0000000..e9d5ed4
--- /dev/null
+++ b/drivers/video/sed156x.c
@@ -0,0 +1,566 @@
+/*
+ * (C) Copyright 2003
+ *
+ * Pantelis Antoniou <panto@intracom.gr>
+ * Intracom S.A.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <watchdog.h>
+
+#include <sed156x.h>
+
+#ifdef CONFIG_SED156X
+
+/* configure according to the selected display */
+#if defined(CONFIG_SED156X_PG12864Q)
+#define LCD_WIDTH	128
+#define LCD_HEIGHT	64
+#define LCD_LINES	64
+#define LCD_PAGES	9
+#define LCD_COLUMNS	132
+#else
+#error Unsupported SED156x configuration
+#endif
+
+/* include the font data */
+#include <video_font.h>
+
+#if VIDEO_FONT_WIDTH != 8 || VIDEO_FONT_HEIGHT != 16
+#error Expecting VIDEO_FONT_WIDTH == 8 && VIDEO_FONT_HEIGHT == 16
+#endif
+
+#define LCD_BYTE_WIDTH		(LCD_WIDTH / 8)
+#define VIDEO_FONT_BYTE_WIDTH	(VIDEO_FONT_WIDTH / 8)
+
+#define LCD_TEXT_WIDTH	(LCD_WIDTH / VIDEO_FONT_WIDTH)
+#define LCD_TEXT_HEIGHT (LCD_HEIGHT / VIDEO_FONT_HEIGHT)
+
+#define LCD_BYTE_LINESZ		(LCD_BYTE_WIDTH * VIDEO_FONT_HEIGHT)
+
+const int sed156x_text_width = LCD_TEXT_WIDTH;
+const int sed156x_text_height = LCD_TEXT_HEIGHT;
+
+/**************************************************************************************/
+
+#define SED156X_SPI_RXD() (SED156X_SPI_RXD_PORT & SED156X_SPI_RXD_MASK)
+
+#define SED156X_SPI_TXD(x) \
+	do { \
+		if (x) \
+			SED156X_SPI_TXD_PORT |=	 SED156X_SPI_TXD_MASK; \
+		else \
+			SED156X_SPI_TXD_PORT &= ~SED156X_SPI_TXD_MASK; \
+	} while(0)
+
+#define SED156X_SPI_CLK(x) \
+	do { \
+		if (x) \
+			SED156X_SPI_CLK_PORT |=	 SED156X_SPI_CLK_MASK; \
+		else \
+			SED156X_SPI_CLK_PORT &= ~SED156X_SPI_CLK_MASK; \
+	} while(0)
+
+#define SED156X_SPI_CLK_TOGGLE() (SED156X_SPI_CLK_PORT ^= SED156X_SPI_CLK_MASK)
+
+#define SED156X_SPI_BIT_DELAY() /* no delay */
+
+#define SED156X_CS(x) \
+	do { \
+		if (x) \
+			SED156X_CS_PORT |=  SED156X_CS_MASK; \
+		else \
+			SED156X_CS_PORT &= ~SED156X_CS_MASK; \
+	} while(0)
+
+#define SED156X_A0(x) \
+	do { \
+		if (x) \
+			SED156X_A0_PORT |=  SED156X_A0_MASK; \
+		else \
+			SED156X_A0_PORT &= ~SED156X_A0_MASK; \
+	} while(0)
+
+/**************************************************************************************/
+
+/*** LCD Commands ***/
+
+#define LCD_ON		0xAF	/* Display ON					      */
+#define LCD_OFF		0xAE	/* Display OFF					      */
+#define LCD_LADDR	0x40	/* Display start line set + (6-bit) address	      */
+#define LCD_PADDR	0xB0	/* Page address set + (4-bit) page		      */
+#define LCD_CADRH	0x10	/* Column address set upper + (4-bit) column hi	      */
+#define LCD_CADRL	0x00	/* Column address set lower + (4-bit) column lo	      */
+#define LCD_ADC_NRM	0xA0	/* ADC select Normal				      */
+#define LCD_ADC_REV	0xA1	/* ADC select Reverse				      */
+#define LCD_DSP_NRM	0xA6	/* LCD display Normal				      */
+#define LCD_DSP_REV	0xA7	/* LCD display Reverse				      */
+#define LCD_DPT_NRM	0xA4	/* Display all points Normal			      */
+#define LCD_DPT_ALL	0xA5	/* Display all points ON			      */
+#define LCD_BIAS9	0xA2	/* LCD bias set 1/9				      */
+#define LCD_BIAS7	0xA3	/* LCD bias set 1/7				      */
+#define LCD_CAINC	0xE0	/* Read/modify/write				      */
+#define LCD_CAEND	0xEE	/* End						      */
+#define LCD_RESET	0xE2	/* Reset					      */
+#define LCD_C_NRM	0xC0	/* Common output mode select Normal direction	      */
+#define LCD_C_RVS	0xC8	/* Common output mode select Reverse direction	      */
+#define LCD_PWRMD	0x28	/* Power control set + (3-bit) mode		      */
+#define LCD_RESRT	0x20	/* V5 v. reg. int. resistor ratio set + (3-bit) ratio */
+#define LCD_EVSET	0x81	/* Electronic volume mode set + byte = (6-bit) volume */
+#define LCD_SIOFF	0xAC	/* Static indicator OFF				      */
+#define LCD_SION	0xAD	/* Static indicator ON + byte = (2-bit) mode	      */
+#define LCD_NOP		0xE3	/* NOP						      */
+#define LCD_TEST	0xF0	/* Test/Test mode reset (Note: *DO NOT USE*)	      */
+
+/*-------------------------------------------------------------------------------
+  Compound commands
+  -------------------------------------------------------------------------------
+  Command	Description			Commands
+  ----------	------------------------	-------------------------------------
+  POWS_ON	POWER SAVER ON command		LCD_OFF, LCD_D_ALL
+  POWS_OFF	POWER SAVER OFF command		LCD_D_NRM
+  SLEEPON	SLEEP mode			LCD_SIOFF, POWS_ON
+  SLEEPOFF	SLEEP mode cancel		LCD_D_NRM, LCD_SION, LCD_SIS_???
+  STDBYON	STAND BY mode			LCD_SION, POWS_ON
+  STDBYOFF	STAND BY mode cancel		LCD_D_NRM
+  -------------------------------------------------------------------------------*/
+
+/*** LCD various parameters ***/
+#define LCD_PPB		8	/* Pixels per byte (display is B/W, 1 bit per pixel) */
+
+/*** LCD Status byte masks ***/
+#define LCD_S_BUSY	0x80	/* Status Read - BUSY mask   */
+#define LCD_S_ADC	0x40	/* Status Read - ADC mask    */
+#define LCD_S_ONOFF	0x20	/* Status Read - ON/OFF mask */
+#define LCD_S_RESET	0x10	/* Status Read - RESET mask  */
+
+/*** LCD commands parameter masks ***/
+#define LCD_M_LADDR	0x3F	/* Display start line (6-bit) address mask	     */
+#define LCD_M_PADDR	0x0F	/* Page address (4-bit) page mask		     */
+#define LCD_M_CADRH	0x0F	/* Column address upper (4-bit) column hi mask	     */
+#define LCD_M_CADRL	0x0F	/* Column address lower (4-bit) column lo mask	     */
+#define LCD_M_PWRMD	0x07	/* Power control (3-bit) mode mask		     */
+#define LCD_M_RESRT	0x07	/* V5 v. reg. int. resistor ratio (3-bit) ratio mask */
+#define LCD_M_EVSET	0x3F	/* Electronic volume mode byte (6-bit) volume mask   */
+#define LCD_M_SION	0x03	/* Static indicator ON (2-bit) mode mask	     */
+
+/*** LCD Power control cirquits control masks ***/
+#define LCD_PWRBSTR	0x04	/* Power control mode - Booster cirquit ON	     */
+#define LCD_PWRVREG	0x02	/* Power control mode - Voltage regulator cirquit ON */
+#define LCD_PWRVFOL	0x01	/* Power control mode - Voltage follower cirquit ON  */
+
+/*** LCD Static indicator states ***/
+#define LCD_SIS_OFF	0x00	/* Static indicator register set - OFF state		 */
+#define LCD_SIS_BL	0x01	/* Static indicator register set - 1s blink state	 */
+#define LCD_SIS_RBL	0x02	/* Static indicator register set - .5s rapid blink state */
+#define LCD_SIS_ON	0x03	/* Static indicator register set - constantly on state	 */
+
+/*** LCD functions special parameters (commands) ***/
+#define LCD_PREVP	0x80	/* Page number for moving to previous */
+#define LCD_NEXTP	0x81	/* or next page */
+#define LCD_ERR_P	0xFF	/* Error in page number */
+
+/*** LCD initialization settings ***/
+#define LCD_BIAS	LCD_BIAS9	/* Bias: 1/9		      */
+#define LCD_ADCMODE	LCD_ADC_NRM	/* ADC mode: normal	      */
+#define LCD_COMDIR	LCD_C_NRM	/* Common output mode: normal */
+#define LCD_RRATIO	0		/* Resistor ratio: 0	      */
+#define LCD_CNTRST	0x1C		/* electronic volume: 1Ch     */
+#define LCD_POWERM	(LCD_PWRBSTR | LCD_PWRVREG | LCD_PWRVFOL)	/* Power mode: All on */
+
+/**************************************************************************************/
+
+static inline unsigned int sed156x_transfer(unsigned int val)
+{
+	unsigned int rx;
+	int b;
+
+	rx = 0; b = 8;
+	while (--b >= 0) {
+		SED156X_SPI_TXD(val & 0x80);
+		val <<= 1;
+		SED156X_SPI_CLK_TOGGLE();
+		SED156X_SPI_BIT_DELAY();
+		rx <<= 1;
+		if (SED156X_SPI_RXD())
+			rx |= 1;
+		SED156X_SPI_CLK_TOGGLE();
+		SED156X_SPI_BIT_DELAY();
+	}
+
+	return rx;
+}
+
+unsigned int sed156x_data_transfer(unsigned int val)
+{
+	unsigned int rx;
+
+	SED156X_SPI_CLK(1);
+	SED156X_CS(0);
+	SED156X_A0(1);
+
+	rx = sed156x_transfer(val);
+
+	SED156X_CS(1);
+
+	return rx;
+}
+
+void sed156x_data_block_transfer(const u8 *p, int size)
+{
+	SED156X_SPI_CLK(1);
+	SED156X_CS(0);
+	SED156X_A0(1);
+
+	while (--size >= 0)
+		sed156x_transfer(*p++);
+
+	SED156X_CS(1);
+}
+
+unsigned int sed156x_cmd_transfer(unsigned int val)
+{
+	unsigned int rx;
+
+	SED156X_SPI_CLK(1);
+	SED156X_CS(0);
+	SED156X_A0(0);
+
+	rx = sed156x_transfer(val);
+
+	SED156X_CS(1);
+	SED156X_A0(1);
+
+	return rx;
+}
+
+/******************************************************************************/
+
+static u8 hw_screen[LCD_PAGES][LCD_COLUMNS];
+static u8 last_hw_screen[LCD_PAGES][LCD_COLUMNS];
+static u8 sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT];
+
+void sed156x_sync(void)
+{
+	int i, j, last_page;
+	u8 *d;
+	const u8 *s, *e, *b, *r;
+	u8 v0, v1, v2, v3, v4, v5, v6, v7;
+
+	/* copy and rotate sw_screen to hw_screen */
+	for (i = 0; i < LCD_HEIGHT / 8; i++) {
+
+		d = &hw_screen[i][0];
+		s = &sw_screen[LCD_BYTE_WIDTH * 8 * i + LCD_BYTE_WIDTH - 1];
+
+		for (j = 0; j < LCD_WIDTH / 8; j++) {
+
+			v0 = s[0 * LCD_BYTE_WIDTH];
+			v1 = s[1 * LCD_BYTE_WIDTH];
+			v2 = s[2 * LCD_BYTE_WIDTH];
+			v3 = s[3 * LCD_BYTE_WIDTH];
+			v4 = s[4 * LCD_BYTE_WIDTH];
+			v5 = s[5 * LCD_BYTE_WIDTH];
+			v6 = s[6 * LCD_BYTE_WIDTH];
+			v7 = s[7 * LCD_BYTE_WIDTH];
+
+			d[0] =	((v7 & 0x01) << 7) |
+				((v6 & 0x01) << 6) |
+				((v5 & 0x01) << 5) |
+				((v4 & 0x01) << 4) |
+				((v3 & 0x01) << 3) |
+				((v2 & 0x01) << 2) |
+				((v1 & 0x01) << 1) |
+				 (v0 & 0x01)	   ;
+
+			d[1] =	((v7 & 0x02) << 6) |
+				((v6 & 0x02) << 5) |
+				((v5 & 0x02) << 4) |
+				((v4 & 0x02) << 3) |
+				((v3 & 0x02) << 2) |
+				((v2 & 0x02) << 1) |
+				((v1 & 0x02) << 0) |
+				((v0 & 0x02) >> 1) ;
+
+			d[2] =	((v7 & 0x04) << 5) |
+				((v6 & 0x04) << 4) |
+				((v5 & 0x04) << 3) |
+				((v4 & 0x04) << 2) |
+				((v3 & 0x04) << 1) |
+				 (v2 & 0x04)	   |
+				((v1 & 0x04) >> 1) |
+				((v0 & 0x04) >> 2) ;
+
+			d[3] =	((v7 & 0x08) << 4) |
+				((v6 & 0x08) << 3) |
+				((v5 & 0x08) << 2) |
+				((v4 & 0x08) << 1) |
+				 (v3 & 0x08)	   |
+				((v2 & 0x08) >> 1) |
+				((v1 & 0x08) >> 2) |
+				((v0 & 0x08) >> 3) ;
+
+			d[4] =	((v7 & 0x10) << 3) |
+				((v6 & 0x10) << 2) |
+				((v5 & 0x10) << 1) |
+				 (v4 & 0x10)	   |
+				((v3 & 0x10) >> 1) |
+				((v2 & 0x10) >> 2) |
+				((v1 & 0x10) >> 3) |
+				((v0 & 0x10) >> 4) ;
+
+			d[5] =	((v7 & 0x20) << 2) |
+				((v6 & 0x20) << 1) |
+				 (v5 & 0x20)	   |
+				((v4 & 0x20) >> 1) |
+				((v3 & 0x20) >> 2) |
+				((v2 & 0x20) >> 3) |
+				((v1 & 0x20) >> 4) |
+				((v0 & 0x20) >> 5) ;
+
+			d[6] =	((v7 & 0x40) << 1) |
+				 (v6 & 0x40)	   |
+				((v5 & 0x40) >> 1) |
+				((v4 & 0x40) >> 2) |
+				((v3 & 0x40) >> 3) |
+				((v2 & 0x40) >> 4) |
+				((v1 & 0x40) >> 5) |
+				((v0 & 0x40) >> 6) ;
+
+			d[7] =	 (v7 & 0x80)	   |
+				((v6 & 0x80) >> 1) |
+				((v5 & 0x80) >> 2) |
+				((v4 & 0x80) >> 3) |
+				((v3 & 0x80) >> 4) |
+				((v2 & 0x80) >> 5) |
+				((v1 & 0x80) >> 6) |
+				((v0 & 0x80) >> 7) ;
+
+			d += 8;
+			s--;
+		}
+	}
+
+	/* and now output only the differences */
+	for (i = 0; i < LCD_PAGES; i++) {
+
+		b = &hw_screen[i][0];
+		e = &hw_screen[i][LCD_COLUMNS];
+
+		d = &last_hw_screen[i][0];
+		s = b;
+
+		last_page = -1;
+
+		/* update only the differences */
+		do {
+			while (s < e && *s == *d) {
+				s++;
+				d++;
+			}
+			if (s == e)
+				break;
+			r = s;
+			while (s < e && *s != *d)
+				*d++ = *s++;
+
+			j = r - b;
+
+			if (i != last_page) {
+				sed156x_cmd_transfer(LCD_PADDR | i);
+				last_page = i;
+			}
+
+			sed156x_cmd_transfer(LCD_CADRH | ((j >> 4) & 0x0F));
+			sed156x_cmd_transfer(LCD_CADRL | (j & 0x0F));
+			sed156x_data_block_transfer(r, s - r);
+
+		} while (s < e);
+	}
+
+/********
+	for (i = 0; i < LCD_PAGES; i++) {
+		sed156x_cmd_transfer(LCD_PADDR | i);
+		sed156x_cmd_transfer(LCD_CADRH | 0);
+		sed156x_cmd_transfer(LCD_CADRL | 0);
+		sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
+	}
+	memcpy(last_hw_screen, hw_screen, sizeof(last_hw_screen));
+********/
+}
+
+void sed156x_clear(void)
+{
+	memset(sw_screen, 0, sizeof(sw_screen));
+}
+
+void sed156x_output_at(int x, int y, const char *str, int size)
+{
+	int i, j;
+	u8 *p;
+	const u8 *s;
+
+	if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
+		return;
+
+	p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
+
+	while (--size >= 0) {
+
+		s = &video_fontdata[((int)*str++ & 0xff) * VIDEO_FONT_BYTE_WIDTH * VIDEO_FONT_HEIGHT];
+		for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
+			for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++)
+				*p++ = *s++;
+			p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
+		}
+		p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
+
+		if (x >= LCD_TEXT_WIDTH)
+			break;
+		x++;
+	}
+}
+
+void sed156x_reverse_at(int x, int y, int size)
+{
+	int i, j;
+	u8 *p;
+
+	if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH)
+		return;
+
+	p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH];
+
+	while (--size >= 0) {
+
+		for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
+			for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++, p++)
+				*p = ~*p;
+			p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH;
+		}
+		p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH);
+
+		if (x >= LCD_TEXT_WIDTH)
+			break;
+		x++;
+	}
+}
+
+void sed156x_scroll_line(void)
+{
+	memmove(&sw_screen[0],
+			&sw_screen[LCD_BYTE_LINESZ],
+			LCD_BYTE_WIDTH * (LCD_HEIGHT - VIDEO_FONT_HEIGHT));
+}
+
+void sed156x_scroll(int dx, int dy)
+{
+	u8 *p1 = NULL, *p2 = NULL, *p3 = NULL;	/* pacify gcc */
+	int adx, ady, i, sz;
+
+	adx = dx > 0 ? dx : -dx;
+	ady = dy > 0 ? dy : -dy;
+
+	/* overscroll? erase everything */
+	if (adx >= LCD_TEXT_WIDTH || ady >= LCD_TEXT_HEIGHT) {
+		memset(sw_screen, 0, sizeof(sw_screen));
+		return;
+	}
+
+	sz = LCD_BYTE_LINESZ * ady;
+	if (dy > 0) {
+		p1 = &sw_screen[0];
+		p2 = &sw_screen[sz];
+		p3 = &sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT - sz];
+	} else if (dy < 0) {
+		p1 = &sw_screen[sz];
+		p2 = &sw_screen[0];
+		p3 = &sw_screen[0];
+	}
+
+	if (ady > 0) {
+		memmove(p1, p2, LCD_BYTE_WIDTH * LCD_HEIGHT - sz);
+		memset(p3, 0, sz);
+	}
+
+	sz = VIDEO_FONT_BYTE_WIDTH * adx;
+	if (dx > 0) {
+		p1 = &sw_screen[0];
+		p2 = &sw_screen[0] + sz;
+		p3 = &sw_screen[0] + LCD_BYTE_WIDTH - sz;
+	} else if (dx < 0) {
+		p1 = &sw_screen[0] + sz;
+		p2 = &sw_screen[0];
+		p3 = &sw_screen[0];
+	}
+
+	/* xscroll */
+	if (adx > 0) {
+		for (i = 0; i < LCD_HEIGHT; i++) {
+			memmove(p1, p2, LCD_BYTE_WIDTH - sz);
+			memset(p3, 0, sz);
+			p1 += LCD_BYTE_WIDTH;
+			p2 += LCD_BYTE_WIDTH;
+			p3 += LCD_BYTE_WIDTH;
+		}
+	}
+}
+
+void sed156x_init(void)
+{
+	int i;
+
+	SED156X_CS(1);
+	SED156X_A0(1);
+
+	/* Send initialization commands to the LCD */
+	sed156x_cmd_transfer(LCD_OFF);			/* Turn display OFF	  */
+	sed156x_cmd_transfer(LCD_BIAS);			/* set the LCD Bias,	  */
+	sed156x_cmd_transfer(LCD_ADCMODE);		/* ADC mode,		  */
+	sed156x_cmd_transfer(LCD_COMDIR);		/* common output mode,	  */
+	sed156x_cmd_transfer(LCD_RESRT | LCD_RRATIO);	/* resistor ratio,	  */
+	sed156x_cmd_transfer(LCD_EVSET);		/* electronic volume,	  */
+	sed156x_cmd_transfer(LCD_CNTRST);
+	sed156x_cmd_transfer(LCD_PWRMD | LCD_POWERM);	/* and power mode	  */
+	sed156x_cmd_transfer(LCD_PADDR | 0);		/* cursor home		  */
+	sed156x_cmd_transfer(LCD_CADRH | 0);
+	sed156x_cmd_transfer(LCD_CADRL | 0);
+	sed156x_cmd_transfer(LCD_LADDR | 0);		/* and display start line */
+	sed156x_cmd_transfer(LCD_DSP_NRM);		/* LCD display Normal	  */
+
+	/* clear everything */
+	memset(sw_screen, 0, sizeof(sw_screen));
+	memset(hw_screen, 0, sizeof(hw_screen));
+	memset(last_hw_screen, 0, sizeof(last_hw_screen));
+
+	for (i = 0; i < LCD_PAGES; i++) {
+		sed156x_cmd_transfer(LCD_PADDR | i);
+		sed156x_cmd_transfer(LCD_CADRH | 0);
+		sed156x_cmd_transfer(LCD_CADRL | 0);
+		sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS);
+	}
+
+	sed156x_clear();
+	sed156x_sync();
+	sed156x_cmd_transfer(LCD_ON);			/* Turn display ON	  */
+}
+
+#endif	/* CONFIG_SED156X */
diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c
new file mode 100644
index 0000000..23db02c
--- /dev/null
+++ b/drivers/video/sm501.c
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2002
+ * Stäubli Faverges - <www.staubli.com>
+ * Pierre AUBERT  p.aubert@staubli.com
+ *
+ * (C) Copyright 2005
+ * Martin Krause TQ-Systems GmbH martin.krause@tqs.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
+ */
+
+/*
+ * Basic video support for SMI SM501 "Voyager" graphic controller
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_VIDEO_SM501
+
+#include <video_fb.h>
+#include <sm501.h>
+
+#define read8(ptrReg)                \
+    *(volatile unsigned char *)(sm501.isaBase + ptrReg)
+
+#define write8(ptrReg,value) \
+    *(volatile unsigned char *)(sm501.isaBase + ptrReg) = value
+
+#define read16(ptrReg) \
+    (*(volatile unsigned short *)(sm501.isaBase + ptrReg))
+
+#define write16(ptrReg,value) \
+    (*(volatile unsigned short *)(sm501.isaBase + ptrReg) = value)
+
+#define read32(ptrReg) \
+    (*(volatile unsigned int *)(sm501.isaBase + ptrReg))
+
+#define write32(ptrReg, value) \
+    (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value)
+
+GraphicDevice sm501;
+
+/*-----------------------------------------------------------------------------
+ * SmiSetRegs --
+ *-----------------------------------------------------------------------------
+ */
+static void SmiSetRegs (void)
+{
+	/*
+	 * The content of the chipset register depends on the board (clocks,
+	 * ...)
+	 */
+	const SMI_REGS *preg = board_get_regs ();
+	while (preg->Index) {
+		write32 (preg->Index, preg->Value);
+		/*
+		 * Insert a delay between
+		 */
+		udelay (1000);
+		preg ++;
+	}
+}
+
+/*-----------------------------------------------------------------------------
+ * video_hw_init --
+ *-----------------------------------------------------------------------------
+ */
+void *video_hw_init (void)
+{
+	unsigned int *vm, i;
+
+	memset (&sm501, 0, sizeof (GraphicDevice));
+
+	/*
+	 * Initialization of the access to the graphic chipset Retreive base
+	 * address of the chipset (see board/RPXClassic/eccx.c)
+	 */
+	if ((sm501.isaBase = board_video_init ()) == 0) {
+		return (NULL);
+	}
+
+	if ((sm501.frameAdrs = board_video_get_fb ()) == 0) {
+		return (NULL);
+	}
+
+	sm501.winSizeX = board_get_width ();
+	sm501.winSizeY = board_get_height ();
+
+#if defined(CONFIG_VIDEO_SM501_8BPP)
+	sm501.gdfIndex = GDF__8BIT_INDEX;
+	sm501.gdfBytesPP = 1;
+
+#elif defined(CONFIG_VIDEO_SM501_16BPP)
+	sm501.gdfIndex = GDF_16BIT_565RGB;
+	sm501.gdfBytesPP = 2;
+
+#elif defined(CONFIG_VIDEO_SM501_32BPP)
+	sm501.gdfIndex = GDF_32BIT_X888RGB;
+	sm501.gdfBytesPP = 4;
+#else
+#error Unsupported SM501 BPP
+#endif
+
+	sm501.memSize = sm501.winSizeX * sm501.winSizeY * sm501.gdfBytesPP;
+
+	/* Load Smi registers */
+	SmiSetRegs ();
+
+	/* (see board/RPXClassic/RPXClassic.c) */
+	board_validate_screen (sm501.isaBase);
+
+	/* Clear video memory */
+	i = sm501.memSize/4;
+	vm = (unsigned int *)sm501.frameAdrs;
+	while(i--)
+		*vm++ = 0;
+
+	return (&sm501);
+}
+
+/*-----------------------------------------------------------------------------
+ * video_set_lut --
+ *-----------------------------------------------------------------------------
+ */
+void video_set_lut (
+	unsigned int index,           /* color number */
+	unsigned char r,              /* red */
+	unsigned char g,              /* green */
+	unsigned char b               /* blue */
+	)
+{
+}
+
+#endif /* CONFIG_VIDEO_SM501 */
diff --git a/drivers/video/smiLynxEM.c b/drivers/video/smiLynxEM.c
new file mode 100644
index 0000000..20f9beb
--- /dev/null
+++ b/drivers/video/smiLynxEM.c
@@ -0,0 +1,858 @@
+/*
+ * (C) Copyright 1997-2002 ELTEC Elektronik AG
+ * Frank Gottschling <fgottschling@eltec.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
+ */
+
+/*
+ * smiLynxEM.c
+ *
+ * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator
+ *
+ * modification history
+ * --------------------
+ * 04-18-2002 Rewritten for U-Boot <fgottschling@eltec.de>.
+ *
+ * 18-03-2004 - Unify videomodes handling with the ct69000
+ *            - The video output can be set via the variable "videoout"
+ *              in the environment.
+ *              videoout=1 output on LCD
+ *              videoout=2 output on CRT (default value)
+ *	                <p.aubert@staubli.com>
+ */
+
+#include <common.h>
+
+#if defined(CONFIG_VIDEO_SMI_LYNXEM)
+
+#include <pci.h>
+#include <video_fb.h>
+#include "videomodes.h"
+/*
+ * Export Graphic Device
+ */
+GraphicDevice smi;
+
+/*
+ * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external
+ */
+#define VIDEO_MEM_SIZE	0x400000
+
+
+/*
+ * ISA mapped regs
+ */
+#define SMI_INDX_C4		(pGD->isaBase + 0x03c4)	   /* index reg */
+#define SMI_DATA_C5		(pGD->isaBase + 0x03c5)	   /* data reg */
+#define SMI_INDX_D4		(pGD->isaBase + 0x03d4)	   /* index reg */
+#define SMI_DATA_D5		(pGD->isaBase + 0x03d5)	   /* data reg */
+#define SMI_ISR1		(pGD->isaBase + 0x03ca)
+#define SMI_INDX_CE		(pGD->isaBase + 0x03ce)	   /* index reg */
+#define SMI_DATA_CF		(pGD->isaBase + 0x03cf)	   /* data reg */
+#define SMI_LOCK_REG		(pGD->isaBase + 0x03c3)	   /* unlock/lock ext crt reg */
+#define SMI_MISC_REG		(pGD->isaBase + 0x03c2)	   /* misc reg */
+#define SMI_LUT_MASK		(pGD->isaBase + 0x03c6)	   /* lut mask reg */
+#define SMI_LUT_START		(pGD->isaBase + 0x03c8)	   /* lut start index */
+#define SMI_LUT_RGB		(pGD->isaBase + 0x03c9)	   /* lut colors auto incr.*/
+#define SMI_INDX_ATTR		(pGD->isaBase + 0x03c0)	   /* attributes index reg */
+
+/*
+ * Video processor control
+ */
+typedef struct {
+	unsigned int   control;
+	unsigned int   colorKey;
+	unsigned int   colorKeyMask;
+	unsigned int   start;
+	unsigned short offset;
+	unsigned short width;
+	unsigned int   fifoPrio;
+	unsigned int   fifoERL;
+	unsigned int   YUVtoRGB;
+} SmiVideoProc;
+
+/*
+ * Video window control
+ */
+typedef struct {
+	unsigned short top;
+	unsigned short left;
+	unsigned short bottom;
+	unsigned short right;
+	unsigned int   srcStart;
+	unsigned short width;
+	unsigned short offset;
+	unsigned char  hStretch;
+	unsigned char  vStretch;
+} SmiVideoWin;
+
+/*
+ * Capture port control
+ */
+typedef struct {
+	unsigned int   control;
+	unsigned short topClip;
+	unsigned short leftClip;
+	unsigned short srcHeight;
+	unsigned short srcWidth;
+	unsigned int   srcBufStart1;
+	unsigned int   srcBufStart2;
+	unsigned short srcOffset;
+	unsigned short fifoControl;
+} SmiCapturePort;
+
+
+/*
+ * Register values for common video modes
+ */
+static char SMI_SCR[] = {
+	/* all modes */
+	0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90,
+	0x17, 0x20, 0x18, 0xb1, 0x19, 0x00,
+};
+static char SMI_EXT_CRT[] = {
+	0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00,
+	0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00,
+};
+static char SMI_ATTR [] = {
+	0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05,
+	0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b,
+	0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00,
+	0x12, 0x0f, 0x13, 0x00, 0x14, 0x00,
+};
+static char SMI_GCR[18] = {
+	0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40,
+	0x06, 0x05, 0x07, 0x0f, 0x08, 0xff,
+};
+static char SMI_SEQR[] = {
+	0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03,
+};
+static char SMI_PCR [] = {
+	0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00,
+};
+static char SMI_MCR[] = {
+	0x60, 0x01, 0x61, 0x00,
+#ifdef CONFIG_HMI1001
+	0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */
+#endif
+};
+
+static char SMI_HCR[] = {
+	0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00,
+	0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00,
+};
+
+
+/*******************************************************************************
+ *
+ * Write SMI ISA register
+ */
+static void smiWrite (unsigned short index, char reg, char val)
+{
+	register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+	out8 ((pGD->isaBase + index), reg);
+	out8 ((pGD->isaBase + index + 1), val);
+}
+
+/*******************************************************************************
+ *
+ * Write a table of SMI ISA register
+ */
+static void smiLoadRegs (
+	unsigned int iReg,
+	unsigned int dReg,
+	char	     *regTab,
+	unsigned int tabSize
+	)
+{
+	register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+	register int i;
+
+	for (i=0; i<tabSize; i+=2) {
+		if (iReg == SMI_INDX_ATTR) {
+			/* Reset the Flip Flop */
+			in8 (SMI_ISR1);
+			out8 (iReg, regTab[i]);
+			out8 (iReg, regTab[i+1]);
+		} else {
+			out8 (iReg, regTab[i]);
+			out8 (dReg, regTab[i+1]);
+		}
+	}
+}
+
+/*******************************************************************************
+ *
+ * Init capture port registers
+ */
+static void smiInitCapturePort (void)
+{
+	SmiCapturePort smiCP = { 0x01400600, 0x30, 0x40, 480, 640, 0, 0, 2560, 6 };
+	register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+	register SmiCapturePort *pCP = (SmiCapturePort *)&smiCP;
+
+	out32r ((pGD->cprBase + 0x0004), ((pCP->topClip<<16)   | pCP->leftClip));
+	out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth));
+	out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8);
+	out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8);
+	out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8);
+	out32r ((pGD->cprBase + 0x0018), pCP->fifoControl);
+	out32r ((pGD->cprBase + 0x0000), pCP->control);
+}
+
+
+/*******************************************************************************
+ *
+ * Init video processor registers
+ */
+static void smiInitVideoProcessor (void)
+{
+	SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed };
+	SmiVideoWin  smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 };
+	register GraphicDevice *pGD = (GraphicDevice *)&smi;
+	register SmiVideoProc  *pVP = (SmiVideoProc *)&smiVP;
+	register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW;
+
+	pVP->width    = pGD->plnSizeX * pGD->gdfBytesPP;
+	pVP->control |= pGD->gdfIndex << 16;
+	pVWin->bottom = pGD->winSizeY - 1;
+	pVWin->right  = pGD->winSizeX - 1;
+	pVWin->width  = pVP->width;
+
+	/* color key */
+	out32r ((pGD->vprBase + 0x0004), pVP->colorKey);
+
+	/* color key mask */
+	out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask);
+
+	/* data src start adrs */
+	out32r ((pGD->vprBase + 0x000c), pVP->start / 8);
+
+	/* data width and offset */
+	out32r ((pGD->vprBase + 0x0010),
+		((pVP->offset	/ 8 * pGD->gdfBytesPP) << 16) |
+		(pGD->plnSizeX / 8 * pGD->gdfBytesPP));
+
+	/* video window 1 */
+	out32r ((pGD->vprBase + 0x0014),
+		((pVWin->top << 16) | pVWin->left));
+
+	out32r ((pGD->vprBase + 0x0018),
+		((pVWin->bottom << 16) | pVWin->right));
+
+	out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8);
+
+	out32r ((pGD->vprBase + 0x0020),
+		(((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+	out32r ((pGD->vprBase + 0x0024),
+		(((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+	/* video window 2 */
+	out32r ((pGD->vprBase + 0x0028),
+		((pVWin->top << 16) | pVWin->left));
+
+	out32r ((pGD->vprBase + 0x002c),
+		((pVWin->bottom << 16) | pVWin->right));
+
+	out32r ((pGD->vprBase + 0x0030),
+		pVWin->srcStart / 8);
+
+	out32r ((pGD->vprBase + 0x0034),
+		(((pVWin->offset / 8) << 16) | (pVWin->width / 8)));
+
+	out32r ((pGD->vprBase + 0x0038),
+		(((pVWin->hStretch) << 8) | pVWin->vStretch));
+
+	/* fifo prio control */
+	out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio);
+
+	/* fifo empty request levell */
+	out32r ((pGD->vprBase + 0x0058), pVP->fifoERL);
+
+	/* conversion constant */
+	out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB);
+
+	/* vpr control word */
+	out32r ((pGD->vprBase + 0x0000), pVP->control);
+}
+
+/******************************************************************************
+ *
+ * Init drawing engine registers
+ */
+static void smiInitDrawingEngine (void)
+{
+	GraphicDevice *pGD = (GraphicDevice *)&smi;
+	unsigned int val;
+
+	/* don't start now */
+	out32r ((pGD->dprBase + 0x000c), 0x000f0000);
+
+	/* set rop2 to copypen */
+	val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c));
+	out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c));
+
+	/* set clip rect */
+	out32r ((pGD->dprBase + 0x002c), 0);
+	out32r ((pGD->dprBase + 0x0030),
+		((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP ));
+
+	/* src row pitch */
+	val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010)));
+	out32r ((pGD->dprBase + 0x0010),
+		(val | pGD->plnSizeX * pGD->gdfBytesPP));
+
+	/* dst row pitch */
+	val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010)));
+	out32r ((pGD->dprBase + 0x0010),
+		(((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val));
+
+	/* window width src/dst */
+	out32r ((pGD->dprBase + 0x003c),
+		(((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) |
+		 (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)));
+	out16r ((pGD->dprBase + 0x001e), 0x0000);
+
+	/* src base adrs */
+	out32r ((pGD->dprBase + 0x0040),
+		(((pGD->frameAdrs/8) & 0x000fffff)));
+
+	/* dst base adrs */
+	out32r ((pGD->dprBase + 0x0044),
+		(((pGD->frameAdrs/8) & 0x000fffff)));
+
+	/* foreground color */
+	out32r ((pGD->dprBase + 0x0014), pGD->fg);
+
+	/* background color */
+	out32r ((pGD->dprBase + 0x0018), pGD->bg);
+
+	/* xcolor */
+	out32r ((pGD->dprBase + 0x0020), 0x00ffffff);
+
+	/* xcolor mask */
+	out32r ((pGD->dprBase + 0x0024), 0x00ffffff);
+
+	/* bit mask */
+	out32r ((pGD->dprBase + 0x0028), 0x00ffffff);
+
+	/* load mono pattern */
+	out32r ((pGD->dprBase + 0x0034), 0);
+	out32r ((pGD->dprBase + 0x0038), 0);
+}
+
+static struct pci_device_id supported[] = {
+	{ PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 },
+	{ PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 },
+	{ PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 },
+	{ }
+};
+
+/*****************************************************************************/
+static void smiLoadMsr (struct ctfb_res_modes *mode)
+{
+	unsigned char h_synch_high, v_synch_high;
+	register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+	h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40;	/* horizontal Synch High active */
+	v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80;	/* vertical Synch High active */
+	out8 (SMI_MISC_REG, (h_synch_high | v_synch_high | 0x29));
+	/* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01
+	 * Selects the upper 64KB page.Bit5=1
+	 * CLK2 (left reserved in standard VGA) Bit3|2=1|0
+	 * Disables CPU access to frame buffer. Bit1=0
+	 * Sets the I/O address decode for ST01, FCR, and all CR registers
+	 * to the 3Dx I/O address range (CGA emulation). Bit0=1
+	 */
+}
+/*****************************************************************************/
+static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel)
+{
+	unsigned char cr[0x7a];
+	int i;
+	unsigned int hd, hs, he, ht, hbs, hbe;	/* Horizontal.	*/
+	unsigned int vd, vs, ve, vt, vbs, vbe;	/* vertical */
+	unsigned int bpp, wd, dblscan, interlaced;
+
+	const int LineCompare = 0x3ff;
+	unsigned int TextScanLines = 1;	/* this is in fact a vertical zoom factor   */
+	register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+	/* Horizontal */
+	hd = (var->xres) / 8;	/* HDisp.  */
+	hs = (var->xres + var->right_margin) / 8;	/* HsStrt  */
+	he = (var->xres + var->right_margin + var->hsync_len) / 8;	/* HsEnd   */
+	ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8;	/* HTotal  */
+	/* Blank */
+	hbs = hd;
+	hbe = 0; /* Blank end at 0 */
+
+	/* Vertical */
+	vd = var->yres;		/* VDisplay   */
+	vs = var->yres + var->lower_margin;	/* VSyncStart */
+	ve = var->yres + var->lower_margin + var->vsync_len;	/* VSyncEnd */
+	vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;	/* VTotal  */
+	vbs = vd;
+	vbe = 0;
+
+	bpp = bits_per_pixel;
+	dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0;
+	interlaced = var->vmode & FB_VMODE_INTERLACED;
+
+
+	if (bpp == 15)
+		bpp = 16;
+	wd = var->xres * bpp / 64;	/* double words per line */
+	if (interlaced) {	/* we divide all vertical timings, exept vd */
+		vs >>= 1;
+		vbs >>= 1;
+		ve >>= 1;
+		vt >>= 1;
+	}
+
+	memset (cr, 0, sizeof (cr));
+	cr[0x00] = ht - 5;
+	cr[0x01] = hd - 1;
+	cr[0x02] = hbs - 1;
+	cr[0x03] = (hbe & 0x1F);
+	cr[0x04] = hs;
+	cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
+
+	cr[0x06] = (vt - 2) & 0xFF;
+	cr[0x07] = (((vt - 2) & 0x100) >> 8)
+		| (((vd - 1) & 0x100) >> 7)
+		| ((vs & 0x100) >> 6)
+		| (((vbs - 1) & 0x100) >> 5)
+		| ((LineCompare & 0x100) >> 4)
+		| (((vt - 2) & 0x200) >> 4)
+		| (((vd - 1) & 0x200) >> 3)
+		| ((vs & 0x200) >> 2);
+
+	cr[0x30] = ((vt - 2) & 0x400) >> 7
+		| (((vd - 1) & 0x400) >> 8)
+		| (((vbs - 1) & 0x400) >> 9)
+		| ((vs & 0x400) >> 10)
+		| (interlaced) ? 0x80 : 0;
+
+
+	cr[0x08] = 0x00;
+	cr[0x09] = (dblscan << 7)
+		| ((LineCompare & 0x200) >> 3)
+		| (((vbs - 1) & 0x200) >> 4)
+		| (TextScanLines - 1);
+
+	cr[0x10] = vs & 0xff;	/* VSyncPulseStart */
+	cr[0x11] = (ve & 0x0f);
+	cr[0x12] = (vd - 1) & 0xff;	/* LineCount  */
+	cr[0x13] = wd & 0xff;
+	cr[0x14] = 0x40;
+	cr[0x15] = (vbs - 1) & 0xff;
+	cr[0x16] = vbe & 0xff;
+	cr[0x17] = 0xe3;	/* but it does not work */
+	cr[0x18] = 0xff & LineCompare;
+	cr[0x22] = 0x00;	/* todo? */
+
+
+	/* now set the registers */
+	for (i = 0; i <= 0x18; i++) {	/*CR00 .. CR18 */
+		smiWrite (SMI_INDX_D4, i, cr[i]);
+	}
+	i = 0x22;		/*CR22 */
+	smiWrite (SMI_INDX_D4, i, cr[i]);
+	i = 0x30;		/*CR30 */
+	smiWrite (SMI_INDX_D4, i, cr[i]);
+}
+
+/*****************************************************************************/
+#define REF_FREQ	14318180
+#define PMIN		1
+#define PMAX		255
+#define QMIN		1
+#define QMAX		63
+
+static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq)
+{
+	unsigned int n = QMIN, m = 0;
+	long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1;
+	long long int D = 0x7ffffffffffffffLL;
+
+	for (n = QMIN; n <= QMAX; n++) {
+		m = PMIN;	/* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */
+		L = P * n - m * Q;
+		while (L > 0 && m < PMAX) {
+			L -= REF_FREQ;	/* difference is greater as 0 subtract fref */
+			m++;	/* and increment m */
+		}
+		/* difference is less or equal than 0 or m > maximum */
+		if (m > PMAX)
+			break;	/* no solution: if we increase n we get the same situation */
+		/* L is <= 0 now */
+		if (-L > H && m > PMIN) {	/* if difference > the half fref */
+			L += REF_FREQ;	/* we take the situation before */
+			m--;	/* because its closer to 0 */
+		}
+		L = (L < 0) ? -L : +L;	/* absolute value */
+		if (D < L)	/* if last difference was better take next n */
+			continue;
+		D = L;
+		*pp = m;
+		*pq = n;	/*  keep improved data */
+		if (D == 0)
+			break;	/* best result we can get */
+	}
+	return (unsigned int) (0xffffffff & D);
+}
+
+/*****************************************************************************/
+static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id)
+{
+	unsigned int p = 0;
+	unsigned int q = 0;
+	long long freq;
+	register GraphicDevice *pGD  = (GraphicDevice *)&smi;
+
+	smiWrite (SMI_INDX_C4, 0x65, 0);
+	smiWrite (SMI_INDX_C4, 0x66, 0);
+	smiWrite (SMI_INDX_C4, 0x68, 0x50);
+	if (device_id == PCI_DEVICE_ID_SMI_810) {
+		smiWrite (SMI_INDX_C4, 0x69, 0x3);
+	} else {
+		smiWrite (SMI_INDX_C4, 0x69, 0x0);
+	}
+
+	/* Memory clock */
+	switch (device_id) {
+	case PCI_DEVICE_ID_SMI_710 :
+		smiWrite (SMI_INDX_C4, 0x6a, 0x75);
+		break;
+	case PCI_DEVICE_ID_SMI_712 :
+		smiWrite (SMI_INDX_C4, 0x6a, 0x80);
+		break;
+	default :
+		smiWrite (SMI_INDX_C4, 0x6a, 0x53);
+		break;
+	}
+	smiWrite (SMI_INDX_C4, 0x6b, 0x15);
+
+	/* VCLK */
+	freq = 1000000000000LL / var -> pixclock;
+
+	FindPQ ((unsigned int)freq, &p, &q);
+
+	smiWrite (SMI_INDX_C4, 0x6c, p);
+	smiWrite (SMI_INDX_C4, 0x6d, q);
+
+}
+
+/*******************************************************************************
+ *
+ * Init video chip with common Linux graphic modes (lilo)
+ */
+void *video_hw_init (void)
+{
+	GraphicDevice *pGD = (GraphicDevice *)&smi;
+	unsigned short device_id;
+	pci_dev_t devbusfn;
+	int videomode;
+	unsigned long t1, hsynch, vsynch;
+	unsigned int pci_mem_base, *vm;
+	char *penv;
+	int tmp, i, bits_per_pixel;
+	struct ctfb_res_modes *res_mode;
+	struct ctfb_res_modes var_mode;
+	unsigned char videoout;
+
+	/* Search for video chip */
+	printf("Video: ");
+
+	if ((devbusfn = pci_find_devices(supported, 0)) < 0)
+	{
+		printf ("Controller not found !\n");
+		return (NULL);
+	}
+
+	/* PCI setup */
+	pci_write_config_dword (devbusfn, PCI_COMMAND, (PCI_COMMAND_MEMORY | PCI_COMMAND_IO));
+	pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id);
+	pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base);
+	pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base);
+
+	tmp = 0;
+
+	videomode = CFG_DEFAULT_VIDEO_MODE;
+	/* get video mode via environment */
+	if ((penv = getenv ("videomode")) != NULL) {
+		/* deceide if it is a string */
+		if (penv[0] <= '9') {
+			videomode = (int) simple_strtoul (penv, NULL, 16);
+			tmp = 1;
+		}
+	} else {
+		tmp = 1;
+	}
+	if (tmp) {
+		/* parameter are vesa modes */
+		/* search params */
+		for (i = 0; i < VESA_MODES_COUNT; i++) {
+			if (vesa_modes[i].vesanr == videomode)
+				break;
+		}
+		if (i == VESA_MODES_COUNT) {
+			printf ("no VESA Mode found, switching to mode 0x%x ", CFG_DEFAULT_VIDEO_MODE);
+			i = 0;
+		}
+		res_mode =
+			(struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].
+								 resindex];
+		bits_per_pixel = vesa_modes[i].bits_per_pixel;
+	} else {
+
+		res_mode = (struct ctfb_res_modes *) &var_mode;
+		bits_per_pixel = video_get_params (res_mode, penv);
+	}
+
+	/* calculate hsynch and vsynch freq (info only) */
+	t1 = (res_mode->left_margin + res_mode->xres +
+	      res_mode->right_margin + res_mode->hsync_len) / 8;
+	t1 *= 8;
+	t1 *= res_mode->pixclock;
+	t1 /= 1000;
+	hsynch = 1000000000L / t1;
+	t1 *=
+		(res_mode->upper_margin + res_mode->yres +
+		 res_mode->lower_margin + res_mode->vsync_len);
+	t1 /= 1000;
+	vsynch = 1000000000L / t1;
+
+	/* fill in Graphic device struct */
+	sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres,
+		 res_mode->yres, bits_per_pixel, (hsynch / 1000),
+		 (vsynch / 1000));
+	printf ("%s\n", pGD->modeIdent);
+	pGD->winSizeX = res_mode->xres;
+	pGD->winSizeY = res_mode->yres;
+	pGD->plnSizeX = res_mode->xres;
+	pGD->plnSizeY = res_mode->yres;
+	switch (bits_per_pixel) {
+	case 8:
+		pGD->gdfBytesPP = 1;
+		pGD->gdfIndex = GDF__8BIT_INDEX;
+		break;
+	case 15:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_15BIT_555RGB;
+		break;
+	case 16:
+		pGD->gdfBytesPP = 2;
+		pGD->gdfIndex = GDF_16BIT_565RGB;
+		break;
+	case 24:
+		pGD->gdfBytesPP = 3;
+		pGD->gdfIndex = GDF_24BIT_888RGB;
+		break;
+	}
+
+	pGD->isaBase = CFG_ISA_IO;
+	pGD->pciBase = pci_mem_base;
+	pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000);
+	pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000);
+	pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000);
+	pGD->frameAdrs = pci_mem_base;
+	pGD->memSize = VIDEO_MEM_SIZE;
+
+	/* Set up hardware : select color mode,
+	   set Register base to isa 3dx for 3?x regs*/
+	out8 (SMI_MISC_REG, 0x01);
+
+	/* Turn off display */
+	smiWrite (SMI_INDX_C4, 0x01, 0x20);
+
+	/* Unlock ext. crt regs */
+	out8 (SMI_LOCK_REG, 0x40);
+
+	/* Unlock crt regs 0-7 */
+	smiWrite (SMI_INDX_D4, 0x11, 0x0e);
+
+	/* Sytem Control Register */
+	smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR));
+
+	/* extented CRT Register */
+	smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT));
+
+	/* Attributes controller registers */
+	smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR));
+
+	/* Graphics Controller Register */
+	smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR));
+
+	/* Sequencer Register */
+	smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR));
+
+	/* Power Control Register */
+	smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR));
+
+	/* Memory Control Register */
+	/* Register MSR62 is a power on configurable register. We don't */
+	/* modify it */
+	smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR));
+
+	/* Set misc output register */
+	smiLoadMsr (res_mode);
+
+	/* Set CRT and Clock control registers */
+	smiLoadCrt (res_mode, bits_per_pixel);
+
+	smiLoadCcr (res_mode, device_id);
+
+	/* Hardware Cusor Register */
+	smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR));
+
+	/* Enable  Display  */
+	videoout = 2;	    /* Default output is CRT */
+	if ((penv = getenv ("videoout")) != NULL) {
+		/* deceide if it is a string */
+		videoout = (int) simple_strtoul (penv, NULL, 16);
+	}
+	smiWrite (SMI_INDX_C4, 0x31, videoout);
+
+	/* Video processor default setup */
+	smiInitVideoProcessor ();
+
+	/* Capture port default setup */
+	smiInitCapturePort ();
+
+	/* Drawing engine default setup */
+	smiInitDrawingEngine ();
+
+	/* Turn on display */
+	smiWrite (0x3c4, 0x01, 0x01);
+
+	/* Clear video memory */
+	i = pGD->memSize/4;
+	vm = (unsigned int *)pGD->pciBase;
+	while(i--)
+		*vm++ = 0;
+	return ((void*)&smi);
+}
+
+/*******************************************************************************
+ *
+ * Drawing engine fill on screen region
+ */
+void video_hw_rectfill (
+	unsigned int bpp,	      /* bytes per pixel */
+	unsigned int dst_x,	      /* dest pos x */
+	unsigned int dst_y,	      /* dest pos y */
+	unsigned int dim_x,	      /* frame width */
+	unsigned int dim_y,	      /* frame height */
+	unsigned int color	      /* fill color */
+	)
+{
+	register GraphicDevice *pGD = (GraphicDevice *)&smi;
+	register unsigned int control;
+
+	dim_x *= bpp;
+
+	out32r ((pGD->dprBase + 0x0014), color);
+	out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+	out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+
+	control = 0x0000ffff &	in32r ((pGD->dprBase + 0x000c));
+
+	control |= 0x80010000;
+
+	out32r ((pGD->dprBase + 0x000c),  control);
+
+	/* Wait for drawing processor */
+	do
+	{
+		out8 ((pGD->isaBase + 0x3c4), 0x16);
+	} while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+ *
+ * Drawing engine bitblt with screen region
+ */
+void video_hw_bitblt (
+	unsigned int bpp,	      /* bytes per pixel */
+	unsigned int src_x,	      /* source pos x */
+	unsigned int src_y,	      /* source pos y */
+	unsigned int dst_x,	      /* dest pos x */
+	unsigned int dst_y,	      /* dest pos y */
+	unsigned int dim_x,	      /* frame width */
+	unsigned int dim_y	      /* frame height */
+	)
+{
+	register GraphicDevice *pGD = (GraphicDevice *)&smi;
+	register unsigned int control;
+
+	dim_x *= bpp;
+
+	if ((src_y<dst_y) || ((src_y==dst_y) && (src_x<dst_x)))
+	{
+		out32r ((pGD->dprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1)));
+		out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1)));
+		control = 0x88000000;
+	} else {
+		out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y));
+		out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y));
+		control = 0x80000000;
+	}
+
+	out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y));
+	control |= (0x0000ffff &  in32r ((pGD->dprBase + 0x000c)));
+	out32r ((pGD->dprBase + 0x000c), control);
+
+	/* Wait for drawing processor */
+	do
+	{
+		out8 ((pGD->isaBase + 0x3c4), 0x16);
+	} while (in8 (pGD->isaBase + 0x3c5) & 0x08);
+}
+
+/*******************************************************************************
+ *
+ * Set a RGB color in the LUT (8 bit index)
+ */
+void video_set_lut (
+	unsigned int index,	      /* color number */
+	unsigned char r,	      /* red */
+	unsigned char g,	      /* green */
+	unsigned char b		      /* blue */
+	)
+{
+	register GraphicDevice *pGD = (GraphicDevice *)&smi;
+
+	out8 (SMI_LUT_MASK,  0xff);
+
+	out8 (SMI_LUT_START, (char)index);
+
+	out8 (SMI_LUT_RGB, r>>2);    /* red */
+	udelay (10);
+	out8 (SMI_LUT_RGB, g>>2);    /* green */
+	udelay (10);
+	out8 (SMI_LUT_RGB, b>>2);    /* blue */
+	udelay (10);
+}
+
+#endif /* CONFIG_VIDEO_SMI_LYNXEM */
diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c
new file mode 100644
index 0000000..c81e5bc
--- /dev/null
+++ b/drivers/video/videomodes.c
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
+ *
+ * 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
+ */
+
+/************************************************************************
+  Get Parameters for the video mode:
+  The default video mode can be defined in CFG_DEFAULT_VIDEO_MODE.
+  If undefined, default video mode is set to 0x301
+  Parameters can be set via the variable "videomode" in the environment.
+  2 diferent ways are possible:
+  "videomode=301"   - 301 is a hexadecimal number describing the VESA
+		      mode. Following modes are implemented:
+
+		      Colors	640x480 800x600 1024x768 1152x864 1280x1024
+		     --------+---------------------------------------------
+		      8 bits |	0x301	0x303	 0x305	  0x161	    0x307
+		     15 bits |	0x310	0x313	 0x316	  0x162	    0x319
+		     16 bits |	0x311	0x314	 0x317	  0x163	    0x31A
+		     24 bits |	0x312	0x315	 0x318	    ?	    0x31B
+		     --------+---------------------------------------------
+  "videomode=bootargs"
+		   - the parameters are parsed from the bootargs.
+		      The format is "NAME:VALUE,NAME:VALUE" etc.
+		      Ex.:
+		      "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000"
+		      Parameters not included in the list will be taken from
+		      the default mode, which is one of the following:
+		      mode:0  640x480x24
+		      mode:1  800x600x16
+		      mode:2  1024x768x8
+		      mode:3  960x720x24
+		      mode:4  1152x864x16
+		      mode:5  1280x1024x8
+
+		      if "mode" is not provided within the parameter list,
+		      mode:0 is assumed.
+		      Following parameters are supported:
+		      x	      xres = visible resolution horizontal
+		      y	      yres = visible resolution vertical
+		      pclk    pixelclocks in pico sec
+		      le      left_marging time from sync to picture in pixelclocks
+		      ri      right_marging time from picture to sync in pixelclocks
+		      up      upper_margin time from sync to picture
+		      lo      lower_margin
+		      hs      hsync_len length of horizontal sync
+		      vs      vsync_len length of vertical sync
+		      sync    see FB_SYNC_*
+		      vmode   see FB_VMODE_*
+		      depth   Color depth in bits per pixel
+		      All other parameters in the variable bootargs are ignored.
+		      It is also possible to set the parameters direct in the
+		      variable "videomode", or in another variable i.e.
+		      "myvideo" and setting the variable "videomode=myvideo"..
+****************************************************************************/
+
+#include <common.h>
+#include "videomodes.h"
+
+const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
+	{0x301, RES_MODE_640x480, 8},
+	{0x310, RES_MODE_640x480, 15},
+	{0x311, RES_MODE_640x480, 16},
+	{0x312, RES_MODE_640x480, 24},
+	{0x303, RES_MODE_800x600, 8},
+	{0x313, RES_MODE_800x600, 15},
+	{0x314, RES_MODE_800x600, 16},
+	{0x315, RES_MODE_800x600, 24},
+	{0x305, RES_MODE_1024x768, 8},
+	{0x316, RES_MODE_1024x768, 15},
+	{0x317, RES_MODE_1024x768, 16},
+	{0x318, RES_MODE_1024x768, 24},
+	{0x161, RES_MODE_1152x864, 8},
+	{0x162, RES_MODE_1152x864, 15},
+	{0x163, RES_MODE_1152x864, 16},
+	{0x307, RES_MODE_1280x1024, 8},
+	{0x319, RES_MODE_1280x1024, 15},
+	{0x31A, RES_MODE_1280x1024, 16},
+	{0x31B, RES_MODE_1280x1024, 24},
+};
+const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
+	/* x	 y pixclk   le	ri  up	lo   hs vs  s  vmode */
+	{640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED},
+	{800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED},
+	{1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0, FB_VMODE_NONINTERLACED},
+	{960, 720, 13100, 160, 40, 32, 8, 80, 4, 0, FB_VMODE_NONINTERLACED},
+	{1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0, FB_VMODE_NONINTERLACED},
+	{1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0, FB_VMODE_NONINTERLACED},
+};
+
+/************************************************************************
+ * Get Parameters for the video mode:
+ */
+/*********************************************************************
+ * returns the length to the next seperator
+ */
+static int
+video_get_param_len (char *start, char sep)
+{
+	int i = 0;
+	while ((*start != 0) && (*start != sep)) {
+		start++;
+		i++;
+	}
+	return i;
+}
+
+static int
+video_search_param (char *start, char *param)
+{
+	int len, totallen, i;
+	char *p = start;
+	len = strlen (param);
+	totallen = len + strlen (start);
+	for (i = 0; i < totallen; i++) {
+		if (strncmp (p++, param, len) == 0)
+			return (i);
+	}
+	return -1;
+}
+
+/***************************************************************
+ * Get parameter via the environment as it is done for the
+ * linux kernel i.e:
+ * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000,
+ *	 le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0
+ *
+ * penv is a pointer to the environment, containing the string, or the name of
+ * another environment variable. It could even be the term "bootargs"
+ */
+
+#define GET_OPTION(name,var)				\
+	if(strncmp(p,name,strlen(name))==0) {		\
+		val_s=p+strlen(name);			\
+		var=simple_strtoul(val_s, NULL, 10);	\
+	}
+
+int video_get_params (struct ctfb_res_modes *pPar, char *penv)
+{
+	char *p, *s, *val_s;
+	int i = 0, t;
+	int bpp;
+	int mode;
+	/* first search for the environment containing the real param string */
+	s = penv;
+	if ((p = getenv (s)) != NULL) {
+		s = p;
+	}
+	/* in case of the bootargs line, we have to start
+	 * after "video=ctfb:"
+	 */
+	i = video_search_param (s, "video=ctfb:");
+	if (i >= 0) {
+		s += i;
+		s += strlen ("video=ctfb:");
+	}
+	/* search for mode as a default value */
+	p = s;
+	t = 0;
+	mode = 0;		/* default */
+	while ((i = video_get_param_len (p, ',')) != 0) {
+		GET_OPTION ("mode:", mode)
+			p += i;
+		if (*p != 0)
+			p++;	/* skip ',' */
+	}
+	if (mode >= RES_MODES_COUNT)
+		mode = 0;
+	*pPar = res_mode_init[mode];	/* copy default values */
+	bpp = 24 - ((mode % 3) * 8);
+	p = s;			/* restart */
+	while ((i = video_get_param_len (p, ',')) != 0) {
+		GET_OPTION ("x:", pPar->xres)
+			GET_OPTION ("y:", pPar->yres)
+			GET_OPTION ("le:", pPar->left_margin)
+			GET_OPTION ("ri:", pPar->right_margin)
+			GET_OPTION ("up:", pPar->upper_margin)
+			GET_OPTION ("lo:", pPar->lower_margin)
+			GET_OPTION ("hs:", pPar->hsync_len)
+			GET_OPTION ("vs:", pPar->vsync_len)
+			GET_OPTION ("sync:", pPar->sync)
+			GET_OPTION ("vmode:", pPar->vmode)
+			GET_OPTION ("pclk:", pPar->pixclock)
+			GET_OPTION ("depth:", bpp)
+			p += i;
+		if (*p != 0)
+			p++;	/* skip ',' */
+	}
+	return bpp;
+}
diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h
new file mode 100644
index 0000000..e2dffe7
--- /dev/null
+++ b/drivers/video/videomodes.h
@@ -0,0 +1,88 @@
+/*
+ * (C) Copyright 2004
+ * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
+ *
+ * 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
+ */
+
+
+#ifndef CFG_DEFAULT_VIDEO_MODE
+#define CFG_DEFAULT_VIDEO_MODE	0x301
+#endif
+
+/* Some mode definitions */
+#define FB_SYNC_HOR_HIGH_ACT	1	/* horizontal sync high active	*/
+#define FB_SYNC_VERT_HIGH_ACT	2	/* vertical sync high active	*/
+#define FB_SYNC_EXT		4	/* external sync		*/
+#define FB_SYNC_COMP_HIGH_ACT	8	/* composite sync high active	*/
+#define FB_SYNC_BROADCAST	16	/* broadcast video timings	*/
+					/* vtotal = 144d/288n/576i => PAL  */
+					/* vtotal = 121d/242n/484i => NTSC */
+#define FB_SYNC_ON_GREEN	32	/* sync on green */
+#define FB_VMODE_NONINTERLACED	0	/* non interlaced */
+#define FB_VMODE_INTERLACED	1	/* interlaced	*/
+#define FB_VMODE_DOUBLE		2	/* double scan */
+#define FB_VMODE_MASK		255
+
+#define FB_VMODE_YWRAP		256	/* ywrap instead of panning	*/
+#define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
+#define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset	*/
+
+
+/******************************************************************
+ * Resolution Struct
+ ******************************************************************/
+struct ctfb_res_modes {
+	int xres;		/* visible resolution		*/
+	int yres;
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	int pixclock;		/* pixel clock in ps (pico seconds) */
+	int left_margin;	/* time from sync to picture	*/
+	int right_margin;	/* time from picture to sync	*/
+	int upper_margin;	/* time from sync to picture	*/
+	int lower_margin;
+	int hsync_len;		/* length of horizontal sync	*/
+	int vsync_len;		/* length of vertical sync	*/
+	int sync;		/* see FB_SYNC_*		*/
+	int vmode;		/* see FB_VMODE_*		*/
+};
+
+/******************************************************************
+ * Vesa Mode Struct
+ ******************************************************************/
+struct ctfb_vesa_modes {
+	int vesanr;		/* Vesa number as in LILO (VESA Nr + 0x200} */
+	int resindex;		/* index to resolution struct */
+	int bits_per_pixel;	/* bpp */
+};
+
+#define RES_MODE_640x480	0
+#define RES_MODE_800x600	1
+#define RES_MODE_1024x768	2
+#define RES_MODE_960_720	3
+#define RES_MODE_1152x864	4
+#define RES_MODE_1280x1024	5
+#define RES_MODES_COUNT		6
+
+#define VESA_MODES_COUNT 19
+
+extern const struct ctfb_vesa_modes vesa_modes[];
+extern const struct ctfb_res_modes res_mode_init[];
+
+int video_get_params (struct ctfb_res_modes *pPar, char *penv);