diff -Nur linux-2.4.21/arch/i386/Linuxbios.in linux-2.4.21-init_dyn/arch/i386/Linuxbios.in
--- linux-2.4.21/arch/i386/Linuxbios.in	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/arch/i386/Linuxbios.in	Sun Jun 29 20:31:39 2003
@@ -0,0 +1,8 @@
+mainmenu_option next_comment
+comment 'Linuxbios Options'
+bool 'Linuxbios Power Management support?' CONFIG_LINUXBIOS_PM
+if [ "$CONFIG_LINUXBIOS_PM" = "y" ]; then
+	bool '	SIS 503 support?' CONFIG_LINUXBIOS_PM_SIS503
+	bool '	PIIX4E support?' CONFIG_LINUXBIOS_PM_PIIX4E
+fi
+endmenu
diff -Nur linux-2.4.21/arch/i386/config.in linux-2.4.21-init_dyn/arch/i386/config.in
--- linux-2.4.21/arch/i386/config.in	Fri Jun 13 22:51:29 2003
+++ linux-2.4.21-init_dyn/arch/i386/config.in	Mon Jun 30 15:40:04 2003
@@ -1,4 +1,4 @@
-#
+
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
@@ -454,6 +454,18 @@
    fi
    endmenu
 fi
+
+
+mainmenu_option next_comment
+comment 'LinuxBIOS'
+
+tristate 'LinuxBIOS Support' CONFIG_LINUXBIOS
+if [ "$CONFIG_LINUXBIOS" != "n" ]; then
+   source arch/i386/Linuxbios.in
+fi
+
+endmenu
+
 
 mainmenu_option next_comment
 comment 'Sound'
diff -Nur linux-2.4.21/arch/i386/kernel/process.c linux-2.4.21-init_dyn/arch/i386/kernel/process.c
--- linux-2.4.21/arch/i386/kernel/process.c	Fri Jun 13 22:51:29 2003
+++ linux-2.4.21-init_dyn/arch/i386/kernel/process.c	Sun Jun 29 20:31:39 2003
@@ -50,6 +50,158 @@
 
 #include <linux/irq.h>
 
+#ifdef CONFIG_LINUXBIOS_PM
+#include <linux/pci.h>
+#ifdef CONFIG_LINUXBIOS_PM_SIS503
+void
+sis503_reset(struct pci_dev *dev)
+{
+	unsigned char b;
+	unsigned short acpi_base;
+
+	printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n");
+
+	/* Enable ACPI by set B7 on Reg 0x40, LPC */
+	pci_read_config_byte(dev, 0x40, &b);
+	pci_write_config_byte(dev, 0x40, b | 0x80);
+	printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n");
+
+	/* get the ACPI base address for register 0x74,0x75 of LPC */
+	pci_read_config_word(dev, 0x74, &acpi_base);	
+	printk(KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base);
+
+	/* Set software watchdog timer init value */
+	outb(0x03, 0x4a + acpi_base);
+	printk(KERN_ERR __FUNCTION__ ": set the dog. \n");
+
+	printk(KERN_ERR __FUNCTION__ ": enabling dog. \n");
+	/* Software watchdog enable, issue PCIRST# when time expire */
+	outb(0x8f, 0x4b + acpi_base);
+
+	printk(KERN_ERR __FUNCTION__ ": We should reset soon. \n");
+}
+
+void
+sis503_off(struct pci_dev *dev)
+{
+	unsigned char b;
+	unsigned short acpi_base;
+
+	printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n");
+	/* Enable ACPI by set B7 on Reg 0x40, LPC */
+	pci_read_config_byte(dev, 0x40, &b);
+	pci_write_config_byte(dev, 0x40, b | 0x80);
+	printk(KERN_ERR __FUNCTION__ ": enabled ACPI. \n");
+
+        /* get the ACPI base address for register 0x74,0x75 of LPC */
+	pci_read_config_word(dev, 0x74, &acpi_base);
+	printk (KERN_ERR __FUNCTION__ ":acpi base: %x\n", acpi_base);
+
+	/* ACPI Register 5, Bit 10-12, Sleeping Type,
+	   set to 101 -> S5, soft_off */
+	outb(0x14, 0x05 + acpi_base);
+	printk(KERN_ERR __FUNCTION__ ": DONE setting sleep type. \n");
+
+	/* ACPI Register 5, Bit 13, Sleep Enable */
+	outb(0x20 | 0x14, 0x05 + acpi_base);
+	printk(KERN_ERR __FUNCTION__ ": DONE sleep enable. \n");
+}
+#endif // CONFIG_LINUXBIOS_PM_SIS503
+#ifdef CONFIG_LINUXBIOS_PM_PIIX4E
+void
+piix4e_reset(struct pci_dev *dev)
+{
+    // simple on this part. outb 0x6 to 0xcf9
+
+    printk(KERN_ERR __FUNCTION__ ": starting reset operation. \n");
+    outb(0x6, 0xcf9);
+    printk(KERN_ERR __FUNCTION__ ": We should reset soon. \n");
+}
+
+void
+piix4e_off(struct pci_dev *dev)
+{
+	unsigned char b;
+	unsigned short acpi_base;
+
+	printk(KERN_ERR __FUNCTION__ ": no power off on this chip! \n");
+}
+#endif
+struct pci_dev * pci_find_device(unsigned int vendor, unsigned int device, 
+				 const struct pci_dev *from);
+
+struct linuxbios_control {
+	u_short vendor, device;
+	void (*poweroff)(struct pci_dev *);
+	void (*reset)(struct pci_dev *);
+};
+
+struct linuxbios_control controls[] = {
+#ifdef CONFIG_LINUXBIOS_PM_SIS503
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, sis503_off, sis503_reset},
+#endif
+#ifdef CONFIG_LINUXBIOS_PM_PIIX4E
+	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, 
+	 piix4e_off, piix4e_reset},
+#endif
+	{0}
+};
+
+struct linuxbios_control *findcontrol(struct pci_dev **d)
+{
+	struct linuxbios_control *lb = controls, *retval = 0;
+	int i;
+
+	printk(KERN_ERR __FUNCTION__ ": Find vendor 0x%x device 0x%x\n", 
+	       lb->vendor, lb->device);
+	for(lb = controls, i = 0; 
+	    (i < sizeof(controls)/sizeof(controls[0])) && (! retval); 
+	    i++, lb++)
+	{
+		*d = pci_find_device(lb->vendor, lb->device, 0);
+		if (*d)
+			retval = lb;
+	}
+
+	printk(KERN_ERR __FUNCTION__ ": result of find is %p\n", retval);
+	return retval;
+}
+
+void
+linuxbios_poweroff(void)
+{
+	struct linuxbios_control *lb = 0;
+	struct pci_dev *dev;
+
+	printk(KERN_ERR __FUNCTION__ ": find an lb\n");
+	lb = findcontrol(&dev);
+
+	printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", 
+	       lb, lb ? lb->poweroff : 0);
+	if (lb && (lb->poweroff))
+		lb->poweroff(dev);
+	printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n");
+}
+
+void
+linuxbios_reset(void)
+{
+	struct linuxbios_control *lb = 0;
+	struct pci_dev *dev;
+
+	printk(KERN_ERR __FUNCTION__ ": find an lb\n");
+	lb = findcontrol(&dev);
+
+	printk(KERN_ERR __FUNCTION__ ": found lb %p, call %p\n", 
+	       lb, lb ? lb->reset : 0);
+	if (lb && (lb->reset))
+		lb->reset(dev);
+	printk(KERN_ERR __FUNCTION__ ": Returning? Can't happen, I thought?\n");
+}
+
+#endif // CONFIG_LINUXBIOS_PM
+
+
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
 int hlt_counter;
@@ -401,6 +553,9 @@
 	smp_send_stop();
 	disable_IO_APIC();
 #endif
+#ifdef CONFIG_LINUXBIOS_PM
+	linuxbios_reset();
+#endif
 
 	if(!reboot_thru_bios) {
 		/* rebooting needs to touch the page at absolute addr 0 */
@@ -430,6 +585,9 @@
 {
 	if (pm_power_off)
 		pm_power_off();
+#ifdef CONFIG_LINUXBIOS_PM
+	linuxbios_poweroff();
+#endif
 }
 
 extern void show_trace(unsigned long* esp);
diff -Nur linux-2.4.21/drivers/ide/pci/sis5513.c linux-2.4.21-init_dyn/drivers/ide/pci/sis5513.c
--- linux-2.4.21/drivers/ide/pci/sis5513.c	Fri Jun 13 22:51:33 2003
+++ linux-2.4.21-init_dyn/drivers/ide/pci/sis5513.c	Sun Jun 29 20:44:58 2003
@@ -174,7 +174,7 @@
 	{ "SiS640",	PCI_DEVICE_ID_SI_640,	ATA_66,		SIS5513_LATENCY },
 	{ "SiS630",	PCI_DEVICE_ID_SI_630,	ATA_66,		SIS5513_LATENCY },
 	{ "SiS620",	PCI_DEVICE_ID_SI_620,	ATA_66,		SIS5513_LATENCY },
-	{ "SiS550",	PCI_DEVICE_ID_SI_550,	ATA_100a,	0},
+	{ "SiS550",	PCI_DEVICE_ID_SI_550,	ATA_100a,	SIS5513_LATENCY },
 	{ "SiS540",	PCI_DEVICE_ID_SI_540,	ATA_66,		0},
 	{ "SiS530",	PCI_DEVICE_ID_SI_530,	ATA_66,		0},
 	{ "SiS5600",	PCI_DEVICE_ID_SI_5600,	ATA_33,		0},
diff -Nur linux-2.4.21/drivers/mtd/devices/docprobe.c linux-2.4.21-init_dyn/drivers/mtd/devices/docprobe.c
--- linux-2.4.21/drivers/mtd/devices/docprobe.c	Fri Jun 13 22:51:34 2003
+++ linux-2.4.21-init_dyn/drivers/mtd/devices/docprobe.c	Sun Jun 29 21:06:30 2003
@@ -40,7 +40,7 @@
    a Millennium enough that they go through and work out what the 
    difference is :)
 */
-#define DOC_SINGLE_DRIVER
+#undef DOC_SINGLE_DRIVER
 
 #include <linux/config.h>
 #include <linux/kernel.h>
diff -Nur linux-2.4.21/drivers/video/Config.in linux-2.4.21-init_dyn/drivers/video/Config.in
--- linux-2.4.21/drivers/video/Config.in	Fri Jun 13 22:51:37 2003
+++ linux-2.4.21-init_dyn/drivers/video/Config.in	Sun Jun 29 21:00:56 2003
@@ -148,11 +148,22 @@
  	 tristate '  ATI Radeon display support (EXPERIMENTAL)' CONFIG_FB_RADEON
 	 tristate '  ATI Rage128 display support (EXPERIMENTAL)' CONFIG_FB_ATY128
 	 tristate '  Intel 830M/845G/852GM/855GM/865G display support (EXPERIMENTAL)' CONFIG_FB_INTEL 
-	 tristate '  SIS acceleration (EXPERIMENTAL)' CONFIG_FB_SIS
+
+ 	 mainmenu_option next_comment
+ 	 comment 'SiSFB Lite support'
+         tristate '  SIS FB Lite' CONFIG_FB_SIS
+
 	 if [ "$CONFIG_FB_SIS" != "n" ]; then
-	    bool '    SIS 630/540/730 support' CONFIG_FB_SIS_300
-	    bool '    SIS 315H/315 support' CONFIG_FB_SIS_315
+
+ 	 #   bool '	SIS 630/540/730 support' CONFIG_FB_SIS_300
+ 	 #   bool '	SIS 315H/315 support' CONFIG_FB_SIS_315
+             source drivers/video/sis/Config.in
+
 	 fi
+         endmenu
+ 
+
+
 	 tristate '  NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
 	 tristate '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
 	 tristate '  3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
diff -Nur linux-2.4.21/drivers/video/sis/Config.in linux-2.4.21-init_dyn/drivers/video/sis/Config.in
--- linux-2.4.21/drivers/video/sis/Config.in	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/Config.in	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,7 @@
+	    bool '    SIS 630/540/730 support' CONFIG_FB_SIS_300
+	    bool '    SIS 315H/315 support' CONFIG_FB_SIS_315
+	    tristate '  SIS Video Overlay Acceleration (EXPERIMENTAL)' CONFIG_FB_SIS_VIDEO
+	    if [ "$CONFIG_FB_SIS_VIDEO" != "n" ]; then
+	    	bool '      MGA Video API support' CONFIG_FB_SIS_MGA_VID
+	    	bool '      SyncFB API support' CONFIG_FB_SIS_SYNCFB
+	    fi
\ No newline at end of file
diff -Nur linux-2.4.21/drivers/video/sis/Makefile linux-2.4.21-init_dyn/drivers/video/sis/Makefile
--- linux-2.4.21/drivers/video/sis/Makefile	Fri Nov 29 07:53:15 2002
+++ linux-2.4.21-init_dyn/drivers/video/sis/Makefile	Sun Jun 29 20:55:16 2003
@@ -4,11 +4,25 @@
 
 O_TARGET := sisfb.o
 
-export-objs := sis_main.o
+obj-$(CONFIG_FB_SIS)		+= sisfb_lite.o sisfb_utils.o sisfb_accel.o sisfb_legacy_init.o
+obj-$(CONFIG_FB_SIS_VIDEO)	+= sisfb_video.o sisfb_overlay.o
+obj-$(CONFIG_FB_SIS_MGA_VID)	+= sisfb_mgavid.o
+obj-$(CONFIG_FB_SIS_SYNCFB)	+= sisfb_syncfb.o
+ 
+ 
+obj-$(CONFIG_FB_SIS_300)	+= sisfb_300_init.o sisfb_300_core.o sisfb_530_accel.o
+ifneq ($(CONFIG_FB_SIS_VIDEO),n)
+  obj-$(CONFIG_FB_SIS_VIDEO) 	+= sisfb_300_overlay.o
+endif
+ 
+obj-$(CONFIG_FB_SIS_315)	+= sisfb_315_init.o sisfb_300_core.o sisfb_315_accel.o
+ifneq ($(CONFIG_FB_SIS_VIDEO),n)
+  obj-$(CONFIG_FB_SIS_VIDEO) 	+= sisfb_315_overlay.o
+endif
 
-obj-y  := sis_main.o init.o init301.o sis_accel.o
 obj-m  := $(O_TARGET)
 
 include $(TOPDIR)/Rules.make
 
-
+clean:
+	rm -f core *.o *.a *.s
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_300_core.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_core.c
--- linux-2.4.21/drivers/video/sis/sisfb_300_core.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_core.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,564 @@
+/* sisfb_300_core.c: Setting Video Mode for SiS 540/550/630/730 Integrated VGA
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. Glamour Design Guideline V0.8
+ *	2. Programmer's Guide to the EGA, VGA, and Super VGA Card. Third Edition,
+ *	   Richard F. Ferraro, Addison-Welsey, Aug. 1994
+ *	3. sis86c201.c in XFree86 3.3.6
+ */
+
+#include "sisfb_lite.h"
+#include "sisfb_300_core.h"
+
+static void sisfb_get_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which);
+static void sisfb_set_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which);
+static void sisfb_set_memory_clocks(struct sisfb_info * sisfb);
+static int sisfb_get_memory_size(struct sisfb_info * sisfb);
+static void sisfb_set_crt1_crtc_regs(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_mode_regs(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_pitch(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_offset(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_vclk(struct sisfb_info * sisfb, struct sisfb_par * par);
+static int sisfb_set_fifo_thresholds(struct sisfb_info * sisfb, struct sisfb_par * par);
+
+/**
+ *	sisfb_get_clock: - Read the clock generator parameters
+ *	@sisfb: SiS Frame Buffer structure
+ *	@clock: Paramters of the clock generator (return)
+ *	@which: Which clock generator to be read.
+ *
+ *	Read the clock generator parameters to @clock form the hardware. The desired
+ *	clock generator is specified by @which. Valid values are MCLK for memory clock,
+ *	VCLK for video dot clock and ECLK for 3D engine.
+ */
+static void
+sisfb_get_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which)
+{
+	u8 data;
+
+	/* get divider and numerator */
+	data = sisfb_get_seq_reg(sisfb, which);
+	clock->divider   = ((data & 0x80) >> 7) + 1;
+	clock->numerator =  (data & ~0x80) + 1;
+
+	/* get denumerator and post scalar */
+	data = sisfb_get_seq_reg(sisfb, which + 1);
+	clock->denumerator = (data & 0x1F) + 1;
+	clock->post_scalar = ((data & 0xE0) >> 5) + 1;
+
+	/* get VCO gain */
+	data = sisfb_get_seq_reg(sisfb, which + 2);
+	clock->vco_gain = (data >> 7);
+}
+
+/**
+ *	sisfb_set_clock: - Set the clock generator parameters
+ *	@sisfb: SiS Frame Buffer structure
+ *	@clock: Paramters of the clock generator
+ *	@which: Which clock generator to be read.
+ *
+ *	Set the clock generator parameters @clock to the hardware. The desired clock
+ *	generator is specified by @which. Valid values are MCLK for memory clock,
+ *	VCLK for video dot clock and ECLK for 3D engine.
+ */
+static void
+sisfb_set_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which)
+{
+	u8 data;
+
+	/* set divider and numerator */
+	data  = (clock->numerator - 1) & 0x7F;
+	data |= (clock->divider   - 1) ? 0x80 : 0x00;
+	sisfb_set_seq_reg(sisfb, which, data);
+
+	/* set denumerator and post scalar */
+	data  = (clock->denumerator - 1) & 0x1F;
+	data |= (clock->post_scalar - 1) << 5;
+	sisfb_set_seq_reg(sisfb, which + 1, data);
+
+	/* set VCO gain */
+	data = clock->vco_gain ? 0x80 : 0x00;
+	sisfb_set_seq_reg(sisfb, which + 2, data);
+}
+
+/**
+ *	sisfb_set_memory_clocks: - Set memory bus clock rate
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Set the memory clocks for VGA core. Form SiS 300 and up, the VGA core has
+ *	2 independent clocks for 2D and 3D engines. We can set them to different
+ *	rates seperatly.
+ */
+extern unsigned long mclk, eclk;
+static void __devinit
+sisfb_set_memory_clocks(struct sisfb_info * sisfb)
+{
+	struct sisfb_clock_param clock;
+
+	/* set the clock rate according to the option */
+	sisfb_calc_clock_param(&clock, mclk);
+	sisfb_set_clock(sisfb, &clock, SIS300_MCLK);
+
+	sisfb_calc_clock_param(&clock, eclk);
+	sisfb_set_clock(sisfb, &clock, SIS300_ECLK);
+
+	/* read the clock rate back and show to user */
+	sisfb_get_clock(sisfb, &clock, SIS300_MCLK);
+	printk(KERN_INFO "sisfb_lite: 2D Memory Clock = %6ld KHz\n",
+	       sisfb_calc_clock_freq(&clock));
+
+	sisfb_get_clock(sisfb, &clock, SIS300_ECLK);
+	printk(KERN_INFO "sisfb_lite: 3D Memory Clock = %6ld KHz\n",
+	       sisfb_calc_clock_freq(&clock));
+}
+/**
+ *	sisfb_config_memory: - Configure Framebuffer Memory
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV on Failure
+ *
+ *	Configure the frame buffer memory.
+ *	If Memory Type Range Registers (MTRR) is configured in the kernel. We set the
+ *	Frame Buffer area as "Write Combine" to boost the perfromance.
+ */
+int __devinit
+sisfb_config_memory(struct sisfb_info * sisfb)
+{
+	int ret;
+	u8 data = 0;
+
+	//sisfb_set_memory_clocks(sisfb);
+
+	/* Check if we have SMA configured correctly and HOW MUCH */
+	if ((ret = sisfb_get_memory_size(sisfb)) < 0)
+		return ret;
+
+	/* Enable PCI Relocated IO, Memory Mapped IO and Linear Framebuffer Addressing */
+	//data  = SIS300_PCI_VGA_MEM_DISABLE | SIS300_PCI_VGA_IO_DISABLE;
+	data = SIS300_PCI_PCI_IO_ENABLE | SIS300_PCI_PCI_MMIO_ENABLE;
+	data |= SIS300_PCI_LINEAR_ENABLE;
+	sisfb_set_seq_reg(sisfb, SIS300_PCI_ADDR_SET, data);
+
+	/* ioremap MMIO and Framebuffer Area */
+	sisfb->video_base_virt = 
+		ioremap(sisfb->video_base_phy, sisfb->video_size_virt);
+	sisfb->mmio_base_virt  =
+		ioremap(sisfb->mmio_base_phy, sisfb->mmio_size_phy);
+
+	printk(KERN_INFO "sisfb_lite: framebuffer at 0x%lx, mapped to 0x%p, size %lu KB\n",
+	       sisfb->video_base_phy, (char *) sisfb->video_base_virt,
+	       sisfb->video_size_virt / 1024);
+
+#ifdef CONFIG_MTRR
+	/* Use MTRR to boost performance */
+	sisfb->mtrr = mtrr_add(sisfb->video_base_phy, sisfb->video_size_virt,
+			       MTRR_TYPE_WRCOMB, 1);
+	if (sisfb->mtrr >= 0) {
+		printk(KERN_INFO "sisfb_lite: Turned on MTRR Write Combine for framebuffer\n");
+	}
+#endif /* CONFIG_MTRR */
+
+	return 0;
+}
+
+/**
+ *	sisfb_set_crt1_crtc_regs: - Set CRTC Registers of CRT1
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: Haedware parameters for CRT1
+ *
+ *	Historically, CRTC registers defined by standard VGA accepts values
+ *	(in units of characters or whatever) slightly different from the
+ *	"physical" ones (in units of dots), so we have to transform hardware
+ *	paramters before programming CRTC. Those CRTC registers alos have different
+ *	"overflow" bits due to higher and higher screen resolution supported along
+ *	the evloution process. These overflow bits are defined differently across
+ *	different generations of SiS VGA core implementation.
+ */
+static void
+sisfb_set_crt1_crtc_regs(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u16 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
+	u16 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
+	u16 overflow, overflow_h1, overflow_h2, overflow_v;
+
+	/* first convert 'par' to "screen" unit */
+	htotal       = (par->htotal     >> 3) - 5;
+	hdispend     = (par->hdispend   >> 3) - 1;
+	hblankstart  = (par->hsyncstart >> 3) - 1;
+	hblankend    = (par->hsyncend   >> 3);
+	hsyncstart   = (par->hsyncstart >> 3);
+	hsyncend     = (par->hsyncend   >> 3);
+
+	vtotal       = par->vtotal     - 2;
+	vdispend     = par->vdispend   - 1;
+	vsyncstart   = par->vsyncstart;
+	vsyncend     = par->vsyncend;
+	vblankstart  = par->vsyncstart;
+	vblankend    = par->vsyncend   + 1;
+
+	/* the "overlow" bits (8:15) of the screen parameters are spread all over
+	 * various registers */ 
+	overflow     = 
+		((vsyncstart  & 0x200) >> 2) | /* Bit 7, Vertical Retrace Start Bit 9 */
+		((vdispend    & 0x200) >> 3) | /* Bit 6, Vertical Display End   Bit 9 */
+		((vtotal      & 0x200) >> 4) | /* Bit 5, Vertical Total         Bit 9 */
+		0x10                         | /* Bit 4, line compare           Bit 8 */
+		((vblankstart & 0x100) >> 5) | /* Bit 3, Vertical Blank   Start Bit 8 */
+		((vsyncstart  & 0x100) >> 6) | /* Bit 2, Vertical Retrace Start Bit 8 */
+		((vdispend    & 0x100) >> 7) | /* Bit 1, Vertical Display End   Bit 8 */
+		((vtotal      & 0x100) >> 8);  /* Bit 0, Vertical Total         Bit 8 */
+
+	overflow_v  =
+		((vsyncend    & 0x010) << 1) | /* Bit 5, Vertical Retrace End   Bit  4 */
+		((vblankend   & 0x100) >> 4) | /* Bit 4, Vertical Blank   End   Bit  8 */
+		((vsyncstart  & 0x400) >> 7) | /* Bit 3, Vertical Retrace Start Bit 10 */
+		((vblankstart & 0x400) >> 8) | /* Bit 2, Vertical Blank   Start Bit 10 */
+		((vdispend    & 0x400) >> 9) | /* Bit 1, Vertical Display End   Bit 10 */
+		((vtotal      & 0x400) >> 10); /* Bit 0, Vertical Total         Bit 10 */
+
+	overflow_h1  =
+		((hsyncstart  & 0x300) >> 2) | /* Bit 6,7 Horizontal Retrace Start Bit 8,9 */
+		((hblankstart & 0x300) >> 4) | /* Bit 4,5 Horizontal Blank   Start Bit 8,9 */
+		((hdispend    & 0x300) >> 6) | /* Bit 2,3 Horizontal Display End   Bit 8,9 */
+		((htotal      & 0x300) >> 8);  /* Bit 0,1 Horizontal Total         Bit 8,9 */
+
+	overflow_h2  =
+		((hsyncend    & 0x020) >> 3) | /* Bit 2   Horizontal Retrace End Bit 5   */
+		((hblankend   & 0x0C0) >> 6);  /* Bit 0,1 Horizontal Blank   End Bit 6,7 */
+
+	/* write 'par' to hardware registers, Standard VGA part, low order bits */
+	sisfb_set_crtc_reg(sisfb, 0x00, htotal);
+	sisfb_set_crtc_reg(sisfb, 0x01, hdispend);
+	sisfb_set_crtc_reg(sisfb, 0x02, hblankstart);
+	sisfb_set_crtc_reg(sisfb, 0x03,
+			   0x80 |               /* Bit 7, Enable Vertical Retrace Start/End */
+			   (hblankend & 0x1f)); /* Bit 0:4,  Horizontal Blank  End Bit 0:4  */
+
+	sisfb_set_crtc_reg(sisfb, 0x04, hsyncstart);
+	if (par->interlace == 1) {
+		sisfb_set_crtc_reg(sisfb, 0x19, hsyncstart);
+		sisfb_set_crtc_reg(sisfb, 0x1a, hsyncstart >> 8);
+	}
+
+	sisfb_set_crtc_reg(sisfb, 0x05,
+			   (hblankend & 0x20) << 2 | /* Bit 7,   Horizontal Blank   End Bit 5   */
+			   (hsyncend & 0x1f));       /* Bit 0:4, Horizontal Retrace End Bit 0:4 */
+	sisfb_set_crtc_reg(sisfb, 0x06, vtotal);
+	sisfb_set_crtc_reg(sisfb, 0x09,
+			   0x40 |                       /* Bit 6, line compare         Bit 9 */
+			   (vblankstart & 0x200) >> 4); /* Bit 5, Vertical Blank Start Bit 9 */
+	sisfb_set_crtc_reg(sisfb, 0x10, vsyncstart);
+	sisfb_set_crtc_reg(sisfb, 0x11, (vsyncend & 0x0F) | 0x20);
+	sisfb_set_crtc_reg(sisfb, 0x12, vdispend);
+	sisfb_set_crtc_reg(sisfb, 0x15, vblankstart);
+	sisfb_set_crtc_reg(sisfb, 0x16, vblankend);
+
+	/* Standard VGA part, overflow bits */
+	sisfb_set_crtc_reg(sisfb, 0x07, overflow);
+
+	/* Extended Registers, overflow bits */
+	sisfb_set_seq_reg(sisfb, 0x0A, overflow_v);
+	sisfb_set_seq_reg(sisfb, 0x0B, overflow_h1);
+	sisfb_set_seq_reg(sisfb, 0x0C, overflow_h2);
+}
+
+/**
+ *	sisfb_set_crt1_mode_regs: - Set misc video mode registers
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Set color depth and enable 2D engine. The display line width register SR 0x10
+ *	is also enabled.
+ */
+static void
+sisfb_set_crt1_mode_regs(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u8 tmp;
+
+	/* enable Enhanced Graphics Mode and Auto Line Width Counter */
+	tmp = 0x03;
+	switch (par->bits_per_pixel) {
+	case 32:
+		tmp |= 0x10;
+		break;
+	case 16:
+		tmp |= 0x08;
+		break;
+	case 8:
+	default:
+		break;
+	}
+
+	if (par->interlace == 1)
+		tmp |= 0x20;
+
+	sisfb_set_seq_reg(sisfb, 0x06, tmp);
+
+	/* enable 2D engine */
+	sisfb_set_seq_reg(sisfb, 0x1E, 0x40);
+}
+
+/**
+ *	sisfb_set_crt1_pitch: - Set screen pitch registers for CRT1
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Set the screen pitch registers for CRT1. Screen pitch refers to the memory address
+ *	difference between two dots of the same col on two vertically neighboring scan lines.
+ *	The CRTC 0x13 is called "offset register" in VGA literatures. SiS VGA also defines
+ *	its own screen line width register SR 0x10 which is enabled by Bit 0 of SR 0x06.
+ */
+static void
+sisfb_set_crt1_pitch(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u16 pitch = par->line_length >> 3;
+	u8 line_length = ((par->line_length + 63) >> 6) + 1;
+
+	if (par->interlace == 1) {
+		pitch <<= 1;
+	}
+
+	/* disable line compare */
+	sisfb_set_seq_reg(sisfb, 0x0F, 0x08);
+
+	/* screen pitch, in units of double word */
+	sisfb_set_crtc_reg(sisfb, 0x13, pitch & 0xFF);
+	sisfb_set_seq_reg(sisfb,  0x0E, (pitch >> 8) & 0x0F);
+
+	/* display line length, in units of 64 bytes */
+	sisfb_set_seq_reg(sisfb, 0x10, line_length);
+}
+
+/**
+ *	sisfb_set_crt1_offset: - Set screen start offset register for CRT1
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Set the screen start offset registers for CRT1. Screen start offset refers to the
+ *	memory address of the pixel (0, 0) on the current vitrual screen. This address
+ *	is calculated when the virtual screen is panned by pan_display() or when the var
+ *	is changed and decoded by decode_var(). This value is stored in the
+ *	par->screen_offset member of the current display. par->screen_offset is in the
+ *	unit of byte while the VGA hardware uses Double Word.
+ */
+static void
+sisfb_set_crt1_offset(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u32 offset;
+
+	/* convert offset address from units of byte to double word */
+	offset = par->screen_offset >> 2;
+
+	/* set screen start memory address in units of double word,
+	   bit 23:16 in SR0D, bit 15:8 in CR0C, bit 7:0 in CR0D */
+	sisfb_set_crtc_reg(sisfb, 0x0C, offset >> 8);
+	sisfb_set_crtc_reg(sisfb, 0x0D, offset);
+	sisfb_set_seq_reg(sisfb, 0x0D, offset >> 16);
+
+	/* FixME: SR37 Bit 0 for SiS 315 ?? */
+}
+
+/**
+ *	sisfb_set_crt1_vclk: - Set video dot clock frequence for CRT1
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Select normal clock generator as DCLK source. Set the clock frequence as
+ *	specified in @par->dot_clock. Also set the DAC slew rate according to DCLK
+ *	frequence.
+ */
+static void
+sisfb_set_crt1_vclk(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	/* FixME: Use clock_param for par->dot_clock */
+	u32 vclk = par->dot_clock / 1000;
+	u8 tmp = 0x10, tmp1;
+	struct sisfb_clock_param clock;
+
+	/* Select normal DCLK clock generator */
+	sisfb_set_seq_reg(sisfb, 0x31, 0x00);
+
+	/* set vclk frequence, FixME: do error check  */
+	sisfb_calc_clock_param(&clock, vclk);
+	sisfb_set_clock(sisfb, &clock, SIS300_DCLK);
+
+	sisfb_get_clock(sisfb, &clock, SIS300_DCLK);
+	printk(KERN_INFO "sisfb_lite: Video Dot Clock = %6ld KHz\n",
+	       sisfb_calc_clock_freq(&clock));
+
+	/* set DAC slew rate, the statesment in Glamour Design Guideline V.08
+	 * is totally contracted to the true hardware implementation */
+	if (vclk < 100000)
+		tmp |= 0x03;
+	else if (vclk < 200000)
+		tmp |= 0x02;
+	else if (vclk < 250000)
+		tmp |= 0x01;
+
+	/* FixME: Set half DCLK if VCLK is too high,
+	 * need to be updated for SiS 315 */
+	if (vclk > 150000) {
+		tmp  |= 0x80;
+		tmp1  = 0x08;
+	} else {
+		tmp &= 0x7F;
+		tmp1 = 0x00;
+	}
+
+	sisfb_set_seq_reg(sisfb, 0x07, tmp);
+	sisfb_set_seq_reg(sisfb, 0x32, tmp1);
+}
+
+static u8 latency_factor[] = {
+	97, 88, 86, 79, 77,  0,
+	 0, 87, 85, 78, 76, 54,
+	80, 72, 69, 63, 61,  0,
+	 0, 70, 68, 62, 59, 37, 
+};
+
+static int
+sisfb_set_fifo_thresholds(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u32 vclk = par->dot_clock / 1000;
+	unsigned int i = 0, threshold;
+	int grant_timer, fg_queue, bg_queue;
+	struct pci_dev * host = NULL;
+	u8 queue, srf;
+
+	if ((host = pci_find_slot(0, 0)) == NULL) {
+		printk(KERN_EMERG "sisfb_lite: Can not find Host Controller !!!\n");
+		return -ENODEV;
+	}
+
+	pci_read_config_byte(host, 0x53, &queue);
+	queue &= 0xF0;
+
+	for (grant_timer = 1; grant_timer >= 0; grant_timer--) {
+		for (fg_queue = 0; fg_queue <= 5; fg_queue++) {
+			for (bg_queue = 0; bg_queue <= 1; bg_queue++) {
+				threshold = latency_factor[i++] * vclk;
+				threshold *= (par->bits_per_pixel >> 3);
+				threshold /= (mclk * 16);
+				if (threshold > 0x13 || threshold == 0x00)
+					;
+				else
+					goto set_threshold;
+			}
+		}
+	}
+
+	return -EINVAL;
+
+ set_threshold:
+	/* write froeground and backgroudn queue, GUI grant timer */
+	queue |= ((fg_queue << 1) | bg_queue);
+	pci_write_config_byte(host, 0x53, queue);
+	pci_write_config_byte(host, 0xA3, grant_timer);
+
+	/* Write CRT/CPU threshold low, CRT/Engine threshold high */
+	threshold += 1;
+	srf = sisfb_get_seq_reg(sisfb, 0x0F);
+	sisfb_set_seq_reg(sisfb, 0x08, ((threshold & 0x0F) << 4 | 0x0F));
+	sisfb_set_seq_reg(sisfb, 0x0F, ((threshold & 0x10) << 1 | srf ));
+
+	/* Write CRT/CPU threshold high */
+	threshold += 3;
+	if (threshold > 0x0F)
+		threshold = 0x0F;
+	sisfb_set_seq_reg(sisfb, 0x09, (threshold & 0x0F));
+
+	return 0;
+}
+
+
+/**
+ *	sisfb_pan_var: - Set screen start offset
+ *	@var: Frame Buffer changable part
+ *	@info: Frame Buffer structure
+ *
+ *	Set the screen start offset accroding to xoffset, yoffset, xres_virtual
+ *
+ *	Virtual Screen:
+ *
+ *	-------------------------------------------> xres_vitrual
+ *	|  O
+ *	|  -----------------------------------------
+ *	|  |          O'                           |
+ *	|  |           ------------------------    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           |                      |    |
+ *	|  |           ------------------------    |
+ *	|  |                                   D'  |
+ *	|  |                                       |
+ *	|  |                                       |
+ *	v  ----------------------------------------- D
+ *    yres_virtual
+ */
+int
+sisfb_pan_display_300(struct fb_var_screeninfo * var, struct sisfb_info * sisfb)
+{
+	u32 offset;
+
+	/* offset address in units of "pixels" */
+	offset = var->yoffset * var->xres_virtual + var->xoffset;
+	/* offset address in units of byte */
+	offset = offset * (var->bits_per_pixel >> 3);
+
+	/* update screen_offset member of current par structure */
+	sisfb->current_par.screen_offset = offset;
+
+	sisfb_set_crt1_offset(sisfb, &sisfb->current_par);
+
+	return 0;
+}
+
+/*
+ *  Set the hardware according to 'par'.
+ */
+void
+sisfb_set_par_300(struct sisfb_par *par, struct sisfb_info * sisfb)
+{
+	sisfb_display_off(sisfb);
+
+	/* Standard VGA CRTC Registers */
+	sisfb_set_crt1_crtc_regs(sisfb, par);
+
+	/* Extended Registers, other stuff */
+	sisfb_set_crt1_pitch(sisfb, par);
+	sisfb_set_crt1_offset(sisfb, par);
+	sisfb_set_crt1_vclk(sisfb, par);
+	sisfb_set_crt1_mode_regs(sisfb, par);
+	sisfb_set_fifo_thresholds(sisfb, par);
+
+	/* makes 'par' values as the current_par of this framebuffer */
+	sisfb->current_par = *par;
+
+	sisfb_display_on(sisfb);
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_300_core.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_core.h
--- linux-2.4.21/drivers/video/sis/sisfb_300_core.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_core.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,24 @@
+#ifndef __SISFB_300_CORE__
+#define __SISFB_300_CORE__
+
+#define SIS300_PCI_ADDR_SET		0x20
+#define SIS300_PCI_PCI_MMIO_ENABLE	0x01
+#define SIS300_PCI_VGA_MEM_DISABLE	0x04
+#define SIS300_PCI_VGA_IO_DISABLE		0x10
+#define SIS300_PCI_PCI_IO_ENABLE		0x20
+#define SIS300_PCI_LINEAR_ENABLE		0x80
+
+#define TURBO_QUEUE_AREA_SIZE 0x80000	/* 512K */
+#define HW_CURSOR_AREA_SIZE   0x1000	/* 4K */
+
+enum clock_gen_base {
+	SIS300_MCLK = 0x28,
+	SIS300_DCLK = 0x2B,
+	SIS300_ECLK = 0x2E
+};
+
+extern int sisfb_config_memory(struct sisfb_info * sisfb);
+extern int sisfb_pan_display_300(struct fb_var_screeninfo * var, struct sisfb_info * sisfb);
+extern void sisfb_set_par_300(struct sisfb_par *par, struct sisfb_info * sisfb);
+
+#endif /* __SISFB_300_CORE__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_300_init.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_init.c
--- linux-2.4.21/drivers/video/sis/sisfb_300_init.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_init.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,203 @@
+/* sisfb_300_init.c: Initialization Code for SiS 540/630/730 Integrated VGA
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. Glamour Design Guideline V0.8
+ */
+
+#include "sisfb_lite.h"
+#include "sisfb_300_core.h"
+#include "sisfb_530_accel.h"
+
+static void sisfb_set_pci_agp_timming(struct sisfb_info * sisfb);
+static void sisfb_enable_turbo_queue(struct sisfb_info * sisfb);
+static void sisfb_fake_vgabios(struct sisfb_info * sisfb);
+
+/* Default values for PCI/AGP Timming control registers: SR21-SR25, SR32 */
+static u8 pci_timming[] __initdata = {
+	0xB6, 0xB2, 0xF6, 0x0D, 0x00, 0x11
+};
+
+/**
+ *	sisfb_set_pci_agp_timming: - Set AGP/PCI timming control registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Initialize PCI and AGP timming control registers. Most of them are
+ *	dumped form normal BIOS setting.
+ */
+static void __devinit
+sisfb_set_pci_agp_timming(struct sisfb_info * sisfb)
+{
+	u8 AGP, tmp;
+
+	/* SR3A, Hardware Trap III */
+	tmp = sisfb_get_seq_reg(sisfb, 0x3A);
+	if ((tmp & 0x30) == 0x30)
+		// PCI Mode
+		AGP = 0;
+	else
+		// AGP Mode;
+		AGP = 1;
+
+	tmp = pci_timming[0];
+	if (AGP == 0)
+		// Disable AGP Request High Priority
+		tmp &= ~0x10;
+	sisfb_set_seq_reg(sisfb, 0x21, tmp);
+
+	tmp = pci_timming[1];
+	if (AGP == 1)
+		// Enable PCI Burst memory write
+		tmp |= 0x20;
+	sisfb_set_seq_reg(sisfb, 0x22, tmp);
+
+	sisfb_set_seq_reg(sisfb, 0x23, pci_timming[2]);
+	sisfb_set_seq_reg(sisfb, 0x24, pci_timming[3]);
+	sisfb_set_seq_reg(sisfb, 0x25, pci_timming[4]);
+	sisfb_set_seq_reg(sisfb, 0x32, pci_timming[5]);
+}
+
+/**
+ *	sisfb_enable_turbo_queue: - Set Turbo Queue size and enable it
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Commands to the Graphics Engine (2D, 3D, etc) are buffered in
+ *	the Video Memory which is called Turbo Queue in SiS VGA Specs.
+ *	Usually this buffer area takes the last few KBs in the Video RAM.
+ */
+/* default turbo queue size == 64KB */
+static int tqueue_size = 0x10000;
+static void __devinit
+sisfb_enable_turbo_queue(struct sisfb_info * sisfb)
+{
+	u32 tqueue_pos;
+	u8 tqueue_status;
+
+	/* turbo queue position, in units of 64KB */
+	tqueue_pos = sisfb->video_size_virt - tqueue_size;
+	tqueue_pos /= 0x10000;
+
+	/* enable Turbo Tueue */
+	tqueue_status = 0x80 | (tqueue_pos >> 8);
+
+	sisfb_set_seq_reg(sisfb, 0x26, tqueue_pos);
+	sisfb_set_seq_reg(sisfb, 0x27, tqueue_status);
+
+	printk(KERN_INFO "sisfb_lite: Use %dKB off-screen memory for Turbo Queue\n",
+	       tqueue_size / 1024);
+}
+
+/**
+ *	sisfb_fake_vgabios: - Pretend we still have VGA BIOS
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Many of the Extended Sequencer Registers and Externded CRT Controller Registers
+ *	are used by traditional System/VGA BIOS and Drivers to pass information back and
+ *	forth. We have to fake some resonable values for these registers in order to let
+ *	some stupid applications like XFree 3.3.6 work properly.  
+ */
+static void __devinit
+sisfb_fake_vgabios(struct sisfb_info * sisfb)
+{
+	int i;
+	u8 data, sma_size;
+	u8 fake_bios[] = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F};
+
+	/* SR 14 is used as "protocol" by VGA BIOS and XFree86 for passing SMA size
+	   and bus width, we have to fake them :~-( */
+	sma_size = sisfb->video_size_virt >> 21;
+	data = fake_bios[ffs(sma_size) - 1];
+	data |= 0x40;	// 64-bit bus
+	sisfb_set_seq_reg(sisfb, 0x14, data);
+
+	/* SR16-SR19 are used as "protocol" by VGA BIOS and System BIOS for passing
+	   information about TV-out, we have to clear them :~-( */
+	for (i = 0x16; i <= 0x19; i++) {
+		sisfb_set_seq_reg(sisfb, i, 0x00);
+	}
+
+	/* SR1A are used as "protocol" by VGA BIOS and System BIOS for passing
+	   information about M/B frequence, we have to fake them :~-( */
+	sisfb_set_seq_reg(sisfb, 0x1A, 0x12);
+
+	/* set MD out enable to 1T (what the hell ??) */
+	sisfb_set_seq_reg(sisfb, 0x15, 0x01);
+
+	/* SR1B, SR1C are not used by SiS 630 (used by SiS 300 ??),
+	   clear them. */
+	sisfb_set_seq_reg(sisfb, 0x1B, 0x00);
+	sisfb_set_seq_reg(sisfb, 0x1C, 0x00);
+
+	/* CR30-CR37 are used by VGA BIOS to pass information
+	   about SiS 301, clean them */
+	for (i = 0x30; i <= 0x37; i++) {
+		sisfb_set_crtc_reg(sisfb, i, 0x00);
+	}
+}
+
+/**
+ *	sisfb_init_300: - Initialize the SiS300 VGA Core in SiS300, SiS630,540,730
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	SiS 300 VGA core is used in SiS540/630/730 chipsets. This routine inits
+ *	the very SiS300 specific stuff.
+ */
+int __devinit
+sisfb_init_300(struct sisfb_info * sisfb)
+{
+	int ret;
+
+	if ((ret = sisfb_config_memory(sisfb)) < 0)
+		return ret;
+
+	sisfb_init_legacy_vga(sisfb);
+
+	/* set to High Speed DAC by default */
+	sisfb_set_seq_reg(sisfb, 0x07, 0x13);
+
+	/* Disable DAC pedestal */
+	sisfb_set_seq_reg(sisfb, 0x1F, 0x00);
+
+	sisfb_set_pci_agp_timming(sisfb);
+
+	/* disable power management mode */
+	sisfb_set_seq_reg(sisfb, 0x11, 0x0F);
+
+	/* set screen start memory address bit 23:16 to 0, bit 15:0 are in CR0C, CR0D */
+	sisfb_set_seq_reg(sisfb, 0x0D, 0x00);
+
+	sisfb_enable_turbo_queue(sisfb);
+
+	sisfb_fake_vgabios(sisfb);
+
+	/* set hardware specific functions */
+	sisfb->accelerator = &sis530_accelerator;
+	sisfb->set_par = sisfb_set_par_300;
+	sisfb->pan_display = sisfb_pan_display_300;
+	sisfb->set_disp = sisfb_set_dispsw_accel;
+
+	return 0;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_300_overlay.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_overlay.c
--- linux-2.4.21/drivers/video/sis/sisfb_300_overlay.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_overlay.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,294 @@
+/* sisfb_300_overlay.c: Low-level utility function for accessing Video Overlay Accelerator
+ *		        for SiS 300/540/630/730
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * ToDo:
+ *	1. Preset for various buffer
+ *	2. Line buffer size and merge
+ *	3. More pixel format support
+ *	4. Source image crop (with preset ??)
+ *	5. Scale down for more than 1/2, with decimation
+ *	6. HW interrupt for page flip (exists ??)
+ */
+
+#include "sisfb_300_video.h"
+
+
+/**
+ *	sisfb_video_set_window: - Set the video overlay window on screen
+ *	@sisfb: SiS Frame Buffer structure
+ *	@startx: x coordinate of upper-left corner
+ *	@starty: y coordinate of upper-left cornet
+ *	@endx: x coordinate of lower-right corner
+ *	@endy: y coordinate of lower-right corner
+ *
+ *	The coordinates of upper-left and lower-right corners of the overlay
+ *	window are in units of screen pixel.
+ *
+ *	The registers have to be set in order. Upon the writing of first
+ *	window coodinate register all Video register are locked. They will be
+ *	unlocked when the last register is programmed.
+ */
+static void
+sisfb_video_set_window(struct sisfb_info * sisfb,
+		       u16 startx, u16 starty, u16 endx, u16 endy)
+{
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_HOR_DISP_START_LOW, startx & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_HOR_DISP_END_LOW,   endx   & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_HOR_DISP_OVERFLOW,
+			    ((endx >> 4) & 0xf0) | ((startx >> 8) & 0x0f) );
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_VER_DISP_START_LOW, starty & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_VER_DISP_END_LOW,   endy   & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_WIN_VER_DISP_OVERFLOW,
+			    ((endy >> 4) & 0xf0) | ((starty >> 8) & 0x0f) );
+}
+
+/**
+ *	sisfb_video_set_start_offset: - Set the YUV buffer start offset
+ *	@sisfb: SiS Frame Buffer structure
+ *	@y: start offset of Y buffer, in byte address
+ *	@u: start offset of U buffer, in byte address
+ *	@v: start offset of V buffer, in byte address
+ *
+ *	The start offsets of YUV buffers have to convert to Dobule Word unit first.
+ */
+void
+sisfb_video_set_start_offset(struct sisfb_info * sisfb, u32 y, u32 u, u32 v)
+{
+	u32 data;
+
+	/* Convert byte address to unit of double word */
+	y >>= 2;
+	u >>= 2;
+	v >>= 2;
+
+	/* FixME: lock address register ?? */
+	data = sisfb_get_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_1);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_1,
+			    data | SIS300_BUF_ADDR_LOCK);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_1,
+			    data | SIS300_BUF_ADDR_LOCK);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_START_LOW,     y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_START_MIDDLE, (y >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_START_HIGH,   (y >> 16) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_U_BUF_START_LOW,     u        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_U_BUF_START_MIDDLE, (u >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_U_BUF_START_HIGH,   (u >> 16) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_V_BUF_START_LOW,     v        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_V_BUF_START_MIDDLE, (v >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_V_BUF_START_HIGH,   (v >> 16) & 0xff);
+
+	/* FixME: unlock address register ?? */
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_1, data);	
+}
+
+/**
+ *	sisfb_video_set_pitch: - Set the YUV buffer pitch
+ *	@sisfb: SiS Frame Buffer structure
+ *	@y: pitch of Y buffer, in byte address
+ *	@uv: pitch of U and V buffers, in byte address
+ *
+ *	The buffer pitch of YUV buffers have to convert to Dobule Word unit first.
+ */
+static void
+sisfb_video_set_pitch(struct sisfb_info * sisfb, u32 y, u32 uv)
+{
+	/* Convert byte address to unit of double word */
+	y >>= 2;
+	uv >>= 2;
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_PITCH_LOW,       y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_UV_BUF_PITCH_LOW,      uv       & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_UV_BUF_PITCH_MIDDLE,
+			    ((uv >> 4) & 0xf0) | ((y >> 8) & 0x0f) );
+}
+
+static void
+sisfb_video_set_preset(struct sisfb_info * sisfb, u32 y, u32 uv)
+{
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_PRESET_LOW,      y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_BUF_PRESET_MIDDLE,  (y >> 8)  & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_UV_BUF_PRESET_LOW,     uv       & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_UV_BUF_PRESET_MIDDLE, (uv >> 8) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_Y_UV_BUF_PRESET_HIGH,
+			    ((uv >> 12) & 0xf0) | ((y >> 16) & 0x0f) );
+}
+
+
+static void
+sisfb_video_set_scale_factor(struct sisfb_info * sisfb,
+			     u32 src_width, u32 src_height,
+			     u32 dst_width, u32 dst_height)
+{
+	struct sisfb_scale_param param;
+	u8 scale_ctrl = 0x00;
+
+	sisfb_calc_scale_parm(sisfb, &param, src_width, src_height,
+			      dst_width, dst_height);
+
+	/* set fractional part of Horizonatl and Vertical scale factor */
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_HOR_SCALE_LOW,
+			    param.hor_fract & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_HOR_SCALE_HIGH,
+			    (param.hor_fract >> 8) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_VER_SCALE_LOW,
+			    param.ver_fract & 0xff);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_VER_SCALE_HIGH,
+			    (param.ver_fract >> 8) & 0xff);
+
+	/* Bit 2:0 Horz Preset Interger Part */
+	scale_ctrl |= param.hor_preset_int;
+	/* Set Horz and Vert Interger Part */
+	scale_ctrl |= (param.hor_int & 0x01) << 3;
+	scale_ctrl |= (param.ver_int & 0x01) << 4;
+	/* Set Horz and Vert DDA Enable */
+	scale_ctrl |= (param.hor_dda & 0x01) << 5;
+	scale_ctrl |= (param.ver_dda & 0x01) << 6;
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_SCALE_CONTROL, scale_ctrl);
+}
+
+void
+sisfb_video_set_colorkey_mode(struct sisfb_info * sisfb, u8 rop)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_MODE);
+	data &= 0xf0;
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_MODE, data | rop);
+}
+
+void
+sisfb_video_set_colorkey(struct sisfb_info * sisfb, u8 red, u8 green, u8 blue)
+{
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_RED_MIN,   red);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_BLUE_MIN,  green);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_GREEN_MIN, blue);
+
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_RED_MAX,   red);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_BLUE_MAX,  green);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_OVERLAY_COLORKEY_GREEN_MAX, blue);
+
+	sisfb_video_set_colorkey_mode(sisfb, ROP_DESTKEY);
+}
+
+void
+sisfb_video_set_pixel_format(struct sisfb_info * sisfb, u32 fmt)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_0);
+	data &= 0x03;
+
+	switch (fmt) {
+	case 0x32315659:
+		sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_0,
+				    data | SIS300_PIX_FMT_YVU420P);
+		break;
+	default:
+	}
+}
+
+void
+sisfb_video_set_geometry(struct sisfb_info * sisfb, u32 startx, u32 starty,
+			 u32 src_width, u32 src_height,
+			 u32 dst_width, u32 dst_height)
+{
+	u32 endx, endy;
+	u32 screen_width, screen_height;
+	u32 pitch;
+
+	screen_width  = sisfb_300_get_screen_width(sisfb);
+	screen_height = sisfb_300_get_screen_height(sisfb);
+
+	if (startx < 0)
+		startx = 0;
+	if (starty < 0)
+		starty = 0;
+
+	if (startx + dst_width > screen_width) {
+		endx = screen_width;
+	} else {
+		endx = startx + dst_width;
+	}
+
+	if (starty + dst_height > screen_height) {
+		endy = screen_height;
+	} else {
+		endy = starty + dst_height;
+	}
+
+	/* make pitch 32 bytes aligned, to be compatable with MGA BES */
+	pitch = (src_width + 31) & ~31;
+
+	sisfb_video_set_window(sisfb, startx, starty, endx, endy);
+	sisfb_video_set_pitch(sisfb, pitch, pitch/2);
+	sisfb_video_set_scale_factor(sisfb, src_width, src_height,
+				     dst_width, dst_height);
+
+	/* FixME: How to calculate ?? */
+	sisfb_video_set_preset(sisfb, 0, 0);
+
+	/* FixME: How to calculate ?? */
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_PLAYBACK_THRESHOLD_LOW, 0x00);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_PLAYBACK_THRESHOLD_HIGH, 0x00);
+        sisfb_set_video_reg(sisfb, SIS300_VIDEO_PLAYBACK_LINE_BUF_SIZE, 0x5f);
+}
+
+static void
+sisfb_video_init(struct sisfb_info * sisfb)
+{
+	sisfb_unlock_video_regs(sisfb);
+
+	/* FixME: figure these registers out */
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_1, 0x10);
+	sisfb_set_video_reg(sisfb, SIS300_VIDEO_MISC_CONTROL_2, 0x90);
+}
+
+static const char im_funcname[] = "sisfb_300_overlay_init";
+
+int __init
+init_sisfb_300_overlay(void)
+{
+	inter_module_register(im_funcname, THIS_MODULE, &sisfb_video_init);
+	return 0;
+}
+
+static void __exit
+cleanup_sisfb_300_overlay(void)
+{
+	inter_module_unregister(im_funcname);
+}
+
+module_exit(cleanup_sisfb_300_overlay);
+module_init(init_sisfb_300_overlay);
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_300_overlay.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_overlay.h
--- linux-2.4.21/drivers/video/sis/sisfb_300_overlay.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_300_overlay.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,39 @@
+#ifndef __SISFB_300_OVERLAY__
+#define __SISFB_300_OVERLAY__
+
+#include "sisfb_overlay.h"
+
+/* 0x82 = rgb 565 */
+enum sis300_video_misc0_bits {
+	SIS300_OVERLAY_ENABLE		= 0x02, /* Turns On/Off Video Overlay */
+	SIS300_420_PLANE_ENABLE		= 0x04, /* Select Plane or Packed mode */
+	SIS300_YUV_FMT_ENABLE		= 0x08, /* Select YUV or RGB mode */
+
+	//SIS300_422_ENABLE		= 0x20, /* Select 422 or 411 mode */
+
+	SIS300_PIX_FMT_YVU420P		= 0x0c,	/* YUV 420 Planar */
+	SIS300_PIX_FMT_YUYV		= 0x28,	/* YUYV Packed */
+	SIS300_PIX_FMT_UYVY		= 0x08,
+};
+
+enum sis300_video_misc1_bits {
+	SIS300_BOB_ENABLE		= 0x02,
+	SIS300_INDIV_LINE_MERGE		= 0x04,
+	SIS300_FIELD_MODE		= 0x08,
+	SIS300_BOTTOM_FIELD		= 0x10,
+	SIS300_BUF_ADDR_LOCK		= 0x20	/* YUV buffer start address access lock */
+};
+
+enum sis300_video_misc2_bits {
+	SIS300_SELECT_VIDEO_2		= 0x01,
+	SIS300_VIDEO2_ON_TOP		= 0x02,
+	SIS300_VIDEO_ONLY		= 0x04,
+	SIS300_VERTICAL_INTERP_ENABLE	= 0x08,
+
+	SIS300_DUAL_LINE_MERGE		= 0x10,
+	SIS300_ALL_LINE_MERGE		= 0x20,
+	SIS300_AUTO_FLIP_ENABLE		= 0x40,
+	SIS300_VIDEO_REG_WRITE_ENABLE 	= 0x80
+};
+
+#endif /* __SISFB_300_OVERLAY__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_315_accel.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_accel.c
--- linux-2.4.21/drivers/video/sis/sisfb_315_accel.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_accel.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,538 @@
+/* sisfb_315_accel.c: 2D Hardware Acceleration for SiS 550
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 315 2D Engine Register, Version 0.30, Jun. 12, 2000
+ *	2. sis315_accel.c in XFree86 4.0.2
+ */
+
+#include "sisfb_315_accel.h"
+
+/**
+ *	sisfb_wait_idle: - Wait for 2D and 3D engine being idle
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Polling the Connamd Queue Status register until all the following condition is
+ *	meat.
+ *		bit 31 2D/3D engine, Hardware/Software Queue: 1 is idle and empty
+ * 		bit 30 Hardware Command Queue: 1 is empty,
+ * 		bit 29 2D Engine: 1 idle
+ * 		bit 28 3D Engine: 1 idle
+ */
+static inline void
+sisfb_wait_idle(struct sisfb_info *sisfb)
+{
+	int count = 0x10;
+	volatile u32 dummy = 0x00000000;
+
+	while (dummy != 0x80000000 && --count) {
+		dummy = sisfb_readl(sisfb, SIS315_2D_CMD_QUEUE_STATUS) & 0x80000000;
+	}
+}
+
+static inline void
+sisfb_set_agp_base(struct sisfb_info *sisfb)
+{
+	u16 base;
+
+	switch (sisfb->current_par.bits_per_pixel) {
+	case 8:
+	case 24:
+	default:
+		base = 0x0000;
+		break;
+	case 16:
+		base = 0x8000;
+		break;
+	case 32:
+		base = 0xC000;
+		break;
+	}
+	sisfb_writew(sisfb, SIS315_2D_AGP_BASE, base);
+}
+
+static inline u32
+sisfb_command_bpp(struct sisfb_info *sisfb)
+{
+	switch (sisfb->current_par.bits_per_pixel) {
+	case 8:
+	default:
+		return SIS315_2D_CMD_CFB_8;
+	case 16:
+		return SIS315_2D_CMD_CFB_16;
+	case 32:
+		return SIS315_2D_CMD_CFB_32;
+	}
+}
+
+/**
+ *	sisfb_fillrect: - Fill a rectangle area on framebuffer
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@color: color to fill
+ *	@rop: Raster Operation for the fill
+ *
+ *	Fille a rectangle area on(off ??) the screen starting from (@x, @y) to
+ *	(@x + @width, @y + @height) with @color.
+ *	The raster operation @rop is used for solid fill or invert (via ROP_XOR).
+ *
+ *	Note:
+ *		1. The Source Pitch is dummy in this case.
+ *		2. We have to use Pattern ROPs with color in Pattern FG/BG Color Register.
+ */
+static void
+sisfb_fillrect(struct sisfb_info *sisfb, u32 x, u32 y,
+	       u32 width, u32 height, u32 color, u8 rop)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, 0 /* dummy*/);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS315_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS315_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS315_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS315_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS315_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS315_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_FG_COLOR, color);
+
+	/* Command = BitBlt, X++, Y++, pattern = Pattern Foreground Color Register, ROP = rop */
+	cmd = SIS315_2D_CMD_BITBLT | SIS315_2D_CMD_PAT_FG_REG |
+		sisfb_command_bpp(sisfb) | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+/**
+ *	sisfb_copyrect: - Copy a rectangle area
+ *	@sisfb: SiS Frame Buffer structure
+ *	@srcx: X origin of source rectangle
+ *	@srcy: Y origin of source rectangle
+ *	@sdst: X origin of destination rectangle
+ *	@sdst: Y origin of destination rectangle
+ *	@width: width
+ *	@height: height
+ *
+ *	Copy a rectangle area on(off ??) the screen starting from (@xsrc, @ysrc) to
+ *	(@xsrc + @width, @ysrc + @height) to (@xdst, @ydst).
+ *
+ *	FixMe: Do we need to set up x,y direction ??
+ */
+static void
+sisfb_copyrect(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+	       u32 dstx, u32 dsty, u32 width, u32 height, u8 rop)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, pitch);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (screen_offset, screen_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, base);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS315_2D_SRC_X, srcx);
+	sisfb_writew(sisfb, SIS315_2D_SRC_Y, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS315_2D_DST_X, dstx);
+	sisfb_writew(sisfb, SIS315_2D_DST_Y, dsty);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS315_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS315_2D_RECT_HEIGHT, height);
+
+	/* Command = BitBlt, X Dir, Y Dir, bitblt from video memory (ScrenToScreen), ROP = rop */
+	cmd = SIS315_2D_CMD_BITBLT | SIS315_2D_CMD_SRC_VIDEO |
+		sisfb_command_bpp(sisfb) | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+static void
+sisfb_copyrect_transparent(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+			   u32 dstx, u32 dsty, u32 width, u32 height,
+			   u32 src_hi, u32 src_low,
+			   u32 dst_hi, u32 dst_low,
+			   u8 key_mode)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, pitch);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (screen_offset, screen_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, base);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS315_2D_SRC_X, srcx);
+	sisfb_writew(sisfb, SIS315_2D_SRC_Y, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS315_2D_DST_X, dstx);
+	sisfb_writew(sisfb, SIS315_2D_DST_Y, dsty);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS315_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS315_2D_RECT_HEIGHT, height);
+
+	/* setup Source Color Key */
+	sisfb_writew(sisfb, SIS315_2D_TRANS_SRC_KEY_HIGH, src_hi);
+	sisfb_writew(sisfb, SIS315_2D_TRANS_SRC_KEY_LOW, src_low);
+
+	/* setup Destination Color Key */
+	sisfb_writew(sisfb, SIS315_2D_TRANS_DEST_KEY_HIGH, dst_hi);
+	sisfb_writew(sisfb, SIS315_2D_TRANS_DEST_KEY_LOW, dst_low);
+
+	/* Command = BitBlt, X Dir, Y Dir, bitblt from video memory (ScrenToScreen), ROP = key_mode */
+	cmd = SIS315_2D_CMD_TRANSPARENT_BITBLT | SIS315_2D_CMD_SRC_VIDEO |
+		sisfb_command_bpp(sisfb) | (key_mode << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+/**
+ *	sisfb_8x8_color_expand: - Color expand with 8x8 monochrome bit mask
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@fg: foreground color to expand
+ *	@bg: background color to expand
+ *	@rop: Raster Operation for the expand
+ *	@bitmap: 8x8 monochrom bitmap (64 bits)
+ *
+ *	Color expand the 8x8 bitmap @bitmap by setting bits with value 1 to @fg while bits
+ *	with value 0 to @bg. If @bg == -1 then background pixels are not expanded. Also fill
+ *	the rectangle (@x, @y) - (@x + @width, @y + @height) with the expanded pattern.
+ *
+ *	Note:
+ *		1. The Source Pitch is width/8 then rounded up.
+ *		2. We have to use Pattern ROPs with color in Pattern FG/BG Color Register.
+ */
+static void
+sisfb_8x8_color_expand(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width,
+		       u32 height, u32 fg, u32 bg, u8 rop, u8 * bitmap)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, (width + 7) >> 3);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS315_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS315_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS315_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS315_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS315_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS315_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_BG_COLOR, bg);
+
+	/* store 8x8 mono bitmap to Mono Mask Register */
+	sisfb_writel(sisfb, SIS315_2D_MONO_MASK, *(u32 *) bitmap);
+	sisfb_writel(sisfb, SIS315_2D_MONO_MASK + 4, *(u32 *) (bitmap + 4));
+
+	/* Command = Color Expand, X++, Y++, color = Pattern Register, ROP = rop */
+	cmd = SIS315_2D_CMD_COLOREXP | SIS315_2D_CMD_PAT_MONO_MASK |
+		sisfb_command_bpp(sisfb) | (rop << 8);
+
+	/* if background color == -1 then don't expand background pixels */
+	if (bg == -1)
+		cmd |= SIS315_2D_CMD_TRANSPARENT;
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+/**
+ *	sisfb_color_expand: - Color expand with Pattern Register
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@fg: foreground color to expand
+ *	@bg: background color to expand
+ *	@rop: Raster Operation for the expand
+ *	@bitmap: monochrom bitmap (384 bytes max)
+ *	@bitmap_pitch: pitch of @bitmap
+ *
+ *	Color expand the bitmap @bitmap by setting bits with value 1 to @fg while bits
+ *	with value 0 to @bg. If @bg == -1 then background pixels are not expanded. The
+ *	bitmap is transfered to hardware Pattern Register and can be as large as 384 bytes,
+ *	effectively expanding 3072 pixels in a single operation.
+ *
+ *	The rectangle (@x, @y) - (@x + @width, @y + @height) is filled with the expanded pattern.
+ *	If the size of @bitmap is samller then 384 bytes and the size of the rectangle is larger
+ *	then 3072 pixels, some pixels in the rectangle are filled with "garbage". 
+ *
+ *	Note:
+ *		1. The Source Pitch is width/8 then rounded up (i.e. in units of byte).
+ *		2. We have to use Normal ROPs with color in Source FG/BG Color Register.
+ */
+static void
+sisfb_color_expand(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width, u32 height,
+		   u32 fg, u32 bg, u8 rop, u8 * bitmap, u32 bitmap_pitch)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, bitmap_pitch);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screem_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS315_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS315_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS315_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS315_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS315_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS315_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Source Foreground Color Register */
+	sisfb_writel(sisfb, SIS315_2D_SRC_FG_COLOR, fg);
+
+	/* setup the foreground color in Source Background Color Register */
+	sisfb_writel(sisfb, SIS315_2D_SRC_BG_COLOR, bg);
+
+	/* transfer bitmap pattern to pattern register */
+	memcpy_toio(sisfb->mmio_base_virt + SIS315_2D_PATTERN_REG,
+		    bitmap, bitmap_pitch * height);
+	
+	/* Command = Color Expand, X++, Y++, color = Pattern Register, ROP = rop */
+	cmd = SIS315_2D_CMD_COLOREXP | SIS315_2D_CMD_PAT_PAT_REG |
+		sisfb_command_bpp(sisfb) | (rop << 8);
+
+	/* if background color == -1 then don't expand background pixels */
+	if (bg == -1)
+		cmd |= SIS315_2D_CMD_TRANSPARENT;
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+static void
+sisfb_drawline(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+	       u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, 1);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS315_2D_LINE_X0, srcx);
+	sisfb_writew(sisfb, SIS315_2D_LINE_Y0, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS315_2D_LINE_X1, dstx);
+	sisfb_writew(sisfb, SIS315_2D_LINE_Y1, dsty);
+
+	/* setup Line Segement Count == 1 */
+	sisfb_writew(sisfb, SIS315_2D_LINE_COUNT, 1);
+	sisfb_writew(sisfb, SIS315_2D_LINE_STYLE_PERIOD, 0);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_BG_COLOR, bg);
+
+	/* Command = Color Expand, X++, Y++, color = Pattern Foreground Register, ROP = rop */
+	cmd = SIS315_2D_CMD_LINE_DRAW | SIS315_2D_CMD_PAT_FG_REG |
+		sisfb_command_bpp(sisfb) | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+static void
+sisfb_drawline_style(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+		     u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop, u8 * bitmap)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS315_2D_SRC_PITCH, 1);
+	sisfb_writew(sisfb, SIS315_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS315_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, 0) */
+	sisfb_writel(sisfb, SIS315_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS315_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS315_2D_LINE_X0, srcx);
+	sisfb_writew(sisfb, SIS315_2D_LINE_Y0, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS315_2D_LINE_X1, dstx);
+	sisfb_writew(sisfb, SIS315_2D_LINE_Y1, dsty);
+
+	/* setup Line Segment Count == 1 */
+	sisfb_writew(sisfb, SIS315_2D_LINE_COUNT, 1);
+	sisfb_writew(sisfb, SIS315_2D_LINE_STYLE_PERIOD, 0);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS315_2D_PAT_BG_COLOR, bg);
+
+	/* transfer bitmap pattern to Line Style register */
+	sisfb_writel(sisfb, SIS315_2D_LINE_STYLE_0, * bitmap);
+	sisfb_writel(sisfb, SIS315_2D_LINE_STYLE_1, *(bitmap + 1));
+	
+	/* Command = Color Expand, X++, Y++, color = Pattern Register, ROP = rop */
+	cmd = SIS315_2D_CMD_LINE_DRAW | SIS315_2D_CMD_PAT_FG_REG
+		| sisfb_command_bpp(sisfb) | SIS315_2D_CMD_LINE_STLYE_ENABLE
+		| (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS315_2D_CMD, cmd);
+}
+
+struct sisfb_accelerator sis315_accelerator = {
+	fillrect:		sisfb_fillrect,
+	copyrect:		sisfb_copyrect,
+	copyrect_transparent:	sisfb_copyrect_transparent,
+
+	color_expand_8x8:	sisfb_8x8_color_expand,
+	color_expand:		sisfb_color_expand,
+
+	drawline:		sisfb_drawline,
+	drawline_style:		sisfb_drawline_style,
+};
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_315_accel.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_accel.h
--- linux-2.4.21/drivers/video/sis/sisfb_315_accel.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_accel.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,89 @@
+#ifndef __SISFB_315_ACCEL__
+#define __SISFB_315_ACCEL__
+
+#include "sisfb_accel.h"
+
+enum sis315_2d_registers {
+	SIS315_2D_SRC_ADDR     = 0x8200,
+	SIS315_2D_SRC_PITCH    = 0x8204, SIS315_2D_AGP_BASE     = 0x8206,
+	SIS315_2D_SRC_Y        = 0x8208, SIS315_2D_SRC_X        = 0x820A,
+	SIS315_2D_DST_Y        = 0x820C, SIS315_2D_DST_X        = 0x820E,
+	SIS315_2D_DST_ADDR     = 0x8210,
+	SIS315_2D_DST_PITCH    = 0x8214, SIS315_2D_DST_HEIGHT   = 0x8216,
+	SIS315_2D_RECT_WIDTH   = 0x8218, SIS315_2D_RECT_HEIGHT  = 0x821A,
+	SIS315_2D_PAT_FG_COLOR = 0x821C,
+	SIS315_2D_PAT_BG_COLOR = 0x8220,
+	SIS315_2D_SRC_FG_COLOR = 0x8224,
+	SIS315_2D_SRC_BG_COLOR = 0x8228,
+	SIS315_2D_MONO_MASK    = 0x822C,
+	SIS315_2D_LEFT_CLIP    = 0x8234, SIS315_2D_TOP_CLIP     = 0x8236,
+	SIS315_2D_RIGHT_CLIP   = 0x8238, SIS315_2D_BOT_CLIP     = 0x823A,
+	SIS315_2D_CMD          = 0x823C,
+	SIS315_2D_PATTERN_REG  = 0x8300
+};
+
+enum sis315_2d_registers_spanfill {
+	SIS315_2D_SPAN_X1_START = 0x8244, SIS315_2D_SPAN_X1_END   = 0x8246,
+	SIS315_2D_SPAN_Xn_START = 0x8300, SIS315_2D_SPAN_Xn_END   = 0x8302,
+};
+
+enum sis315_2d_registers_drawline {
+	SIS315_2D_LINE_X0      = 0x8208, SIS315_2D_LINE_Y0           = 0x820A,
+	SIS315_2D_LINE_X1      = 0x820C, SIS315_2D_LINE_Y1           = 0x820E,
+	SIS315_2D_LINE_COUNT   = 0x8218, SIS315_2D_LINE_STYLE_PERIOD = 0x821A,
+	SIS315_2D_LINE_STYLE_0 = 0x822C,
+	SIS315_2D_LINE_STYLE_1 = 0x8230,
+	SIS315_2D_LINE_Xn      = 0x8300, SIS315_2D_LINE_Yn           = 0x8302,
+};
+
+enum sis315_2d_register_transparent_bitblt {
+	SIS315_2D_TRANS_DEST_KEY_HIGH = 0x821C,
+	SIS315_2D_TRANS_DEST_KEY_LOW  = 0x8220,
+	SIS315_2D_TRANS_SRC_KEY_HIGH  = 0x8224,
+	SIS315_2D_TRANS_SRC_KEY_LOW   = 0x8228,
+};
+
+enum sis315_2d_cmd_type {
+	SIS315_2D_CMD_BITBLT             = 0x00, SIS315_2D_CMD_COLOREXP           = 0x01,
+	SIS315_2D_CMD_ENCOLOREXP         = 0x02, SIS315_2D_CMD_MULTIPLE_SCANLINE  = 0x03,
+	SIS315_2D_CMD_LINE_DRAW          = 0x04, SIS315_2D_CMD_TRAPEZOID_FILL     = 0x05,
+	SIS315_2D_CMD_TRANSPARENT_BITBLT = 0x06, SIS315_2D_CMD_ALPHA_BLENDING     = 0x07,
+	SIS315_2D_CMD_3D_FUNCTION        = 0x08, SIS315_2D_CMD_CLEAR_Z_BUFFER     = 0x09,
+       	SIS315_2D_CMD_GRADIENT_FILL      = 0x0A, SIS315_2D_CMD_STRETCH_BITBLT     = 0x0B
+};
+
+enum sis315_2d_cmd_control {
+	SIS315_2D_CMD_SRC_VIDEO     = 0x00,
+	SIS315_2D_CMD_SRC_SYSTEM    = 0x10,
+	SIS315_2D_CMD_SRC_AGP       = 0x20,
+
+	SIS315_2D_CMD_PAT_FG_REG    = 0x00,
+	SIS315_2D_CMD_PAT_PAT_REG   = 0x40,
+	SIS315_2D_CMD_PAT_MONO_MASK = 0x80,
+
+	SIS315_2D_CMD_CFB_8         = 0x00000000,
+	SIS315_2D_CMD_CFB_16        = 0x00010000,
+	SIS315_2D_CMD_CFB_32        = 0x00020000,
+
+	SIS315_2D_CMD_RECT_CLIP_EN  = 0x00040000,
+	SIS315_2D_CMD_TRANSPARENT   = 0x00100000,
+
+	/* Subfunction for Color/Enhanced Color Expansion */
+	SIS315_2D_CMD_COLOR_TO_MONO = 0x00100000,
+	SIS315_2D_CMD_AA_TEXT       = 0x00200000,
+
+	SIS315_2D_CMD_MERGE_CLIP_DIS    = 0x04000000,
+
+	SIS315_2D_CMD_LINE_STLYE_ENABLE = 0x00800000
+};
+
+enum sis315_command_queue_registers {
+	SIS315_2D_CMD_QUEUE_BASE_ADDRESS  = 0x85C0,
+	SIS315_2D_CMD_QUEUE_WRITE_POINTER = 0x85C4,
+	SIS315_2D_CMD_QUEUE_READ_POINTER  = 0x85C8,
+	SIS315_2D_CMD_QUEUE_STATUS        = 0x85CC
+};
+
+extern struct sisfb_accelerator sis315_accelerator;
+
+#endif /* __SISFB_315_ACCEL__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_315_init.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_init.c
--- linux-2.4.21/drivers/video/sis/sisfb_315_init.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_init.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,241 @@
+/* sisfb_315_init.c: Initialization Code for SiS 550 Integrated VGA
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. Glamour II Design Guideline V.12
+ */
+
+#include "sisfb_lite.h"
+#include "sisfb_300_core.h"
+#include "sisfb_315_accel.h"
+
+static void sisfb_set_pci_agp_timming(struct sisfb_info * sisfb);
+static void sisfb_set_dram_config(struct sisfb_info * sisfb);
+static void sisfb_enable_turbo_queue(struct sisfb_info * sisfb);
+static void sisfb_fake_vgabios(struct sisfb_info * sisfb);
+
+/* Default values for PCI/AGP Timming control registers: SR21-SR25, SR32 */
+static u8 pci_timming[] __initdata = {
+	/* SR 0x21 - 0x25, 0x31 - 0x33 */
+	0xB6, 0xB2, 0xF6, 0x0D, 0x30, 0x00, 0x01, 0x10
+};
+
+/**
+ *	sisfb_set_pci_agp_timming: - Set AGP/PCI timming control registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Initialize PCI and AGP timming control registers. Most of them are
+ *	dumped form normal BIOS setting.
+ */
+static void __devinit
+sisfb_set_pci_agp_timming(struct sisfb_info * sisfb)
+{
+	u8 AGP, tmp;
+
+	/* SR3A, Hardware Trap III */
+	tmp = sisfb_get_seq_reg(sisfb, 0x3A);
+	if ((tmp & 0x30) == 0x30)
+		// PCI Mode
+		AGP = 0;
+	else
+		// AGP Mode;
+		AGP = 1;
+
+	tmp = pci_timming[0];
+	if (AGP == 0)
+		// Disable AGP Request High Priority
+		tmp &= ~0x10;
+	sisfb_set_seq_reg(sisfb, 0x21, tmp);
+
+	tmp = pci_timming[1];
+	if (AGP == 1)
+		// Enable PCI Burst memory write
+		tmp |= 0x20;
+	sisfb_set_seq_reg(sisfb, 0x22, tmp);
+
+	sisfb_set_seq_reg(sisfb, 0x23, pci_timming[2]);
+	sisfb_set_seq_reg(sisfb, 0x24, pci_timming[3]);
+	sisfb_set_seq_reg(sisfb, 0x25, pci_timming[4]);
+	sisfb_set_seq_reg(sisfb, 0x31, pci_timming[5]);
+	sisfb_set_seq_reg(sisfb, 0x32, pci_timming[6]);
+	sisfb_set_seq_reg(sisfb, 0x33, pci_timming[7]);
+
+	/* command queue threshold, max = 11111b */
+	sisfb_set_seq_reg(sisfb, 0x27, 0x1F);
+}
+
+static u8 dram_config1[] __initdata = {
+	/* SR 0x15-0x1B */
+	0x00, 0x0F, 0x5E, 0xA9, 0xA0, 0x00, 0x30
+};
+
+static u8 dram_config2[] __initdata = {
+	/* CR 0x40-0x44 */
+	0x33, 0x33, 0x00, 0x03, 0x00
+};
+
+static void __devinit
+sisfb_set_dram_config(struct sisfb_info * sisfb)
+{
+	int i;
+
+	for (i = 0x15; i <= 0x1B; i++)
+		sisfb_set_seq_reg(sisfb, i, dram_config1[i - 0x15]);
+
+	for (i = 0x40; i <= 0x44; i++)
+		sisfb_set_crtc_reg(sisfb, i, dram_config2[i - 0x40]);
+}
+
+/**
+ *	sisfb_enable_turbo_queue: - Set Turbo Queue size and enable it
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Commands to the Graphics Engine (2D, 3D, etc) are buffered in
+ *	the Video Memory which is called Turbo Queue in SiS VGA Specs.
+ *	Usually this buffer area takes the last few KBs in the Video RAM.
+ *
+ *	For SiS 315 and later, the Command Queue can be place on both Video RAM
+ *	or System AGP memory. 
+ */
+/* default turbo queue size == 512KB */
+static int tqueue_size = 0x80000;
+static void __devinit
+sisfb_enable_turbo_queue(struct sisfb_info * sisfb)
+{
+	u32 tqueue_pos;
+	volatile u32 dummy;
+
+	tqueue_pos = sisfb->video_size_virt - tqueue_size;
+
+	/* set Command Queue threshold to max value 11111b */
+	sisfb_set_seq_reg(sisfb, 0x27, 0x1F);
+	/* synchronous reset for Connamd Queue */
+	sisfb_set_seq_reg(sisfb, 0x26, 0x01);
+
+	/* Sync Read and Write pointers of Turbo Queue */
+	dummy = sisfb_readl(sisfb, 0x85C8);
+	sisfb_writel(sisfb, 0x85C4, dummy);
+
+	/* enable Command Queue (on Video RAM) , MMIO Commands */
+	sisfb_set_seq_reg(sisfb, 0x26, 0x22);
+
+	/* set Command Queue Base Address */
+	sisfb_writel(sisfb, 0x85C0, tqueue_pos);
+
+	printk(KERN_INFO "sisfb_lite: Use %dKB off-screen memory for Turbo Queue\n",
+	       tqueue_size / 1024);
+}
+
+/**
+ *	sisfb_fake_vgabios: - Pretend we still have VGA BIOS
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Many of the Extended Sequencer Registers and Externded CRT Controller Registers
+ *	are used by traditional System/VGA BIOS and Drivers to pass information back and
+ *	forth. We have to fake some resonable values for these registers in order to let
+ *	some stupid applications like XFree 3.3.6 work properly.  
+ */
+static void __devinit
+sisfb_fake_vgabios(struct sisfb_info * sisfb)
+{
+	int i;
+	u8 data, sma_size;
+	u8 fake_bios[] = {0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F};
+
+	/* SR 14 is used as "protocol" by VGA BIOS and XFree86 for passing SMA size
+	   and bus width, we have to fake them :~-( */
+	sma_size = sisfb->video_size_virt >> 21;
+	data = fake_bios[ffs(sma_size) - 1];
+	data |= 0x40;	// 64-bit bus
+	sisfb_set_seq_reg(sisfb, 0x14, data);
+
+	/* SR16-SR19 are used as "protocol" by VGA BIOS and System BIOS for passing
+	   information about TV-out, we have to clear them :~-( */
+	for (i = 0x16; i <= 0x19; i++) {
+		sisfb_set_seq_reg(sisfb, i, 0x00);
+	}
+
+	/* SR1A are used as "protocol" by VGA BIOS and System BIOS for passing
+	   information about M/B frequence, we have to fake them :~-( */
+	sisfb_set_seq_reg(sisfb, 0x1A, 0x12);
+
+	/* set MD out enable to 1T (what the hell ??) */
+	sisfb_set_seq_reg(sisfb, 0x15, 0x01);
+
+	/* SR1B, SR1C are not used by SiS 630 (used by SiS 300 ??),
+	   clear them. */
+	sisfb_set_seq_reg(sisfb, 0x1B, 0x00);
+	sisfb_set_seq_reg(sisfb, 0x1C, 0x00);
+
+	/* CR30-CR37 are used by VGA BIOS to pass information
+	   about SiS 301, clean them */
+	for (i = 0x30; i <= 0x3F; i++) {
+		sisfb_set_crtc_reg(sisfb, i, 0x00);
+	}
+}
+
+/**
+ *	sisfb_init_315: - Initialize the SiS315 VGA Core in SiS550
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	SiS 315 VGA core is used in SiS550 chipsets. This routine inits
+ *	the very SiS315 specific stuff.
+ */
+int __devinit
+sisfb_init_315(struct sisfb_info * sisfb)
+{
+	int ret;
+
+	if ((ret = sisfb_config_memory(sisfb)) < 0)
+		return ret;
+
+	sisfb_init_legacy_vga(sisfb);
+
+	/* set to High Speed DAC by default */
+	sisfb_set_seq_reg(sisfb, 0x07, 0x10);
+
+	/* Disable DAC pedestal */
+	sisfb_set_seq_reg(sisfb, 0x1F, 0x00);
+
+	sisfb_set_pci_agp_timming(sisfb);
+
+	sisfb_set_dram_config(sisfb);
+
+	/* disable power management mode */
+	sisfb_set_seq_reg(sisfb, 0x11, 0x0F);
+
+	sisfb_enable_turbo_queue(sisfb);
+
+	sisfb_fake_vgabios(sisfb);
+
+	/* set hardware specific functions */
+	sisfb->accelerator = &sis315_accelerator;
+	sisfb->set_par = sisfb_set_par_300;
+	sisfb->pan_display = sisfb_pan_display_300;
+	sisfb->set_disp = sisfb_set_dispsw_fbcon;
+
+	return 0;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_315_overlay.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_overlay.c
--- linux-2.4.21/drivers/video/sis/sisfb_315_overlay.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_overlay.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,375 @@
+/* sisfb_300_overlay.c: Low-level utility function for accessing Video Overlay Accelerator
+ *		        for SiS 315/550
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * ToDo:
+ *	1. Preset for various buffer
+ *	2. Line buffer size and merge
+ *	3. More pixel format support
+ *	4. Source image crop (with preset ??)
+ *	5. Scale down for more than 1/2, with decimation
+ *	6. HW interrupt for page flip (exists ??)
+ */
+
+#include "sisfb_315_video.h"
+
+
+/**
+ *	sisfb_video_set_window: - Set the video overlay window on screen
+ *	@sisfb: SiS Frame Buffer structure
+ *	@startx: x coordinate of upper-left corner
+ *	@starty: y coordinate of upper-left cornet
+ *	@endx: x coordinate of lower-right corner
+ *	@endy: y coordinate of lower-right corner
+ *
+ *	The coordinates of upper-left and lower-right corners of the overlay
+ *	window are in units of screen pixel.
+ *
+ *	The registers have to be set in order. Upon the writing of first
+ *	window coodinate register all Video register are locked. They will be
+ *	unlocked when the last register is programmed.
+ */
+static void
+sisfb_video_set_window(struct sisfb_info * sisfb,
+		       u16 startx, u16 starty, u16 endx, u16 endy)
+{
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_HOR_DISP_START_LOW, startx & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_HOR_DISP_END_LOW,   endx   & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_HOR_DISP_OVERFLOW,
+			    ((endx >> 4) & 0xf0) | ((startx >> 8) & 0x0f) );
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_VER_DISP_START_LOW, starty & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_VER_DISP_END_LOW,   endy   & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_WIN_VER_DISP_OVERFLOW,
+			    ((endy >> 4) & 0xf0) | ((starty >> 8) & 0x0f) );
+}
+
+/**
+ *	sisfb_video_set_start_offset: - Set the YUV buffer start offset
+ *	@sisfb: SiS Frame Buffer structure
+ *	@y: start offset of Y buffer, in byte address
+ *	@u: start offset of U buffer, in byte address
+ *	@v: start offset of V buffer, in byte address
+ *
+ *	The start offsets of YUV buffers have to convert to Dobule Word unit first.
+ */
+void
+sisfb_video_set_start_offset(struct sisfb_info * sisfb, u32 y, u32 u, u32 v)
+{
+	u32 data;
+
+	/* Convert byte address to unit of word */
+	y >>= 1;
+	u >>= 1;
+	v >>= 1;
+
+	/* lock address register ?? */
+	data = sisfb_get_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_1);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_1, data | 0x20);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_1, data | 0x20);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_START_LOW,       y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_START_MIDDLE,   (y >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_START_HIGH,     (y >> 16) & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_START_OVERFLOW, (y >> 24) & 0x01);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_U_BUF_START_LOW,       u        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_U_BUF_START_MIDDLE,   (u >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_U_BUF_START_HIGH,     (u >> 16) & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_U_BUF_START_OVERFLOW, (u >> 24) & 0x01);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_V_BUF_START_LOW,       v        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_V_BUF_START_MIDDLE,   (v >> 8)  & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_V_BUF_START_HIGH,     (v >> 16) & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_V_BUF_START_OVERFLOW, (v >> 24) & 0x01);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_1, data);	
+}
+
+/**
+ *	sisfb_video_set_pitch: - Set the YUV buffer pitch
+ *	@sisfb: SiS Frame Buffer structure
+ *	@y: pitch of Y buffer, in byte address
+ *	@uv: pitch of U and V buffers, in byte address
+ *
+ *	The start offsets of YUV buffers have to convert to Dobule Word unit first.
+ *
+ *	FixME: Should we convert to word or dowble aliged ??
+ */
+static void
+sisfb_video_set_pitch(struct sisfb_info * sisfb, u32 y, u32 uv)
+{
+	/* Convert byte address to unit of double word */
+	y  >>= 1;
+	uv >>= 1;
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_PITCH_LOW,       y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_UV_BUF_PITCH_LOW,      uv       & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_UV_BUF_PITCH_MIDDLE,
+			    ((uv >> 4) & 0xf0) | ((y >> 8) & 0x0f) );
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_PITCH_HIGH,     (y  >> 12) & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_UV_BUF_PITCH_HIGH,    (uv >> 12) & 0xff);
+}
+
+static void
+sisfb_video_set_preset(struct sisfb_info * sisfb, u32 y, u32 uv)
+{
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_PRESET_LOW,      y        & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_BUF_PRESET_MIDDLE,  (y >> 8)  & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_UV_BUF_PRESET_LOW,     uv       & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_UV_BUF_PRESET_MIDDLE, (uv >> 8) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_Y_UV_BUF_PRESET_HIGH,
+			    ((uv >> 12) & 0xf0) | ((y >> 16) & 0x0f) );
+}
+
+#define log2(n) ffz(~(n))
+
+struct sisfb_scale_param {
+	u8 hor_int;
+	u16 hor_fract;
+	u8 ver_int;
+	u16 ver_fract;
+
+	u8 hor_preset_int;
+
+	/* DDA Enable, used for Scale >= 1 */
+	u8 hor_dda;
+	u8 ver_dda;	
+};
+
+/**
+ *	sisfb_video_set_window: - Set the video overlay scale parameter
+ *	@sisfb: SiS Frame Buffer structure
+ *	@src_width: Source image width
+ *	@src_height: Source image height
+ *	@dest_width: Destination image width
+ *	@dest_height: Destination image height
+ *
+ *	  dst              1
+ *	 ----- = ------------------------
+ *	  src     Int_part +  Fract_part
+ *	                     ------------
+ *	                        0xFFFF
+ */
+static void
+sisfb_calc_scale_parm(struct sisfb_info * sisfb, struct sisfb_scale_param * param,
+		      u32 src_width, u32 src_height,
+		      u32 dest_width, u32 dest_height)
+{
+	param->hor_preset_int = 0;
+
+	/* Horizontal  Scale Factors*/
+	if (src_width == dest_width) {
+		param->hor_int   = 0x01;
+		param->hor_fract = 0x00;
+		param->hor_dda   = 0x01;
+	} else if (src_width < dest_width) {
+		param->hor_int   = 0x00;
+		param->hor_fract = 0xFFFF * src_width / dest_width;
+		param->hor_dda   = 0x01;
+	} else {
+		param->hor_int   = 0x01;
+		param->hor_fract = (src_width - dest_width) * 0xFFFF / dest_width;
+		param->hor_dda   = 0x00;
+
+		/* FixME: Scale down more than 1/2 */
+		//param->hor_preset_int = log2(src_width/dest_width);
+	}
+
+	/* Vertical Scale Factors*/
+	if (src_height == dest_height) {
+		param->ver_int   = 0x01;
+		param->ver_fract = 0x00;
+		param->ver_dda   = 0x01;
+	} else if (src_height < dest_height) {
+		param->ver_int   = 0x00;
+		param->ver_fract = 0xFFFF * src_height / dest_height;
+		param->ver_dda   = 0x01;
+	} else {
+		param->ver_int   = 0x01;
+		param->ver_fract = (src_height - dest_height) * 0xFFFF / dest_height;
+		param->ver_dda   = 0x00;
+
+		/* FixME: Scale down more than 1/2 */
+	}
+
+}
+
+static void
+sisfb_video_set_scale_factor(struct sisfb_info * sisfb,
+			     u32 src_width, u32 src_height,
+			     u32 dst_width, u32 dst_height)
+{
+	struct sisfb_scale_param param;
+	u8 scale_ctrl = 0x00;
+
+	sisfb_calc_scale_parm(sisfb, &param, src_width, src_height,
+			      dst_width, dst_height);
+
+	/* set fractional part of Horizonatl and Vertical scale factor */
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_HOR_SCALE_LOW,
+			    param.hor_fract & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_HOR_SCALE_HIGH,
+			    (param.hor_fract >> 8) & 0xff);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_VER_SCALE_LOW,
+			    param.ver_fract & 0xff);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_VER_SCALE_HIGH,
+			    (param.ver_fract >> 8) & 0xff);
+
+	/* Bit 2:0 Horz Preset Interger Part */
+	scale_ctrl |= param.hor_preset_int;
+	/* Set Horz and Vert Interger Part */
+	scale_ctrl |= (param.hor_int & 0x01) << 3;
+	scale_ctrl |= (param.ver_int & 0x01) << 4;
+	/* Set Horz and Vert DDA Enable */
+	scale_ctrl |= (param.hor_dda & 0x01) << 5;
+	scale_ctrl |= (param.ver_dda & 0x01) << 6;
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_SCALE_CONTROL, scale_ctrl);
+}
+
+void
+sisfb_video_set_colorkey_mode(struct sisfb_info * sisfb, u8 rop)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_MODE);
+	data &= 0xf0;
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_MODE, data | rop);
+}
+
+void
+sisfb_video_set_colorkey(struct sisfb_info * sisfb, u8 red, u8 green, u8 blue)
+{
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_RED_MIN,   red);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_BLUE_MIN,  green);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_GREEN_MIN, blue);
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_RED_MAX,   red);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_BLUE_MAX,  green);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_GREEN_MAX, blue);
+
+	sisfb_video_set_colorkey_mode(sisfb, ROP_DESTKEY);
+}
+
+void
+sisfb_video_set_pixel_format(struct sisfb_info * sisfb, u32 fmt)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_0);
+	data &= 0x03;
+
+	switch (fmt) {
+	case 0x32315659:
+		sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_0,
+				    data | SIS315_PIX_FMT_YVU420P);
+		break;
+	default:
+	}
+}
+
+void
+sisfb_video_set_geometry(struct sisfb_info * sisfb, u32 startx, u32 starty,
+			 u32 src_width, u32 src_height,
+			 u32 dst_width, u32 dst_height)
+{
+	u32 endx, endy;
+	u32 screen_width, screen_height;
+	u32 pitch;
+
+	screen_width  = sisfb_300_get_screen_width(sisfb);
+	screen_height = sisfb_300_get_screen_height(sisfb);
+
+	if (startx < 0)
+		startx = 0;
+	if (starty < 0)
+		starty = 0;
+
+	if (startx + dst_width > screen_width) {
+		endx = screen_width;
+	} else {
+		endx = startx + dst_width;
+	}
+
+	if (starty + dst_height > screen_height) {
+		endy = screen_height;
+	} else {
+		endy = starty + dst_height;
+	}
+
+	/* make pitch 32 bytes aligned, to be compatable with MGA BES */
+	pitch = (src_width + 31) & ~31;
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_3, 0x00);
+	sisfb_video_set_window(sisfb, startx, starty, endx, endy);
+	sisfb_video_set_pitch(sisfb, pitch, pitch/2);
+	sisfb_video_set_scale_factor(sisfb, src_width, src_height,
+				     dst_width, dst_height);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_3, 0x07);
+
+	/* FixME: How to calculate ?? */
+	sisfb_video_set_preset(sisfb, 0, 0);
+
+	/* FixME: How to calculate ?? */
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_PLAYBACK_THRESHOLD_LOW, 0x00);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_PLAYBACK_THRESHOLD_HIGH, 0x00);
+        sisfb_set_video_reg(sisfb, SIS315_VIDEO_PLAYBACK_LINE_BUF_SIZE, 0x5f);
+}
+
+static void
+sisfb_video_init(struct sisfb_info * sisfb)
+{
+	sisfb_unlock_video_regs(sisfb);
+
+	/* FixME: figure this registers out */
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_1, 0x10);
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_MISC_CONTROL_2, 0x90);
+
+	sisfb_video_set_preset(sisfb, 0, 0);	
+}
+
+static const char im_funcname[] = "sisfb_300_overlay_init";
+
+int __init
+init_sisfb_300_overlay(void)
+{
+	inter_module_register(im_funcname, THIS_MODULE, &sisfb_video_init);
+	return 0;
+}
+
+static void __exit
+cleanup_sisfb_300_overlay(void)
+{
+	inter_module_unregister(im_funcname);
+}
+
+module_exit(cleanup_sisfb_300_overlay);
+module_init(init_sisfb_300_overlay);
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_315_overlay.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_overlay.h
--- linux-2.4.21/drivers/video/sis/sisfb_315_overlay.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_315_overlay.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,111 @@
+#ifndef __SISFB_315_OVERLAY__
+#define __SISFB_315_OVERLAY__
+
+#include "sisfb_overlay.h"
+
+enum sis315_overlay_registers {
+	/* Bit 16:24 of Y_U_V Buffer start address */
+	SIS315_VIDEO_Y_BUF_START_OVERFLOW	= 0x6B,
+	SIS315_VIDEO_U_BUF_START_OVERFLOW	= 0x6C,
+	SIS315_VIDEO_V_BUF_START_OVERFLOW	= 0x6D,
+
+	SIS315_VIDEO_Y_BUF_PITCH_HIGH		= 0x6E,
+	SIS315_VIDEO_UV_BUF_PITCH_HIGH		= 0x6F,
+
+	/* Hue and Saturation value */
+	SIS315_VIDEO_HUE_VALUE			= 0x70,
+	SIS315_VIDEO_SATURATION_VALUE		= 0x71,
+
+	SIS315_VIDEO_SUB_BUF_START_OVERFLOW	= 0x72,
+	SIS315_VIDEO_SUB_BUF_PITCH_HIGH		= 0x73,
+
+	SIS315_VIDEO_MISC_CONTROL_3		= 0x74
+};
+
+/* 0x82 = rgb 565 */
+enum sis315_video_misc0_bits {
+	SIS315_OVERLAY_ENABLE		= 0x02, /* Turns On/Off Video Overlay */
+	SIS315_420_PLANE_ENABLE		= 0x04, /* Select Plane or Packed mode */
+	SIS315_YUV_FMT_ENABLE		= 0x08, /* Select YUV or RGB mode */
+
+	//SIS315_422_ENABLE		= 0x20, /* Select 422 or 411 mode */
+
+	SIS315_PIX_FMT_YVU420P		= 0x0c,	/* YUV 420 Planar */
+	SIS315_PIX_FMT_YUYV		= 0x28,	/* YUYV Packed */
+	SIS315_PIX_FMT_UYVY		= 0x08,
+};
+
+enum sis315_video_misc1_bits {
+	SIS315_BOB_ENABLE		= 0x02,
+	SIS315_INDIV_LINE_MERGE		= 0x04,
+	SIS315_FIELD_MODE		= 0x08,
+
+	SIS315_BOTTOM_FIELD		= 0x10,
+	SIS315_NON_INTERLEAVE		= 0x20,
+};
+
+enum sis315_video_misc2_bits {
+	SIS315_SELECT_VIDEO_2		= 0x01,
+	SIS315_VIDEO2_ON_TOP		= 0x02,
+
+	SIS315_VIDEO_ONLY		= 0x04,
+	SIS315_VERTICAL_INTERP_ENABLE	= 0x08,
+
+	SIS315_DUAL_LINE_MERGE		= 0x10,
+	SIS315_ALL_LINE_MERGE		= 0x20,
+
+	SIS315_AUTO_FLIP_ENABLE		= 0x40,
+};
+
+enum sis315_video_misc3_bits {
+	SIS315_SUBMIT_VIDEO1		= 0x01,
+	SIS315_SUBMIT_VIDEO2		= 0x02,
+	SIS315_SUBMIT_SUBPICT		= 0x04
+};
+
+static inline void
+sisfb_video_set_alpha_value(struct sisfb_info * sisfb, u8 alpha)
+{
+	u8 data;
+
+	alpha &= 0x0f;
+
+	data = sisfb_get_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_MODE);
+	data &= 0x0f;
+
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_OVERLAY_COLORKEY_MODE,
+			    data | (alpha << 4));
+}
+
+static inline void
+sisfb_overlay_set_hue(struct sisfb_info * sisfb, u8 hue)
+{
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_HUE_VALUE, hue);
+}
+
+static inline u8
+sisfb_overlay_get_hue(struct sisfb_info * sisfb)
+{
+	return sisfb_get_video_reg(sisfb, SIS315_VIDEO_HUE_VALUE);
+}
+
+static inline void
+sisfb_overlay_set_saturation(struct sisfb_info * sisfb, u8 saturation)
+{
+	sisfb_set_video_reg(sisfb, SIS315_VIDEO_SATURATION_VALUE, saturation);
+}
+
+static inline u8
+sisfb_overlay_get_saturation(struct sisfb_info * sisfb)
+{
+	return sisfb_get_video_reg(sisfb, SIS315_VIDEO_SATURATION_VALUE);
+}
+
+extern void sisfb_video_set_colorkey_mode(struct sisfb_info * sisfb, u8 rop);
+extern void sisfb_video_set_colorkey(struct sisfb_info * sisfb, u8 red, u8 green, u8 blue);
+extern void sisfb_video_set_pixel_format(struct sisfb_info * sisfb, u32 fmt);
+extern void sisfb_video_set_geometry(struct sisfb_info * sisfb, u32 startx, u32 starty,
+				     u32 src_width, u32 src_height,
+				     u32 dst_width, u32 dst_height);
+extern void sisfb_video_set_start_offset(struct sisfb_info * sisfb, u32 y, u32 u, u32 v);
+#endif /* __SISFB_315_OVERLAY__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_530_accel.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_accel.c
--- linux-2.4.21/drivers/video/sis/sisfb_530_accel.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_accel.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,573 @@
+/* sisfb_530_accel.c: 2D Hardware Acceleration for SiS 530/620/540/630/730
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 6326 AGP/PCI Graphics & Video Acclerator. Rev 1.0, May 12, 1997
+ *	2. SiS 530 Host, PCI, 3D Graphics & Memory Controller Datasheet,
+ *	   Preliminary v1.0 Nov. 10, 1998
+ *	3. sis_accel2.c in XFree86 3.3.6
+ *	4. sis300_accel.c in XFree86 4.0.2
+ */
+
+#include "sisfb_530_accel.h"
+
+/**
+ *	sisfb_wait_idle: - Wait for 2D and 3D engine being idle
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Polling the Connamd Status register until all the following condition is
+ *	meat.
+ *		bit 31 2D engine: 1 is idle,
+ * 		bit 30 3D engine: 1 is idle,
+ * 		bit 29 Command queue: 1 is empty
+ */
+static inline void
+sisfb_wait_idle(struct sisfb_info *sisfb)
+{
+	int count = 0x10;
+	volatile u32 dummy = 0x00000000;
+
+	while (dummy != 0xe0000000 && --count) {
+		dummy = sisfb_readl(sisfb, SIS530_2D_CMD_STATUS) & 0xe0000000;
+	}
+}
+
+/**
+ *	sisfb_wait_cmd_queue: - Wait for command queue space
+ *	@sisfb: SiS Frame Buffer structure
+ *	@length: Space need for command queue
+ *
+ *	Polling the Command Status register until there is more space
+ *	left for @length of command
+ */
+static inline void
+sisfb_wait_cmd_queue(struct sisfb_info *sisfb, unsigned length)
+{
+	do {
+		/* nothing */
+	} while ((sisfb_readl(sisfb, SIS530_2D_CMD_STATUS) & 0x1FFF) < (length));
+}
+
+static inline void
+sisfb_set_agp_base(struct sisfb_info *sisfb)
+{
+	u16 base;
+
+	switch (sisfb->current_par.bits_per_pixel) {
+	case 8:
+	case 24:
+	default:
+		base = 0x0000;
+		break;
+	case 16:
+		base = 0x8000;
+		break;
+	case 32:
+		base = 0xC000;
+		break;
+	}
+	sisfb_writew(sisfb, SIS530_2D_AGP_BASE, base);
+}
+
+/**
+ *	sisfb_fillrect: - Fill a rectangle area on framebuffer
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@color: color to fill
+ *	@rop: Raster Operation for the fill
+ *
+ *	Fill a rectangle area on(off ??) the screen starting from (@x, @y) to
+ *	(@x + @width, @y + @height) with @color.
+ *	The raster operation @rop is used for solid fill or invert (via ROP_XOR).
+ *
+ *	Note:
+ *		1. The Source Pitch is dummy in this case.
+ *		2. We have to use Pattern ROPs with color in Pattern FG/BG Color Register.
+ */
+static void
+sisfb_fillrect(struct sisfb_info *sisfb, u32 x, u32 y,
+	       u32 width, u32 height, u32 color, u8 rop)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, 0 /* dummy*/);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS530_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS530_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS530_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS530_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS530_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS530_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_FG_COLOR, color);
+
+	/* Command = BitBlt, X++, Y++, pattern = Pattern Foreground Color Register, ROP = rop */
+	cmd = SIS530_2D_CMD_BITBLT | SIS530_2D_CMD_PAT_FG_REG |
+		SIS530_2D_CMD_DIR_X_INC | SIS530_2D_CMD_DIR_Y_INC | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+/**
+ *	sisfb_copyrect: - Copy a rectangle area
+ *	@sisfb: SiS Frame Buffer structure
+ *	@srcx: X origin of source rectangle
+ *	@srcy: Y origin of source rectangle
+ *	@sdst: X origin of destination rectangle
+ *	@sdst: Y origin of destination rectangle
+ *	@width: width
+ *	@height: height
+ *
+ *	Copy a rectangle area on(off ??) the screen starting from (@xsrc, @ysrc) to
+ *	(@xsrc + @width, @ysrc + @height) to (@xdst, @ydst).
+ */
+static void
+sisfb_copyrect(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+	       u32 dstx, u32 dsty, u32 width, u32 height, u8 rop)
+{
+	u32 cmd;
+	u32 x_dir = SIS530_2D_CMD_DIR_X_INC, y_dir = SIS530_2D_CMD_DIR_Y_INC;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* If the direction is "decreasing", the chip wants the addresses
+	 * to be at the other end, so we must be aware of that in our
+	 * calculations. */
+	if (srcx <= dstx) {
+		x_dir = SIS530_2D_CMD_DIR_X_DEC;
+		srcx += width - 1;
+		dstx += width - 1;
+	}
+
+	if (srcy <= dsty) {
+		y_dir = SIS530_2D_CMD_DIR_Y_DEC;
+		srcy += height - 1;
+		dsty += height - 1;
+	}
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, pitch);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (screen_offset, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, base);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS530_2D_SRC_X, srcx);
+	sisfb_writew(sisfb, SIS530_2D_SRC_Y, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS530_2D_DST_X, dstx);
+	sisfb_writew(sisfb, SIS530_2D_DST_Y, dsty);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS530_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS530_2D_RECT_HEIGHT, height);
+
+	/* Command = BitBlt, X Dir, Y Dir, bitblt from video memory (ScrenToScreen), ROP = rop */
+	cmd = SIS530_2D_CMD_BITBLT | SIS530_2D_CMD_SRC_VIDEO |
+		x_dir | y_dir | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+static void
+sisfb_copyrect_transparent(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+			   u32 dstx, u32 dsty, u32 width, u32 height,
+			   u32 src_hi, u32 src_low,
+			   u32 dst_hi, u32 dst_low,
+			   u8 key_mode)
+{
+	u32 cmd;
+	u32 x_dir = SIS530_2D_CMD_DIR_X_INC, y_dir = SIS530_2D_CMD_DIR_Y_INC;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* If the direction is "decreasing", the chip wants the addresses
+	 * to be at the other end, so we must be aware of that in our
+	 * calculations. */
+	if (srcx <= dstx) {
+		x_dir = SIS530_2D_CMD_DIR_X_DEC;
+		srcx += width - 1;
+		dstx += width - 1;
+	}
+
+	if (srcy <= dsty) {
+		y_dir = SIS530_2D_CMD_DIR_Y_DEC;
+		srcy += height - 1;
+		dsty += height - 1;
+	}
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, pitch);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (screen_offset, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, base);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS530_2D_SRC_X, srcx);
+	sisfb_writew(sisfb, SIS530_2D_SRC_Y, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS530_2D_DST_X, dstx);
+	sisfb_writew(sisfb, SIS530_2D_DST_Y, dsty);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS530_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS530_2D_RECT_HEIGHT, height);
+
+	/* setup Source Color Key */
+	sisfb_writew(sisfb, SIS530_2D_TRANS_SRC_KEY_HIGH, src_hi);
+	sisfb_writew(sisfb, SIS530_2D_TRANS_SRC_KEY_LOW, src_low);
+
+	/* setup Destination Color Key */
+	sisfb_writew(sisfb, SIS530_2D_TRANS_DEST_KEY_HIGH, dst_hi);
+	sisfb_writew(sisfb, SIS530_2D_TRANS_DEST_KEY_LOW, dst_low);
+
+	/* Command = BitBlt, X Dir, Y Dir, bitblt from video memory (ScrenToScreen), ROP = key_mode */
+	cmd = SIS530_2D_CMD_TRANSPARENT_BITBLT | SIS530_2D_CMD_SRC_VIDEO |
+		x_dir | y_dir | (key_mode << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+/**
+ *	sisfb_8x8_color_expand: - Color expand with 8x8 monochrome bit mask
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@fg: foreground color to expand
+ *	@bg: background color to expand
+ *	@rop: Raster Operation for the expand
+ *	@bitmap: 8x8 monochrom bitmap (64 bits)
+ *
+ *	Color expand the 8x8 bitmap @bitmap by setting bits with value 1 to @fg while bits
+ *	with value 0 to @bg. If @bg == -1 then background pixels are not expanded. Also fill
+ *	the rectangle (@x, @y) - (@x + @width, @y + @height) with the expanded pattern.
+ *
+ *	Note:
+ *		1. The Source Pitch is dummy in this case.
+ *		2. We have to use Pattern ROPs with color in Pattern FG/BG Color Register.
+ */
+static void
+sisfb_8x8_color_expand(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width,
+		       u32 height, u32 fg, u32 bg, u8 rop, u8 * bitmap)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, 0 /*dummy*/);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS530_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS530_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS530_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS530_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS530_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS530_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_BG_COLOR, bg);
+
+	/* store 8x8 mono bitmap to Mono Mask Register */
+	sisfb_writel(sisfb, SIS530_2D_MONO_MASK, *(u32 *) bitmap);
+	sisfb_writel(sisfb, SIS530_2D_MONO_MASK + 4, *(u32 *) (bitmap + 4));
+
+	/* Command = Color Expand, X++, Y++, color = Mono Mask, ROP = rop */
+	cmd = SIS530_2D_CMD_COLOREXP | SIS530_2D_CMD_PAT_MONO_MASK |
+		SIS530_2D_CMD_DIR_X_INC | SIS530_2D_CMD_DIR_Y_INC | (rop << 8);
+
+	/* if background color == -1 then don't expand background pixels */
+	if (bg == -1)
+		cmd |= SIS530_2D_CMD_TRANSPARENT;
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+/**
+ *	sisfb_color_expand: - Color expand with Pattern Register
+ *	@sisfb: SiS Frame Buffer structure
+ *	@x: X origin
+ *	@y: Y origin
+ *	@width: width
+ *	@height: height
+ *	@fg: foreground color to expand
+ *	@bg: background color to expand
+ *	@rop: Raster Operation for the expand
+ *	@bitmap: monochrom bitmap (384 bytes max)
+ *	@bitmap_pitch: pitch of @bitmap
+ *
+ *	Color expand the bitmap @bitmap by setting bits with value 1 to @fg while bits
+ *	with value 0 to @bg. If @bg == -1 then background pixels are not expanded. The
+ *	bitmap is transfered to hardware Pattern Register and can be as large as 384 bytes,
+ *	effectively expanding 3072 pixels in a single operation.
+ *
+ *	The rectangle (@x, @y) - (@x + @width, @y + @height) is filled with the expanded
+ *	pattern. If the size of @bitmap is samller then 384 bytes and the size of the
+ *	rectangle is larger then 3072 pixels, some pixels in the rectangle are filled
+ *	with "garbage". 
+ *
+ *	Note:
+ *		1. The Source Pitch is width/8 then rounded up (i.e. in units of byte).
+ *		2. We have to use Normal ROPs with color in Source FG/BG Color Register.
+ *
+ */
+static void
+sisfb_color_expand(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width, u32 height,
+		   u32 fg, u32 bg, u8 rop, u8 * bitmap, u32 bitmap_pitch)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, bitmap_pitch);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (0, 0) */
+	sisfb_writew(sisfb, SIS530_2D_SRC_X, 0);
+	sisfb_writew(sisfb, SIS530_2D_SRC_Y, 0);
+
+	/* setup Destination X and Y origin  == (x, y) */
+	sisfb_writew(sisfb, SIS530_2D_DST_X, x);
+	sisfb_writew(sisfb, SIS530_2D_DST_Y, y);
+
+	/* setup Rectangle Width and Height */
+	sisfb_writew(sisfb, SIS530_2D_RECT_WIDTH, width);
+	sisfb_writew(sisfb, SIS530_2D_RECT_HEIGHT, height);
+
+	/* setup the foreground color in Source Foreground Color Register */
+	sisfb_writel(sisfb, SIS530_2D_SRC_FG_COLOR, fg);
+
+	/* setup the foreground color in Source Background Color Register */
+	sisfb_writel(sisfb, SIS530_2D_SRC_BG_COLOR, bg);
+
+	/* transfer bitmap pattern to pattern register */
+	memcpy_toio(sisfb->mmio_base_virt + SIS530_2D_PATTERN_REG,
+		    bitmap, bitmap_pitch * height);
+	
+	/* Command = Color Expand, X++, Y++, color = Pattern Register, ROP = rop */
+	cmd = SIS530_2D_CMD_COLOREXP |SIS530_2D_CMD_PAT_PAT_REG |
+		SIS530_2D_CMD_DIR_X_INC | SIS530_2D_CMD_DIR_Y_INC | (rop << 8);
+
+	/* if background color == -1 then don't expand background pixels */
+	if (bg == -1)
+		cmd |= SIS530_2D_CMD_TRANSPARENT;
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+static void
+sisfb_drawline(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+	       u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, 1);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, screen_offset) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS530_2D_LINE_X0, srcx);
+	sisfb_writew(sisfb, SIS530_2D_LINE_Y0, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS530_2D_LINE_X1, dstx);
+	sisfb_writew(sisfb, SIS530_2D_LINE_Y1, dsty);
+
+	/* setup Line Segement Count == 1 */
+	sisfb_writew(sisfb, SIS530_2D_LINE_COUNT, 1);
+	sisfb_writew(sisfb, SIS530_2D_LINE_STYLE_PERIOD, 0);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_BG_COLOR, bg);
+
+	/* Command = Color Expand, X++, Y++, color = Pattern Foreground Register, ROP = rop */
+	cmd = SIS530_2D_CMD_LINE_DRAW | SIS530_2D_CMD_PAT_FG_REG |
+		(rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+static void
+sisfb_drawline_style(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+		     u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop, u8 * bitmap)
+{
+	u32 cmd;
+	u16 pitch = sisfb->current_par.line_length;
+	u32 base = sisfb->current_par.screen_offset;
+
+	/* FixMe: What the hell is this ?? */
+	sisfb_set_agp_base(sisfb);
+
+	/* setup Source & Desination Pitch */
+	sisfb_writew(sisfb, SIS530_2D_SRC_PITCH, 1);
+	sisfb_writew(sisfb, SIS530_2D_DST_PITCH, pitch);
+
+	/* disable merge clipping */
+	sisfb_writew(sisfb, SIS530_2D_DST_HEIGHT, -1);
+
+	/* setup Source & Destination Base Address == (0, 0) */
+	sisfb_writel(sisfb, SIS530_2D_SRC_ADDR, 0);
+	sisfb_writel(sisfb, SIS530_2D_DST_ADDR, base);
+
+	/* setup Source X and Y origin  == (srcx, srcy) */
+	sisfb_writew(sisfb, SIS530_2D_LINE_X0, srcx);
+	sisfb_writew(sisfb, SIS530_2D_LINE_Y0, srcy);
+
+	/* setup Destination X and Y origin  == (dstx, dsty) */
+	sisfb_writew(sisfb, SIS530_2D_LINE_X1, dstx);
+	sisfb_writew(sisfb, SIS530_2D_LINE_Y1, dsty);
+
+	/* setup Line Segment Count == 1 */
+	sisfb_writew(sisfb, SIS530_2D_LINE_COUNT, 1);
+	sisfb_writew(sisfb, SIS530_2D_LINE_STYLE_PERIOD, 0);
+
+	/* setup the foreground color in Pattern Foreground Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_FG_COLOR, fg);
+
+	/* setup the foreground color in Pattern Background Color Register */
+	sisfb_writel(sisfb, SIS530_2D_PAT_BG_COLOR, bg);
+
+	/* transfer bitmap pattern to Line Style register */
+	sisfb_writel(sisfb, SIS530_2D_LINE_STYLE_0, * bitmap);
+	sisfb_writel(sisfb, SIS530_2D_LINE_STYLE_1, *(bitmap + 1));
+	
+	/* Command = Color Expand, X++, Y++, color = Pattern Register, ROP = rop */
+	cmd = SIS530_2D_CMD_LINE_DRAW | SIS530_2D_CMD_PAT_FG_REG |
+		SIS530_2D_CMD_LINE_STLYE_ENABLE | (rop << 8);
+
+	/* Fire The Command !! */
+	sisfb_writel(sisfb, SIS530_2D_CMD, cmd);
+	sisfb_writel(sisfb, SIS530_2D_CMD_STATUS, 0);
+}
+
+struct sisfb_accelerator sis530_accelerator = {
+	fillrect:		sisfb_fillrect,
+	copyrect:		sisfb_copyrect,
+	copyrect_transparent:	sisfb_copyrect_transparent,
+
+	color_expand_8x8:	sisfb_8x8_color_expand,
+	color_expand:		sisfb_color_expand,
+
+	drawline:		sisfb_drawline,
+	drawline_style:		sisfb_drawline_style,
+};
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_530_accel.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_accel.h
--- linux-2.4.21/drivers/video/sis/sisfb_530_accel.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_accel.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,72 @@
+#ifndef __SISFB_530_ACCEL__
+#define __SISFB_530_ACCEL__
+
+#include "sisfb_accel.h"
+
+enum sis530_2d_registers {
+	SIS530_2D_SRC_ADDR     = 0x8200,
+	SIS530_2D_SRC_PITCH    = 0x8204, SIS530_2D_AGP_BASE     = 0x8206,
+	SIS530_2D_SRC_Y        = 0x8208, SIS530_2D_SRC_X        = 0x820A,
+	SIS530_2D_DST_Y        = 0x820C, SIS530_2D_DST_X        = 0x820E,
+	SIS530_2D_DST_ADDR     = 0x8210,
+	SIS530_2D_DST_PITCH    = 0x8214, SIS530_2D_DST_HEIGHT   = 0x8216,
+	SIS530_2D_RECT_WIDTH   = 0x8218, SIS530_2D_RECT_HEIGHT  = 0x821A,
+	SIS530_2D_PAT_FG_COLOR = 0x821C,
+	SIS530_2D_PAT_BG_COLOR = 0x8220,
+	SIS530_2D_SRC_FG_COLOR = 0x8224,
+	SIS530_2D_SRC_BG_COLOR = 0x8228,
+	SIS530_2D_MONO_MASK    = 0x822C,
+	SIS530_2D_LEFT_CLIP    = 0x8234, SIS530_2D_TOP_CLIP     = 0x8236,
+	SIS530_2D_RIGHT_CLIP   = 0x8238, SIS530_2D_BOT_CLIP     = 0x823A,
+	SIS530_2D_CMD          = 0x823C,
+	SIS530_2D_CMD_STATUS   = 0x8240,
+	SIS530_2D_PATTERN_REG  = 0x8300
+};
+
+enum sis530_2d_registers_drawline {
+	SIS530_2D_LINE_X0      = 0x8208, SIS530_2D_LINE_Y0           = 0x820A,
+	SIS530_2D_LINE_X1      = 0x820C, SIS530_2D_LINE_Y1           = 0x820E,
+	SIS530_2D_LINE_COUNT   = 0x8218, SIS530_2D_LINE_STYLE_PERIOD = 0x821A,
+	SIS530_2D_LINE_STYLE_0 = 0x822C,
+	SIS530_2D_LINE_STYLE_1 = 0x8230,
+	SIS530_2D_LINE_Xn      = 0x8300, SIS530_2D_LINE_Yn           = 0x8302,
+};
+
+enum sis530_2d_register_transparent_bitblt {
+	SIS530_2D_TRANS_DEST_KEY_HIGH = 0x821C,
+	SIS530_2D_TRANS_DEST_KEY_LOW  = 0x8220,
+	SIS530_2D_TRANS_SRC_KEY_HIGH  = 0x8224,
+	SIS530_2D_TRANS_SRC_KEY_LOW   = 0x8228,
+};
+
+enum sis530_2d_cmd_type {
+	SIS530_2D_CMD_BITBLT             = 0x00, SIS530_2D_CMD_COLOREXP           = 0x01,
+	SIS530_2D_CMD_ENCOLOREXP         = 0x02, SIS530_2D_CMD_MULTIPLE_SCANLINE  = 0x03,
+	SIS530_2D_CMD_LINE_DRAW          = 0x04, SIS530_2D_CMD_TRAPEZOID_FILL     = 0x05,
+	SIS530_2D_CMD_TRANSPARENT_BITBLT = 0x06
+};
+
+enum sis530_2d_cmd_control {
+	SIS530_2D_CMD_SRC_VIDEO     = 0x00,
+	SIS530_2D_CMD_SRC_SYSTEM    = 0x10,
+	SIS530_2D_CMD_SRC_AGP       = 0x20,
+
+	SIS530_2D_CMD_PAT_FG_REG    = 0x00,
+	SIS530_2D_CMD_PAT_PAT_REG   = 0x40,
+	SIS530_2D_CMD_PAT_MONO_MASK = 0x80,
+
+	SIS530_2D_CMD_DIR_X_INC     = 0x00010000,
+	SIS530_2D_CMD_DIR_X_DEC     = 0x00000000,
+	SIS530_2D_CMD_DIR_Y_INC     = 0x00020000,
+	SIS530_2D_CMD_DIR_Y_DEC     = 0x00000000,
+
+	SIS530_2D_CMD_RECT_CLIP_EN    = 0x00040000,
+	SIS530_2D_CMD_MERGE_CLIP_DIS  = 0x04000000,
+	SIS530_2D_CMD_TRANSPARENT     = 0x00100000,
+
+	SIS530_2D_CMD_LINE_STLYE_ENABLE = 0x00800000
+};
+
+extern struct sisfb_accelerator sis530_accelerator;
+
+#endif /* __SISFB_530_ACCEL__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_530_core.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_core.c
--- linux-2.4.21/drivers/video/sis/sisfb_530_core.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_core.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,333 @@
+/* sisfb_530_core.c: Setting Video Mode for SiS 530/620 Integrated VGA
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 530 Host, PCI, 3D Graphics & Memory Controller Datasheet,
+ *	   Preliminary v1.0 Nov. 10, 1998
+ */
+
+#include "sisfb_lite.h"
+#include "sisfb_530_core.h"
+
+static void sisfb_get_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which);
+static void sisfb_set_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which);
+static void sisfb_set_memory_clocks(struct sisfb_info * sisfb);
+static int sisfb_get_memory_size(struct sisfb_info * sisfb);
+static void sisfb_set_crt1_crtc_regs(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_mode_regs(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_pitch(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_offset(struct sisfb_info * sisfb, struct sisfb_par * par);
+static void sisfb_set_crt1_vclk(struct sisfb_info * sisfb, struct sisfb_par * par);
+static int sisfb_set_fifo_thresholds(struct sisfb_info * sisfb, struct sisfb_par * par);
+
+/**
+ *	sisfb_get_clock: - Read the clock generator parameters
+ *	@sisfb: SiS Frame Buffer structure
+ *	@clock: Paramters of the clock generator (return)
+ *	@which: Which clock generator to be read.
+ *
+ *	Read the clock generator parameters to @clock form the hardware. The desired
+ *	clock generator is specified by @which. Valid values are MCLK for memory clock,
+ *	VCLK for video dot clock.
+ */
+static void
+sisfb_get_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which)
+{
+	u8 data, data1;
+
+	/* get divider and numerator */
+	data = sisfb_get_seq_reg(sisfb, which);
+	clock->divider   = ((data & 0x80) >> 7) + 1;
+	clock->numerator =  (data & ~0x80) + 1;
+
+	/* get denumerator and post scalar */
+	data = sisfb_get_seq_reg(sisfb, which + 1);
+	clock->denumerator = (data & 0x1F) + 1;
+
+	/* Bit 2 of post scaler is in SR13 */
+	data1 = sisfb_get_seq_reg(sisfb, SIS530_CLK);
+	if (which == SIS530_MCLK) {
+		data1 &= 0x80;
+		data1 >>= 5;
+	} else {
+		data1 &= 0x40;
+		data1 >>= 4;
+	}
+	clock->post_scalar = ((data & 0x60) >> 5) | data1;
+
+	/* get VCO gain */
+	data = sisfb_get_seq_reg(sisfb, which + 1);
+	clock->vco_gain = (data >> 7);
+}
+
+/**
+ *	sisfb_set_clock: - Set the clock generator parameters
+ *	@sisfb: SiS Frame Buffer structure
+ *	@clock: Paramters of the clock generator
+ *	@which: Which clock generator to be read.
+ *
+ *	Set the clock generator parameters @clock to the hardware. The desired clock
+ *	generator is specified by @which. Valid values are MCLK for memory clock,
+ *	VCLK for video dot clock.
+ */
+static void
+sisfb_set_clock(struct sisfb_info * sisfb, struct sisfb_clock_param * clock, int which)
+{
+	u8 data, data1;
+
+	/* set divider and numerator */
+	data  = (clock->numerator - 1) & 0x7F;
+	data |= (clock->divider   - 1) ? 0x80 : 0x00;
+	sisfb_set_seq_reg(sisfb, which, data);
+
+	/* set denumerator and post scalar */
+	data  = (clock->denumerator - 1) & 0x1F;
+	data |= ((clock->post_scalar - 1) & 0x03) << 5;
+	/* set VCO gain */
+	data |= clock->vco_gain ? 0x80 : 0x00;
+	sisfb_set_seq_reg(sisfb, which + 1, data);
+
+	/* set Bit 2 of post scalar
+	 * FixMe: sis86c201.c says SIS530_CLK should be set fist  */
+	data = sisfb_get_seq_reg(sisfb, SIS530_CLK);
+	if (which == SIS530_MCLK) {
+		data &= ~0x80;
+		data |= ((clock->post_scalar - 1) & 0x04) << 5;
+	} else {
+		data &= ~0x40;
+		data |= ((clock->post_scalar - 1) & 0x04) << 4;
+	}
+	sisfb_set_seq_reg(sisfb, SIS530_CLK, data);	
+}
+
+/**
+ *	sisfb_set_memory_clocks: - Set memory bus clock rate
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Set the memory clocks for VGA core.
+ */
+extern unsigned long mclk, eclk;
+static void __devinit
+sisfb_set_memory_clocks(struct sisfb_info * sisfb)
+{
+	struct sisfb_clock_param clock;
+
+	/* set the clock rate according to the option */
+	sisfb_calc_clock_param(&clock, mclk);
+	sisfb_set_clock(sisfb, &clock, SIS530_MCLK);
+
+	/* read the clock rate back and show to user */
+	sisfb_get_clock(sisfb, &clock, SIS300_MCLK);
+	printk(KERN_INFO "sisfb_lite: 2D Memory Clock = %6ld KHz\n",
+	       sisfb_calc_clock_freq(&clock));
+}
+
+/**
+ *	sisfb_get_memory_size: - Get framebuffer memory size
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	Get the framebuffer memory size from host controller. For SiS 530/620 Families,
+ *	the Shared Memory Area (SMA) is enabled in Bit 6, size is stored in Bit 4..5 of
+ *	Register 0x63, Host Bridge (i.e. PCI 0:0.0).
+ *
+ *	The register is set by DRAM initialzation code during boot process and can
+ *	not be re-configured once the DRAM has been turned on. 
+ */
+#define SIS530_BANKENABLE 0x63
+static int __devinit
+sisfb_get_memory_size(struct sisfb_info * sisfb)
+{
+	struct pci_dev * host = NULL;
+	u8 dram_status, sma_size, sma_size_bits;
+
+	if ((host = pci_find_slot(0, 0)) == NULL) {
+		printk(KERN_EMERG "sisfb_lite: Can not find Host Controller !!!\n");
+		return -ENODEV;
+	}
+
+	/* get SMA configuration from register 0x63 */
+	pci_read_config_byte(host, SIS530_BANKENABLE, &dram_status);
+
+	/* SMA not enabled */
+	if ((dram_status & 0x40) != 0x40)
+		return -ENODEV;
+
+	/* compute Shared Menory Area (SMA) size in Mega Bytes */
+	sma_size_bits = (dram_status >> 4) & 0x3;
+	sma_size = (2 << sma_size_bits);
+	sisfb->video_size_virt = sma_size * 1024 * 1024;
+
+	return 0;
+}
+
+static void
+sisfb_set_crt1_crtc_regs(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u8 data;
+	u16 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
+	u16 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
+	u16 overflow, overflow_h1, overflow_h2, overflow_v;
+
+	/* first convert 'par' to "screen" unit */
+	htotal       = (par->htotal     >> 3) - 5;
+	hdispend     = (par->hdispend   >> 3) - 1;
+	hblankstart  = (par->hsyncstart >> 3) - 1;
+	hblankend    = (par->hsyncend   >> 3);
+	hsyncstart   = (par->hsyncstart >> 3);
+	hsyncend     = (par->hsyncend   >> 3);
+
+	vtotal       = par->vtotal     - 2;
+	vdispend     = par->vdispend   - 1;
+	vsyncstart   = par->vsyncstart;
+	vsyncend     = par->vsyncend;
+	vblankstart  = par->vsyncstart;
+	vblankend    = par->vsyncend   + 1;
+
+	/* the "overlow" bits (8:15) of the screen parameters are spread all over
+	 * various registers */ 
+	overflow     = 
+		((vsyncstart  & 0x200) >> 2) | /* Bit 7, Vertical Retrace Start Bit 9 */
+		((vdispend    & 0x200) >> 3) | /* Bit 6, Vertical Display End   Bit 9 */
+		((vtotal      & 0x200) >> 4) | /* Bit 5, Vertical Total         Bit 9 */
+		0x10                         | /* Bit 4, line compare           Bit 8 */
+		((vblankstart & 0x100) >> 5) | /* Bit 3, Vertical Blank   Start Bit 8 */
+		((vsyncstart  & 0x100) >> 6) | /* Bit 2, Vertical Retrace Start Bit 8 */
+		((vdispend    & 0x100) >> 7) | /* Bit 1, Vertical Display End   Bit 8 */
+		((vtotal      & 0x100) >> 8);  /* Bit 0, Vertical Total         Bit 8 */
+
+	overflow_v  =
+		((vsyncstart  & 0x400) >> 7) | /* Bit 3, Vertical Retrace Start Bit 10 */
+		((vblankstart & 0x400) >> 8) | /* Bit 2, Vertical Blank   Start Bit 10 */
+		((vdispend    & 0x400) >> 9) | /* Bit 1, Vertical Display End   Bit 10 */
+		((vtotal      & 0x400) >> 10); /* Bit 0, Vertical Total         Bit 10 */
+
+	overflow_h  =
+		((hblankend   & 0x040) >> 2) | /* Bit 4, Horizontal Blank   End   Bit 6 */
+		((hsyncstart  & 0x100) >> 5) | /* Bit 3, Horizontal Retrace Start Bit 8 */
+		((hblankstart & 0x100) >> 6) | /* Bit 2, Horizontal Blank   Start Bit 8 */
+		((hdispend    & 0x100) >> 7) | /* Bit 1, Horizontal Display End   Bit 8 */
+		((htotal      & 0x100) >> 8);  /* Bit 0, Horizontal Total         Bit 8 */
+
+	/* write 'par' to hardware registers, Standard VGA part, low order bits */
+	sisfb_set_crtc_reg(sisfb, 0x00, htotal);
+	sisfb_set_crtc_reg(sisfb, 0x01, hdispend);
+	sisfb_set_crtc_reg(sisfb, 0x02, hblankstart);
+	sisfb_set_crtc_reg(sisfb, 0x03,
+			   0x80 |               /* Bit 7, Enable Vertical Retrace Start/End */
+			   (hblankend & 0x1f)); /* Bit 0:4,  Horizontal Blank  End Bit 0:4  */
+	sisfb_set_crtc_reg(sisfb, 0x04, hsyncstart);
+	sisfb_set_crtc_reg(sisfb, 0x05,
+			   (hblankend & 0x20) << 2 | /* Bit 7,   Horizontal Blank   End Bit 5   */
+			   (hsyncend & 0x1f));       /* Bit 0:4, Horizontal Retrace End Bit 0:4 */
+	sisfb_set_crtc_reg(sisfb, 0x06, vtotal);
+	sisfb_set_crtc_reg(sisfb, 0x09,
+			   0x40 |                       /* Bit 6, line compare         Bit 9 */
+			   (vblankstart & 0x200) >> 4); /* Bit 5, Vertical Blank Start Bit 9 */
+	sisfb_set_crtc_reg(sisfb, 0x10, vsyncstart);
+	sisfb_set_crtc_reg(sisfb, 0x11, (vsyncend & 0x0F) | 0x20);
+	sisfb_set_crtc_reg(sisfb, 0x12, vdispend);
+	sisfb_set_crtc_reg(sisfb, 0x15, vblankstart);
+	sisfb_set_crtc_reg(sisfb, 0x16, vblankend);
+
+	/* Standard VGA part, overflow bits */
+	sisfb_set_crtc_reg(sisfb, 0x07, overflow);
+
+	/* Extended Registers, overflow bits */
+	data = sisfb_get_seq_reg(sisfb, 0x0A) & 0xF0;
+	sisfb_set_seq_reg(sisfb, 0x0A, data | overflow_v);
+	data = sisfb_get_seq_reg(sisfb, 0x12) & 0xE0;
+	sisfb_set_seq_reg(sisfb, 0x0B, data | overflow_h);
+}
+
+/**
+ *	sisfb_set_crt1_mode_regs: - Set misc video mode registers
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Set color depth and enable 2D engine. The display line width register SR 0x10
+ *	is also enabled.
+ */
+static void
+sisfb_set_crt1_mode_regs(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u8 tmp;
+
+	/* enable Linear Addressing, Enhanced Graphics/Text Mode */
+	tmp = 0x83;
+	switch (par->bits_per_pixel) {
+	case 32:
+		tmp |= 0x10;
+		break;
+	case 16:
+		tmp |= 0x08;
+		break;
+	case 8:
+	default:
+		break;
+	}
+	sisfb_set_seq_reg(sisfb, 0x06, tmp);
+
+	/* enable 32 bpp ture color (instead of 24 ??) */
+	if (par->bits_per_pixel == 32) {
+		tmp = sisfb_get_seq_reg(sisfb, 0x09) | 0x80;
+		sisfb_set_seq_reg(sisfb, 0x09, tmp);
+		tmp = sisfb_get_seq_reg(sisfb, 0x0B) | 0x80;
+		sisfb_set_seq_reg(sisfb, 0x0B, tmp);
+	}
+
+	/* enable 2D engine programming, disable logical screen width
+	 * FixMe: move to init.c */
+	tmp = sisfb_get_seq_reg(sisfb, 0x27) | 0x70;
+	sisfb_set_seq_reg(sisfb, 0x27, tmp);
+}
+
+/**
+ *	sisfb_set_crt1_pitch: - Set screen pitch registers for CRT1
+ *	@sisfb: SiS Frame Buffer structure
+ *	@par: hardware specific parameters
+ *
+ *	Set the screen pitch registers for CRT1. Screen pitch refers to the memory address
+ *	difference between two dots of the same col on two vertically neighboring scan lines.
+ *	The CRTC 0x13 is called "offset register" in VGA literatures.
+ */
+static void
+sisfb_set_crt1_pitch(struct sisfb_info * sisfb, struct sisfb_par * par)
+{
+	u8 data;
+	u16 pitch = par->line_length >> 3;
+	u8 line_length = ((par->line_length + 63) >> 6) + 1;
+
+	/* disable line compare 
+	 * FixMe: move to init.c */
+	data = sisfb_get_seq_reg(sisfb, 0x38) | 0x20;
+	sisfb_set_seq_reg(sisfb, 0x38, data);
+
+	/* screen pitch, in units of double word */
+	sisfb_set_crtc_reg(sisfb, 0x13, pitch & 0xFF);
+	tmp = sisfb_get_seq_reg(sisfb, 0x0A);
+	sisfb_set_seq_reg(sisfb,  0x0A, (pitch >> 8) & tmp);
+}
+
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_530_core.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_core.h
--- linux-2.4.21/drivers/video/sis/sisfb_530_core.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_core.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,17 @@
+#ifndef __SISFB_530_CORE__
+#define __SISFB_530_CORE__
+
+#define TURBO_QUEUE_AREA_SIZE 0x80000	/* 512K */
+#define HW_CURSOR_AREA_SIZE   0x1000	/* 4K */
+
+enum clock_gen_base {
+	SIS530_CLK  = 0x13,
+	SIS530_MCLK = 0x28,
+	SIS530_DCLK = 0x2A,
+};
+
+extern int sisfb_config_memory(struct sisfb_info * sisfb);
+extern int sisfb_pan_display_300(struct fb_var_screeninfo * var, struct sisfb_info * sisfb);
+extern void sisfb_set_par_300(struct sisfb_par *par, struct sisfb_info * sisfb);
+
+#endif /* __SISFB_300_CORE__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_530_init.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_init.c
--- linux-2.4.21/drivers/video/sis/sisfb_530_init.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_530_init.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,113 @@
+/* sisfb_530_init.c: Initialization code for SiS 530/620 Integrated VGA
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 6326 AGP/PCI Graphics & Video Acclerator. Rev 1.0, May 12, 1997
+ *	2. SiS 530 Host, PCI, 3D Graphics & Memory Controller Datasheet,
+ *	   Preliminary v1.0 Nov. 10, 1998
+ */
+
+#include "sisfb_lite.h"
+#include "sisfb_530_core.h"
+#include "sisfb_530_accel.h"
+
+/**
+ *	sisfb_enable_turbo_queue: - Set Turbo Queue size and enable it
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Commands to the Graphics Engine (2D, 3D, etc) are buffered in
+ *	the Video Memory which is called Turbo Queue in SiS VGA Specs.
+ *	Usually this buffer area takes the last few KBs in the Video RAM.
+ */
+/* default turbo queue size == 32KB */
+static int tqueue_size = 0x8000;
+static void __devinit
+sisfb_enable_turbo_queue(struct sisfb_info * sisfb)
+{
+	u32 tqueue_pos;
+	u8 tqueue_status;
+
+	/* turbo queue position, in units of 32KB */
+	tqueue_pos = sisfb->video_size_virt - tqueue_size;
+	tqueue_pos /= 0x8000;
+
+	/* enable Turbo Tueue and Graphics Engine Programming */
+	tqueue_status = sisfb_get_seq_reg(sisfb, 0x27);
+	tqueue_status |= 0x80;
+
+	sisfb_set_seq_reg(sisfb, 0x27, tqueue_status);
+	sisfb_set_seq_reg(sisfb, 0x2C, tqueue_pos);
+
+	printk(KERN_INFO "sisfb_lite: Use %dKB off-screen memory for Turbo Queue\n",
+	       tqueue_size / 1024);
+
+}
+
+/**
+ *	sisfb_init_530: - Initialize the SiS530 VGA Core in SiS 530/620
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	SiS 300 VGA core is used in SiS 530/620 chipsets. This routine inits
+ *	the very SiS300 specific stuff.
+ */
+int __devinit
+sisfb_init_530(struct sisfb_info * sisfb)
+{
+	int ret;
+
+	if ((ret = sisfb_config_memory(sisfb)) < 0)
+		return ret;
+
+	sisfb_init_legacy_vga(sisfb);
+
+#if 0
+	/* set to High Speed DAC by default */
+	sisfb_set_seq_reg(sisfb, 0x07, 0x13);
+
+	/* Disable DAC pedestal */
+	sisfb_set_seq_reg(sisfb, 0x1F, 0x00);
+
+	sisfb_set_pci_agp_timming(sisfb);
+
+	/* disable power management mode */
+	sisfb_set_seq_reg(sisfb, 0x11, 0x0F);
+
+	/* set screen start memory address bit 23:16 to 0, bit 15:0 are in CR0C, CR0D */
+	sisfb_set_seq_reg(sisfb, 0x0D, 0x00);
+
+	sisfb_enable_turbo_queue(sisfb);
+
+	sisfb_fake_vgabios(sisfb);
+#endif
+
+	/* set hardware specific functions */
+	sisfb->accelerator = &sis530_accelerator;
+	sisfb->set_par = sisfb_set_par_530;
+	sisfb->pan_display = sisfb_pan_display_53;
+	sisfb->set_disp = sisfb_set_dispsw_accel;
+
+	return 0;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_accel.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_accel.c
--- linux-2.4.21/drivers/video/sis/sisfb_accel.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_accel.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,359 @@
+/* sisfb_accel.c: Generic 2D Hardware Acceleration Layer for Text Mode Console (fbcon)
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ */
+
+#include "sisfb_accel.h"
+
+static void
+sisfb_cfbX_bmove(struct display *disp, int sy, int sx, int dy, int dx,
+		 int height, int width)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+
+	sx *= fontwidth(disp);
+	sy *= fontheight(disp);
+	dx *= fontwidth(disp);
+	dy *= fontheight(disp);
+	width *= fontwidth(disp);
+	height *= fontheight(disp);
+
+	accel->copyrect(sisfb, sx, sy, dx, dy, width, height, ROP_COPY);
+}
+
+static void
+sisfb_cfbX_clear(struct display *disp, int sy, int sx, int height,
+		 int width, u32 color)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+
+	sx *= fontwidth(disp);
+	sy *= fontheight(disp);
+	width *= fontwidth(disp);
+	height *= fontheight(disp);
+
+	accel->fillrect(sisfb, sx, sy, width, height, color, ROP_COPY_PAT);
+}
+
+static void
+sisfb_cfbX_putc(struct display *disp, int c, int sy, int sx, u32 fg, u32 bg)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+	int width    = fontwidth(disp);
+	int height   = fontheight(disp);
+	int width_b  = (width + 7) >> 3;
+	u8 * bitmap = disp->fontdata + (c & disp->charmask) * height * width_b;
+
+	sx *= fontwidth(disp);
+	sy *= fontheight(disp);
+
+	accel->color_expand(sisfb, sx, sy, width, height, fg, bg,
+			    ROP_COPY, bitmap, width_b);
+}
+
+static void
+sisfb_cfbX_putcs(struct display *disp, unsigned short * s, int count,
+		 int sy, int sx, u32 fg, u32 bg)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+	int width    = fontwidth(disp);
+	int height   = fontheight(disp);
+	int width_b  = (width + 7) >> 3;
+
+	sx *= fontwidth(disp);
+	sy *= fontheight(disp);
+
+	while (count--) {
+		u16 c;
+		u8 * bitmap;
+
+		c = scr_readw(s++) & disp->charmask;
+		bitmap = disp->fontdata + c * height * width_b;
+
+		accel->color_expand(sisfb, sx, sy, width, height, fg, bg,
+				    ROP_COPY, bitmap, width_b);
+
+		sx += fontwidth(disp);
+	}
+}
+
+static void
+sisfb_cfbX_revc(struct display *disp, int sx, int sy)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+	int width    = fontwidth(disp);
+	int height   = fontheight(disp);
+	int bpp      = sisfb->current_par.bits_per_pixel;
+
+	accel->fillrect(sisfb, sx * width, sy * height, width, height,
+		       (bpp == 8) ? 0x0f : 0xffffffff, ROP_XOR_PAT);
+}
+
+#ifdef FBCON_HAS_CFB8
+static void
+sisfb_cfb8_clear(struct vc_data *conp, struct display *disp,
+		 int sy, int sx, int height, int width)
+{
+	u32 color;
+
+	color = attr_bgcol_ec(disp, conp);
+
+	sisfb_cfbX_clear(disp, sy, sx, height, width, color);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void
+sisfb_cfb16_clear(struct vc_data *conp, struct display *disp,
+		  int sy, int sx, int height, int width)
+{
+	u32 color;
+
+	color = ((u16 *) disp->dispsw_data)[attr_bgcol_ec(disp, conp)];
+
+	sisfb_cfbX_clear(disp, sy, sx, height, width, color);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void
+sisfb_cfb32_clear(struct vc_data * conp, struct display * disp,
+		  int sy, int sx, int height, int width)
+{
+	u32 color;
+
+	color = ((u32 *) disp->dispsw_data)[attr_bgcol_ec(disp, conp)];
+	sisfb_cfbX_clear(disp, sy, sx, height, width, color);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB8
+static void
+sisfb_cfb8_putc(struct vc_data * conp, struct display * disp, int c, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = attr_fgcol(disp, c);
+	bg = attr_bgcol(disp, c);
+
+	sisfb_cfbX_putc(disp, c, sy, sx, fg, bg);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void
+sisfb_cfb16_putc(struct vc_data * conp, struct display * disp, int c, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = ((u16 *)disp->dispsw_data)[attr_fgcol(disp, c)];
+	bg = ((u16 *)disp->dispsw_data)[attr_bgcol(disp, c)];
+
+	sisfb_cfbX_putc(disp, c, sy, sx, fg, bg);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void
+sisfb_cfb32_putc(struct vc_data * conp, struct display * disp, int c, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = ((u32 *)disp->dispsw_data)[attr_fgcol(disp, c)];
+	bg = ((u32 *)disp->dispsw_data)[attr_bgcol(disp, c)];
+
+	sisfb_cfbX_putc(disp, c, sy, sx, fg, bg);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB8
+static void
+sisfb_cfb8_putcs(struct vc_data * conp, struct display * disp, const unsigned short *s,
+		 int count, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = attr_fgcol(disp, *s);
+	bg = attr_bgcol(disp, *s);
+
+	sisfb_cfbX_putcs(disp, s, count, sy, sx, fg, bg);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static void
+sisfb_cfb16_putcs(struct vc_data * conp, struct display * disp, const unsigned short *s,
+		  int count, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = ((u16 *)disp->dispsw_data)[attr_fgcol(disp, *s)];
+	bg = ((u16 *)disp->dispsw_data)[attr_bgcol(disp, *s)];
+
+	sisfb_cfbX_putcs(disp, s, count, sy, sx, fg, bg);
+}
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void
+sisfb_cfb32_putcs(struct vc_data * conp, struct display * disp, const unsigned short *s,
+		  int count, int sy, int sx)
+{
+	u32 fg, bg;
+
+	fg = ((u32 *)disp->dispsw_data)[attr_fgcol(disp, *s)];
+	bg = ((u32 *)disp->dispsw_data)[attr_bgcol(disp, *s)];
+
+	sisfb_cfbX_putcs(disp, s, count, sy, sx, fg, bg);
+}
+#endif
+
+/**
+ *	sisfb_cfbX_clear_margins: - Clear the margin of the text console
+ *	@conp:
+ *	@disp:
+ *	@bottom_onlly:
+ *
+ *	It's used to clear the margins around the region used for the emulated text
+ *	console, when the resolution of the (virtual) screen is not a multiple of the
+ *	font size, or when you want a small text console in the center of the screen
+ *	(on Sparc). `bottom_only' means clear the bottom area only, which is useful
+ *	when panning (using the virtual screen).
+ */
+static void
+sisfb_cfbX_clear_margins(struct vc_data * conp, struct display * disp,
+			 int bottom_only)
+{
+	struct sisfb_info *sisfb = (struct sisfb_info *) (disp->fb_info);
+	struct sisfb_accelerator * accel = 
+		(struct sisfb_accelerator *) (sisfb->accelerator);
+	unsigned int cell_w = fontwidth(disp);
+	unsigned int cell_h = fontheight(disp);
+	unsigned int right_width   = disp->var.xres % cell_w;
+	unsigned int bottom_height = disp->var.yres % cell_h;
+	unsigned int right_start   = disp->var.xres - right_width;
+	unsigned int bottom_start  = disp->var.yres - bottom_height;
+
+	if (!bottom_only && right_width) {
+		/* clear whole right margin, not only visible portion */
+		accel->fillrect(sisfb,
+				disp->var.xoffset + right_start, 0,
+				right_width, disp->var.yres_virtual,
+				0x0000, ROP_COPY_PAT);
+	}
+
+	if (bottom_height) {
+		accel->fillrect(sisfb,
+				disp->var.xoffset, disp->var.yoffset + bottom_start,
+				right_start, bottom_height,
+				0x0000, ROP_COPY_PAT);
+	}
+}
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch sisfb_cfb8 = {
+	setup:		fbcon_cfb8_setup,
+	bmove:		sisfb_cfbX_bmove,
+	clear:		sisfb_cfb8_clear,
+	putc:		sisfb_cfb8_putc,
+	putcs:		sisfb_cfb8_putcs,
+	revc:		sisfb_cfbX_revc,
+	cursor:		NULL,
+	clear_margins:	sisfb_cfbX_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB16
+static struct display_switch sisfb_cfb16 = {
+	setup:		fbcon_cfb16_setup,
+	bmove:		sisfb_cfbX_bmove,
+	clear:		sisfb_cfb16_clear,
+	putc:		sisfb_cfb16_putc,
+	putcs:		sisfb_cfb16_putcs,
+	revc:		sisfb_cfbX_revc,
+	cursor:		NULL,
+	clear_margins:	sisfb_cfbX_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static struct display_switch sisfb_cfb32 = {
+	setup:		fbcon_cfb32_setup,
+	bmove:		sisfb_cfbX_bmove,
+	clear:		sisfb_cfb32_clear,
+	putc:		sisfb_cfb32_putc,
+	putcs:		sisfb_cfb32_putcs,
+	revc:		sisfb_cfbX_revc,
+	cursor:		NULL,
+	clear_margins:	sisfb_cfbX_clear_margins,
+	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+void
+sisfb_set_dispsw_accel(struct display *disp, struct sisfb_info *sisfb,
+			int bpp, int accel)
+{
+	switch (bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &sisfb_cfb8;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 15:
+	case 16:
+		disp->dispsw = &sisfb_cfb16;
+		disp->dispsw_data = sisfb->fbcon_cmap.cfb16;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		disp->dispsw = &sisfb_cfb32;
+		disp->dispsw_data = sisfb->fbcon_cmap.cfb32;
+		break;
+#endif
+
+	default:
+		disp->dispsw = &fbcon_dummy;
+		return;
+	}
+
+	disp->scrollmode = SCROLL_YREDRAW;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_accel.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_accel.h
--- linux-2.4.21/drivers/video/sis/sisfb_accel.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_accel.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,96 @@
+#ifndef __SISFB_ACCEL__
+#define __SISFB_ACCEL__
+
+#ifdef __KERNEL__
+#include "sisfb_lite.h"
+#endif /* __KERNEL__ */
+
+#define PAT_REG_SIZE 384
+
+enum sisfb_raster_op_bitblt {
+	ROP_CLEAR		= 0x00, /* dst =    0,            0    */
+	ROP_AND			= 0x88, /* dst =  dst &  src,     DSa  */
+	ROP_AND_REVERSE		= 0x44, /* dst = ~dst &  src,     SDna */
+	ROP_COPY		= 0xCC, /* dst =  src,            S    */
+	ROP_AND_INVERTED	= 0x22, /* dst =  dst & ~src,     DSna */
+	ROP_NOOP		= 0xAA, /* dst =  dst,            D    */
+	ROP_XOR			= 0x66, /* dst =  dst ^  src,     DSx  */
+	ROP_OR			= 0xEE, /* dst =  dst |  src,     DSo  */
+	ROP_NOR			= 0x11, /* dst =  ~(dst | src),   DSon */
+	ROP_EQUIV		= 0x99, /* dst =  dst ^ ~src,     DSxn */
+	ROP_INVERT  		= 0x55, /* dst = ~dst,            Dn   */
+	ROP_OR_INVERSE		= 0xDD, /* dst = ~dst | src,      SDno */
+	ROP_COPY_INVERTED	= 0x33, /* dst = ~src,            Sn   */
+	ROP_OR_INVERTED		= 0xBB, /* dst = ~src | dst,      DSno */
+	ROP_NAND		= 0x77, /* dst = ~(dst & src),    DSan */
+	ROP_SET			= 0xFF, /* dst =    1,            1    */
+
+	/* same as above, but with pattern as source */
+	ROP_CLEAR_PAT		= 0x00, /* dst =    0,            0    */
+	ROP_AND_PAT		= 0xA0, /* dst =  dst &  src,     DSa  */
+	ROP_AND_REVERSE_PAT	= 0x50, /* dst = ~dst &  src,     SDna */
+	ROP_COPY_PAT		= 0xF0, /* dst =  src,            S    */
+	ROP_AND_INVERTED_PAT	= 0x0A, /* dst =  dst & ~src,     DSna */
+	ROP_NOOP_PAT		= 0xAA, /* dst =  dst,            D    */
+	ROP_XOR_PAT		= 0x5A, /* dst =  dst ^  src,     DSx  */
+	ROP_OR_PAT		= 0xFA, /* dst =  dst |  src,     DSo  */
+	ROP_NOR_PAT	       	= 0x05, /* dst =  ~(dst | src),   DSon */
+	ROP_EQUIV_PAT		= 0xA5, /* dst =  dst ^ ~src,     DSxn */
+	ROP_INVERT_PAT		= 0x55, /* dst = ~dst,            Dn   */
+	ROP_OR_REVERSE_PAT	= 0xDD, /* dst = ~dst | src,      SDno */
+	ROP_COPY_INVERTED_PAT	= 0x0F, /* dst = ~src,            Sn   */
+	ROP_OR_INVERTED_PAT	= 0xAF, /* dst = ~src | dst,      DSno */
+	ROP_NAND_PAT		= 0x5F, /* dst = ~(dst & src),    DSan */
+	ROP_SET_PAT		= 0xFF, /* dst =    1,            1    */
+};
+
+enum sisfb_color_key_mode {
+	KEYMODE_NEVER			= 0x00,
+	KEYMODE_DESTKEY_NOTSRCKEY	= 0x02,
+	KEYMODE_DESTKEY			= 0x03,
+	KEYMODE_NOTSRCKEY		= 0x0A,
+	KEYMODE_ALWAYS			= 0x0F
+};
+
+struct sisfb_accelerator {
+	void (*fillrect)(struct sisfb_info *sisfb, u32 x, u32 y,
+			  u32 width, u32 height, u32 color, u8 rop);
+	void (*copyrect)(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+			 u32 dstx, u32 dsty, u32 width, u32 height, u8 rop);
+	void (*copyrect_transparent)(struct sisfb_info *sisfb, u32 srcx, u32 srcy,
+				     u32 dstx, u32 dsty, u32 width, u32 height,
+				     u32 src_hi, u32 src_low,
+				     u32 dst_hi, u32 dst_low,
+				     u8 key_mode);
+
+	void (*color_expand_8x8)(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width,
+				 u32 height, u32 fg, u32 bg, u8 rop, u8 * bitmap);
+	void (*color_expand)(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width,
+			     u32 height, u32 fg, u32 bg, u8 rop, u8 * bitmap,
+			     u32 bitmap_pitch);
+
+	void (*drawline)(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+			 u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop);
+	void (*drawline_style)(struct sisfb_info * sisfb, u32 srcx, u32 srcy,
+			       u32 dstx, u32 dsty, u32 fg, u32 bg, u8 rop,
+			       u8 * bitmap);
+
+#if 0
+	/* not implemented yet */
+	void (color_expand_enhanced)(struct sisfb_info * sisfb,  u32 x, u32 y, u32 width,
+				     u32 height, u32 fg, u32 bg, u8 rop,
+				     u8 * bitmap, u32 bitmap_pitch)
+
+	void (*span_fill)(struct sisfb_info * sisfb, u32 srcy, u32 fg, u32 bg,
+			  u32 *span, u8 rop, u8 * bitmap);
+
+	void (*trapezoid_fill)(struct sisfb_info * sisfb, ...);
+#endif
+};
+
+#ifdef __KERNEL__
+void sisfb_set_dispsw_accel(struct display *disp, struct sisfb_info *sisfb, int bpp, int accel);
+
+#endif /* __KERNEL_ */
+
+#endif /* __SISFB_ACCEL__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_legacy_init.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_legacy_init.c
--- linux-2.4.21/drivers/video/sis/sisfb_legacy_init.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_legacy_init.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,313 @@
+/* sisfb_legacy_init.c: Initialization code for Legacy VGA Registers
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 6326 AGP/PCI Graphics & Video Acclerator. Rev 1.0, May 12, 1997
+ *	2. SiS 530 Host, PCI, 3D Graphics & Memory Controller Datasheet,
+ *	   Preliminary v1.0 Nov. 10, 1998
+ *	3. Programmer's Guide to the EGA, VGA, and Super VGA Card. Third Edition,
+ *	   Richard F. Ferraro, Addison-Welsey, Aug. 1994
+ */
+
+#include "sisfb_lite.h"
+
+static void sisfb_set_default_misc_reg(struct sisfb_info * sisfb);
+static void sisfb_set_default_seq_regs(struct sisfb_info * sisfb);
+static void sisfb_set_default_crtc_regs(struct sisfb_info * sisfb);
+static void sisfb_set_default_grc_regs(struct sisfb_info * sisfb);
+static void sisfb_set_default_attr_regs(struct sisfb_info * sisfb);
+static void sisfb_permute_dac_rgb(struct sisfb_info * sisfb, u8 * colors);
+static void sisfb_load_default_palette(struct sisfb_info * sisfb);
+void sisfb_init_legacy_vga(struct sisfb_info * sisfb);
+
+static u8 default_vga_palette[] __initdata = {
+	/* Palette 0-15, original EGA 16 colors stored as 00bbggrr where
+	 * bbggrr are 2 bits index to the color values {0, 42, 21, 63} */
+	0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15,
+	0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F,
+
+	/* Palette 16-31, 16 evenly spaced shades of gray */
+	0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18,
+	0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F,
+
+	/* Palette 32-247, 24 colors group generated form 5 elements,
+	 * each group has 3 intensity and 3 saturation levels */
+	0x00, 0x10, 0x1F, 0x2F, 0x3F,
+	0x1F, 0x27, 0x2F, 0x37, 0x3F,
+	0x2D, 0x31, 0x36, 0x3A, 0x3F,
+	0x00, 0x07, 0x0E, 0x15, 0x1C,
+	0x0E, 0x11, 0x15, 0x18, 0x1C,
+	0x14, 0x16, 0x18, 0x1A, 0x1C,
+	0x00, 0x04, 0x08, 0x0C, 0x10,
+	0x08, 0x0A, 0x0C, 0x0E, 0x10,
+	0x0B, 0x0C, 0x0D, 0x0F, 0x10
+};
+
+/**
+ *	sisfb_set_default_misc_reg: - Set default value for standard VGA Miscellaneouse
+ *	Output Register
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Miscellaneouse Output Register is used for selecting Sync Polarity, Clock Generator
+ *	and Enable/Disable IO/MEM address space.
+ *
+ *	The Miscellaneouse Output Register is programmed with 0x6F => VGA 400 lines,
+ *	internal clock generator, MEM/IO address enabled.
+ *
+ *	This function is needed to be called once at driver initialization.
+ */
+static void __devinit
+sisfb_set_default_misc_reg(struct sisfb_info * sisfb)
+{
+	sisfb_set_gen_reg(sisfb, 0x3c2, 0x6F);
+}
+
+/**
+ *	sisfb_set_default_seq_regs: - Set default values for standard VGA Sequencer Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Most of the Seqencer Registers are used for "backward compability" with EGA cards.
+ *	The really essential registers are SR0 for reset and SR1 for turnning on/off the
+ *	display.
+ *
+ *	This function is needed to be called once at driver initialization.
+ */
+static void __devinit
+sisfb_set_default_seq_regs(struct sisfb_info * sisfb)
+{
+	/* recover from Reset state */
+	sisfb_set_seq_reg(sisfb, 0x00, 0x03);
+
+	/* set SR1 Bit5: Screen Off , Bit 0, 9 dots/char (why not 8 ??) */
+	sisfb_set_seq_reg(sisfb, 0x01, 0x21);
+
+	/* Enable bit plane 0-3 */
+	sisfb_set_seq_reg(sisfb, 0x02, 0x0F);
+
+	/* Use Character Table 0 */
+	sisfb_set_seq_reg(sisfb, 0x03, 0x00);
+
+	/* Enable 4-Chain Mode, Disable Odd/Even Mode, Enable 256KB Memory */
+	sisfb_set_seq_reg(sisfb, 0x04, 0x0E);
+}
+
+/**
+ *	sisfb_set_default_crtc_regs: - Set default values for standard VGA CRT
+ *	Controller Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Most of the CRT Controllers Registers are display mode specific, they are set
+ *	in various node setting routines. 
+ *
+ *	This function is needed to be called once at driver initialization.
+ */
+static void __devinit
+sisfb_set_default_crtc_regs(struct sisfb_info * sisfb)
+{
+	/* Disable Vertical Panning */
+	sisfb_set_crtc_reg(sisfb, 0x08, 0x00);
+
+	/* No text cursor */
+	sisfb_set_crtc_reg(sisfb, 0x0A, 0x00);
+	sisfb_set_crtc_reg(sisfb, 0x0B, 0x00);
+
+	/* Screen start from 0 */
+	sisfb_set_crtc_reg(sisfb, 0x0C, 0x00);
+	sisfb_set_crtc_reg(sisfb, 0x0D, 0x00);
+
+	/* Text cursor at 0 */
+	sisfb_set_crtc_reg(sisfb, 0x0E, 0x00);
+	sisfb_set_crtc_reg(sisfb, 0x0F, 0x00);
+
+	/* Enable Double Word Mode */
+	sisfb_set_crtc_reg(sisfb, 0x14, 0x40);
+
+	/* Enable vertical and horizonal retrace,
+	   sequential memory addressing */
+	sisfb_set_crtc_reg(sisfb, 0x17, 0xA3);
+	/* set line compare Bit 0..7 to 0xFF */
+	sisfb_set_crtc_reg(sisfb, 0x18, 0xFF);
+}
+
+/**
+ *	sisfb_set_default_grc_regs: - Set default values for standard VGA Graphics
+ *	Controller Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Graphics Controller Registers are used for "backward compability" with EGA cards.
+ *	These registers are not actually used by this driver. Set them to some sane values
+ *	or clear to 0.
+ *
+ *	This function is needed to be called once at driver initialization.
+ *
+ *	FixME: GR05 Bit 6 seem to be used for 256-color stuff, is it really needed ??
+ */
+static void __devinit
+sisfb_set_default_grc_regs(struct sisfb_info * sisfb)
+{
+	int i;
+
+	/* GR0-GR4 are not used by VGA, clear them */
+	for (i = 0; i <= 0x04; i++) {
+		sisfb_set_grc_reg(sisfb, i, 0x00);
+	}
+
+	/* enable 256-color mode */
+	sisfb_set_grc_reg(sisfb, 0x05, 0x40);
+
+	/* Graphics Mode, Memory Address 0xA0000 to 0xAFFFF */
+	sisfb_set_grc_reg(sisfb, 0x06, 0x05);
+	sisfb_set_grc_reg(sisfb, 0x07, 0x0F);
+	sisfb_set_grc_reg(sisfb, 0x08, 0xFF);
+}
+
+/**
+ *	sisfb_set_default_attr_regs: - Set default values for standard VGA Attribute Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Attribute Registers are used for "backward compability" with EGA cards. These
+ *	registers are not actually used by this driver. Set them to some sane values
+ *	or clear to 0.
+ *
+ *	This function is needed to be called once at driver initialization.
+ */
+static void __devinit
+sisfb_set_default_attr_regs(struct sisfb_info * sisfb)
+{
+	int i;
+
+	/* Color Palette Registers AR0-ARF are used for EGA compability,
+	 * set them as "identical mapping" */
+	for (i = 0; i <= 0x0F; i++) {
+		sisfb_set_attr_reg(sisfb, i, i);
+	}
+
+	/* AR10-AR14 are not used by VGA, clear them */
+	for (i = 0x10; i <= 0x14; i++) {
+		sisfb_set_attr_reg(sisfb, i, 0x00);
+	}
+
+	/* Set the Palette Address Source to Video Memory */
+	sisfb_get_gen_reg(sisfb, 0x3DA);
+	sisfb_set_gen_reg(sisfb, 0x3C0, 0x20);
+}
+
+/**
+ *	sisfb_permute_dac_rgb: - Program the DAC color registers for a color group
+ *	@sisfb: SiS Frame Buffer structure
+ *	@colors: Color elements in a color group
+ *
+ *	Generate the 24 permutation of the colors in each color group and program the
+ *	DAC color registers in the pre-defined order.
+ */
+static void __devinit
+sisfb_permute_dac_rgb(struct sisfb_info * sisfb, u8 * colors)
+{
+	int i;
+
+	for (i = 0; i < 5; i++)
+		sisfb_set_dac_rgb(sisfb, colors[i], colors[0], colors[4]);
+	for (i = 3; i > 0; i--)
+		sisfb_set_dac_rgb(sisfb, colors[4], colors[0], colors[i]);
+
+	for (i = 0; i < 5; i++)
+		sisfb_set_dac_rgb(sisfb, colors[4], colors[i], colors[0]);
+	for (i = 3; i > 0; i--)
+		sisfb_set_dac_rgb(sisfb, colors[i], colors[4], colors[0]);
+
+	for (i = 0; i < 5; i++)
+		sisfb_set_dac_rgb(sisfb, colors[0], colors[4], colors[i]);
+	for (i = 3; i > 0; i--)
+		sisfb_set_dac_rgb(sisfb, colors[0], colors[i], colors[4]);
+}
+
+/**
+ *	sisfb_load_default_palette: - Load the default VGA Palette.
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Load the pre-defined standard VGA Palette default_vga_palette by writing
+ *	to DAC color registers.
+ */
+static void __devinit
+sisfb_load_default_palette(struct sisfb_info * sisfb)
+{
+	int i, level;
+    	u8 data;
+	u8 * table = default_vga_palette;
+
+	/* set PEL Mask */
+	sisfb_set_gen_reg(sisfb, 0x3C6, 0xFF);
+	sisfb_set_dac_index(sisfb, 0x00);
+
+	/* 0-15, 16 colors initially loaded to EGA color palette */
+	for (i = 0; i < 16; i++) {
+		u8 ega_colors[] = {0, 42, 21, 63};
+		u8 red, green, blue;
+
+		/* data == 00bbggrr */
+		data  = table[i];
+		red   = ega_colors[((data >> 0) & 0x03)];
+		green = ega_colors[((data >> 2) & 0x03)];
+		blue  = ega_colors[((data >> 4) & 0x03)];
+		sisfb_set_dac_rgb(sisfb, red, green, blue);
+	}
+
+	/* 16-31, 16 evenly spaced shades of gray */
+	for (i = 16; i < 32; i++) {
+		data = table[i];
+		sisfb_set_dac_rgb(sisfb, data, data, data);
+	}
+
+	/* for each of 3 intensity x 3 saturation == 9 levels */
+	for (level = 0; level < 9; level++) {
+		u8 * colors = table + 32;
+		sisfb_permute_dac_rgb(sisfb, colors);
+		colors += 5;
+	}
+
+	/* last 8 entries are cleared to 0 for black */
+	for (i = 0; i < 8; i++) {
+		sisfb_set_dac_rgb(sisfb, 0x00, 0x00, 0x00);
+	}
+}
+
+/**
+ *	sisfb_init_legacy_vga: - Initialize the Standard VGA Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Call other help functions to initialize the standard/legacy VGA registers.
+ */
+void __devinit
+sisfb_init_legacy_vga(struct sisfb_info * sisfb)
+{
+	sisfb_set_default_seq_regs(sisfb);
+	sisfb_set_default_misc_reg(sisfb);
+	sisfb_set_default_attr_regs(sisfb);
+	sisfb_set_default_grc_regs(sisfb);
+	sisfb_load_default_palette(sisfb);
+
+	/* you have to load CRTC registers last or SiS 630E and SiS 630S
+	   will not work. I have no idea why */
+	sisfb_set_default_crtc_regs(sisfb);
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_legacy_vga.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_legacy_vga.h
--- linux-2.4.21/drivers/video/sis/sisfb_legacy_vga.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_legacy_vga.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,300 @@
+#ifndef __SISFB_LEGACY_VGA__
+#define __SISFB_LEGACY_VGA__
+
+/* VGA register Offsets */
+#define ATTR_WRITE           0x40
+#define ATTR_READ            0x41
+#define MISC_OUT_W           0x42
+#define SEQ_ADDR             0x44
+#define SEQ_DATA             0x45
+#define PEL_MASK             0x46
+#define DACR_ADDR            0x47
+#define DACW_ADDR            0x48
+#define DAC_DATA             0x49
+#define MISC_OUT_R           0x4C
+#define GRC_ADDR             0x4E
+#define GRC_DATA             0x4F
+#define CRTC_ADDR            0x54
+#define CRTC_DATA            0x55
+
+#define FEATURE_READ         0x4A
+#define FEATURE_WRITE        0x5A
+
+#define SIS_PASSWD           0x05
+#define SIS_PASSWD_LOCK      0x21
+#define SIS_PASSWD_UNLOCK    0x86
+
+static inline void
+sisfb_writeb(struct sisfb_info *sisfb, u32 offset, u8 val)
+{
+	writeb(val, sisfb->mmio_base_virt + offset);
+}
+
+static inline void
+sisfb_writew(struct sisfb_info *sisfb, u32 offset, u16 val)
+{
+	writew(val, sisfb->mmio_base_virt + offset);
+}
+
+static inline void
+sisfb_writel(struct sisfb_info *sisfb, u32 offset, u32 val)
+{
+	writel(val, sisfb->mmio_base_virt + offset);
+}
+
+static inline u8
+sisfb_readb(struct sisfb_info *sisfb, u32 offset)
+{
+	return readb(sisfb->mmio_base_virt + offset);
+}
+
+static inline u16
+sisfb_readw(struct sisfb_info *sisfb, u32 offset)
+{
+	return readw(sisfb->mmio_base_virt + offset);
+}
+
+static inline u32
+sisfb_readl(struct sisfb_info *sisfb, u32 offset)
+{
+	return readl(sisfb->mmio_base_virt + offset);
+}
+
+static inline void
+sisfb_set_gen_reg(struct sisfb_info * sisfb, u16 port, u8 data)
+{
+	u16 base = sisfb->vga_io_base;
+
+	outb(data, port + base - 0x380);
+}
+
+static inline u8
+sisfb_get_gen_reg(struct sisfb_info * sisfb, u16 port)
+{
+	u16 base = sisfb->vga_io_base;
+
+	return inb(port + base - 0x380);
+}
+
+static inline void
+sisfb_set_seq_reg(struct sisfb_info * sisfb, u8 index, u8 data)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + SEQ_ADDR);
+	outb(data, port + SEQ_DATA);
+}
+
+static inline u8
+sisfb_get_seq_reg(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + SEQ_ADDR);
+	return inb(port + SEQ_DATA);
+}
+
+static inline void
+sisfb_set_crtc_reg(struct sisfb_info * sisfb, u8 index, u8 data)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + CRTC_ADDR);
+	outb(data, port + CRTC_DATA);
+}
+
+static inline u8
+sisfb_get_crtc_reg(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + CRTC_ADDR);
+	return inb(port + CRTC_DATA);
+}
+
+static inline void
+sisfb_set_grc_reg(struct sisfb_info * sisfb, u8 index, u8 data)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + GRC_ADDR);
+	outb(data, port + GRC_DATA);
+}
+
+static inline u8
+sisfb_get_grc_reg(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + GRC_ADDR);
+	return inb(port + GRC_DATA);
+}
+
+static inline void
+sisfb_set_attr_reg(struct sisfb_info * sisfb, u8 index, u8 data)
+{
+	u16 port = sisfb->vga_io_base;
+	volatile u8 dummy;
+
+	/* Read port 0x3DA, to set the Adderss flip-flop */
+	dummy = sisfb_get_gen_reg(sisfb, 0x3DA);
+	outb(index, port + ATTR_WRITE);
+	outb(data, port + ATTR_WRITE);	
+}
+
+static inline u8
+sisfb_get_attr_reg(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+	volatile u8 dummy;
+
+	/* Read port 0x3DA, to set the Adderss flip-flop */	
+	dummy = sisfb_get_gen_reg(sisfb, 0x3DA);
+	outb(index, port + ATTR_READ);
+	return inb(port + ATTR_READ);	
+}
+
+/**
+ *	sisfb_set_dac_index: - Select DAC color register to be loaded
+ *	@sisfb: SiS Frame Buffer structure
+ *	@index: Index of the DAC color Register to be loaded
+ *
+ *	Select the DAC color register to be loaded by programming the
+ *	DAC Write Address Register.
+ */
+static inline void
+sisfb_set_dac_index(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + DACW_ADDR);
+}	
+
+/**
+ *	sisfb_set_dac_rgb: - Load the DAC color register
+ *	@sisfb: SiS Frame Buffer structure
+ *	@red: Red component
+ *	@green: Green component
+ *	@blue: Blue compoenet
+ *
+ *	Load the DAC color register with (@red, @green, @blue) by writing to the DAC Data
+ *	Register. The color register to be loaded is implicitely selected by the DAC Write
+ *	Address Register.
+ */
+static inline void
+sisfb_set_dac_rgb(struct sisfb_info * sisfb, u8 red, u8 green, u8 blue)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(red,   port + DAC_DATA);
+	outb(green, port + DAC_DATA);
+	outb(blue,  port + DAC_DATA);
+}		
+
+/**
+ *	sisfb_lock_regs: - Lock the CRTC Registers 0-7 and Extended Sequencer Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Lock CRTC 0-7 by setting Bit 7 of CRTC 0x11.
+ *	Lock Extended Registers by writing 0x21 (%SIS_PASSWD_LOCK) to
+ *	SR 0x05 (%SIS_PASSWD)
+ */
+static inline void
+sisfb_lock_regs(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	/* Set Bit 7 to enable Write Protect for CR0 to CR7 */
+	data = sisfb_get_crtc_reg(sisfb, 0x11);
+	data = data | 0x80;
+	sisfb_set_crtc_reg(sisfb, 0x11, data);
+
+	/* lock the access to Extended Registers SR5-SR3C and/or CR30-CR37 ?? */
+	sisfb_set_seq_reg(sisfb, SIS_PASSWD, SIS_PASSWD_LOCK);
+}
+
+/**
+ *	sisfb_unlock_regs: - Unlock the CRTC Registers 0-7 and Extended Sequencer Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Unlock CRTC 0-7 by clearing Bit 7 of CRTC 0x11.
+ *	Unlock Extended Registers by writing 0x86 (%SIS_PASSWD_UNLOCK) to
+ *	SR 0x05 (%SIS_PASSWD)
+ */
+static inline void
+sisfb_unlock_regs(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	/* clear Bit 7 to disable Write Protect for CR0 to CR7 */
+	data = sisfb_get_crtc_reg(sisfb, 0x11);
+	data = data & 0x7f;
+	sisfb_set_crtc_reg(sisfb, 0x11, data);
+
+	/* unlock the access to Extended Registers SR5-SR3C and/or CR30-CR37 ?? */
+	sisfb_set_seq_reg(sisfb, SIS_PASSWD, SIS_PASSWD_UNLOCK);
+}
+
+/**
+ *	sisfb_display_on: - Turn the monitor on.
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Turn on the monitor by clearing Bit 5 of Seqencer Register 0x01
+ */
+static inline void
+sisfb_display_on(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	data = sisfb_get_seq_reg(sisfb, 0x01);
+
+	/* clear SR1 Bit 5: Screen Off ==> Screen On */
+	data &= ~0x20;
+	sisfb_set_seq_reg(sisfb, 0x01, data);
+}
+
+/**
+ *	sisfb_display_off: - Turn the monitor off.
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Turn off the monitor by settng Bit 5 of Seqencer Register 0x01
+ */
+static inline void
+sisfb_display_off(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	data = sisfb_get_seq_reg(sisfb, 0x01);
+
+    	/* set SR1 Bit5: Screen Off */
+	data |= 0x20;
+	sisfb_set_seq_reg(sisfb, 0x01, data);
+}
+
+static inline u32
+sisfb_get_screen_width(struct sisfb_info * sisfb)
+{
+	u8 sr_b, cr_1;
+
+	sr_b = sisfb_get_seq_reg(sisfb, 0x0B) & 0x0c;
+	cr_1 = sisfb_get_crtc_reg(sisfb, 0x01);
+
+	return ((((sr_b << 6) | cr_1) & 0x3ff) + 1) << 3;
+}
+
+static inline u32
+sisfb_get_screen_height(struct sisfb_info * sisfb)
+{
+	u8 sr_a, cr_7, cr_12;
+
+	sr_a = sisfb_get_seq_reg(sisfb, 0x0A) & 0x02;
+	cr_7 = sisfb_get_crtc_reg(sisfb, 0x07);
+	cr_12 = sisfb_get_crtc_reg(sisfb, 0x12);
+
+	return ((((sr_a << 9) | ((cr_7 & 0x40) << 3) |
+		  ((cr_7 & 0x02) << 7) | cr_12) & 0x7ff) + 1);
+}
+
+extern void sisfb_init_legacy_vga(struct sisfb_info * sisfb);
+
+#endif /* __SISFB_LEGACY_VGA__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_lite.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_lite.c
--- linux-2.4.21/drivers/video/sis/sisfb_lite.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_lite.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,1043 @@
+/* sisfb_lite.c: SiSFB Lite, Frame Buffer Device Driver for SiS 540/630/730 requires no VGA BIOS
+ *
+ * Copyright 2000 Ollie Lho <ollie@sis.com.tw>
+ *
+ * This driver is derived form an eraly version of sisfb.c which is:
+ * 	This driver is partly based on the VBE 2.0 compliant graphic 
+ * 	boards framebuffer driver, which is 
+ * 
+ * 	(c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ * Reference:
+ *	1. SiS 6326 AGP/PCI Graphics & Video Acclerator. Rev 1.0, May 12, 1997
+ *	2. Programmer's Guide to the EGA, VGA, and Super VGA Card. Third Edition,
+ *	   Richard F. Ferraro, Addison-Welsey, Aug. 1994
+ *	3. Glamour Design Guideline V0.8
+ *	4. Graphics Hardware by Geert Uytterhoeven <geert@linux-m86k.org>
+ *	5. sis86c201.c in XFree86 3.3.6
+ *
+ * ToDo:
+ *	0. make sure that this file contains only /dev/fb API code
+ */
+
+/* make checkconfig does not check included files... */
+#include <linux/config.h>
+#include "sisfb_lite.h"
+
+#define PCI_DEVICE_ID_SI_550_VGA 0x5315
+
+static struct pci_device_id sisfb_pci_tbl [] __devinitdata = {
+#ifdef CONFIG_FB_SIS_300
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SISFB_LITE_300},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SISFB_LITE_300},
+#endif /* CONFIG_FB_SIS_300 */
+#ifdef CONFIG_FB_SIS_315
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, SISFB_LITE_315},
+#endif /* CONFIG_FB_SIS_300 */
+	{0,}
+};
+MODULE_DEVICE_TABLE (pci, sisfb_pci_tbl);
+
+static char fontname[40] __initdata;
+static const char * mode_option __initdata;
+
+static struct fb_var_screeninfo default_var __initdata = {
+	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+	xres:		640,
+	yres:		480,
+	xres_virtual:	640,
+	yres_virtual:	480,
+	xoffset:	0,
+	yoffset:	0,
+	bits_per_pixel:	8,
+	grayscale:	0,
+	red:		{0, 8, 0},
+	green:		{0, 8, 0},
+	blue:		{0, 8, 0},
+	transp:		{0, 0, 0},
+	nonstd:		0,
+	activate:	FB_ACTIVATE_NOW,
+	height:		-1,
+	width:		-1,
+	accel_flags:	0,
+
+	/* timming, virtually the same as sisfb_default_mode */
+	pixclock:	39722,
+	left_margin:	48,
+	right_margin:	16,
+	upper_margin:	33,
+	lower_margin:	10,
+	hsync_len:	96,
+	vsync_len:	2,
+	sync:		0,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+static struct fb_videomode sisfb_default_mode __initdata = {
+	name:	        "640x480-8@60",
+	refresh:	60,
+	xres:		640,
+	yres:		480,
+	pixclock:	39722,
+	left_margin:	48,
+	right_margin:	16,
+	upper_margin:	33,
+	lower_margin:	10,
+	hsync_len:	96,
+	vsync_len:	2,
+	sync:		0,
+	vmode:		FB_VMODE_NONINTERLACED
+};
+
+static int inverse;
+
+unsigned long mclk = 100000, eclk = 100000;
+
+extern int sisfb_init_300(struct sisfb_info * sisfb);
+extern int sisfb_init_315(struct sisfb_info * sisfb);
+
+/* Interface used by the world */
+int sisfb_setup(char *options);
+int sisfb_init(void);
+
+/* Internal routines */
+static void do_install_cmap(struct display * disp, struct fb_info *info);
+/* ---------------------------------------------------------------------------------- */
+static int sisfb_encode_fix(struct fb_fix_screeninfo * fix, struct sisfb_par * par,
+			    struct sisfb_info * sisfb);
+static int sisfb_decode_var(struct fb_var_screeninfo * var, struct sisfb_par * par,
+			    const struct sisfb_info * sisfb);
+static int sisfb_encode_var(struct fb_var_screeninfo * var, const struct sisfb_par * par,
+			    const struct sisfb_info * sisfb);
+static int sisfb_getcolreg(unsigned regno, unsigned * red, unsigned * green, unsigned * blue,
+			   unsigned * transp, struct fb_info * info);
+static int sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+			   unsigned transp, struct fb_info * info);
+/* ---------------------------------------------------------------------------------- */
+static int sisfb_switch_con(int con, struct fb_info * info);
+static void sisfb_blank(int blank, struct fb_info * info);
+/* ----------------------------------------- fb_ops --------------------------------- */
+static int sisfb_get_fix(struct fb_fix_screeninfo * fix, int con, struct fb_info * info);
+static int sisfb_get_var(struct fb_var_screeninfo * var, int con, struct fb_info * info);
+static int sisfb_set_var(struct fb_var_screeninfo * var, int con, struct fb_info * info);
+static int sisfb_get_cmap(struct fb_cmap * cmap, int kspc, int con, struct fb_info * info);
+static int sisfb_set_cmap(struct fb_cmap * cmap, int kspc, int con, struct fb_info * info);
+static int sisfb_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
+		       unsigned long arg, int con, struct fb_info * info);
+
+
+/**
+ *	do_install_cmap: - Install colormap
+ *	@disp: Display structure of current console
+ *	@info: Frame Buffer structure
+ *
+ *	Install colormap for the current console. This function is called every
+ *	time the display mode is changed (by set_var or switch_con).
+ */
+static void
+do_install_cmap(struct display * disp, struct fb_info *info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+
+	if (disp->cmap.len)
+		fb_set_cmap(&disp->cmap, 1, sisfb_setcolreg, info);
+	else {
+		fb_set_cmap(fb_default_cmap(sisfb->current_par.cmap_len), 1, 
+			    sisfb_setcolreg, info);
+	}
+}
+
+void
+sisfb_set_dispsw_fbcon(struct display * disp, struct sisfb_info * sisfb, int bpp, int accel)
+{
+	switch (bpp) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 15:
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = sisfb->fbcon_cmap.cfb16;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		disp->dispsw = &fbcon_cfb32;
+		disp->dispsw_data = sisfb->fbcon_cmap.cfb32;
+		break;
+#endif
+
+	default:
+		disp->dispsw = &fbcon_dummy;
+		return;
+	}
+
+	disp->scrollmode = SCROLL_YREDRAW;
+}
+
+/**
+ *	sisfb_encode_fix: - Encode the Fixed Part of the Display
+ *	@fix: Fixed screen info (return)
+ *	@con: Console number
+ *	@info: Frame Buffer structure
+ *
+ *	Return the fixed part of the display information in @fix. The struct of @fix is
+ *	defined in linux/fb.h.
+ */
+static int
+sisfb_encode_fix(struct fb_fix_screeninfo * fix, struct sisfb_par * par, struct sisfb_info * sisfb)
+{
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+	strcpy(fix->id, "SiSFB Lite");
+
+	fix->smem_start = sisfb->video_base_phy;
+	fix->smem_len   = sisfb->video_size_virt;
+
+	fix->type     = FB_TYPE_PACKED_PIXELS;
+	fix->type_aux = 0;
+
+	if (par->bits_per_pixel == 8)
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		fix->visual = FB_VISUAL_TRUECOLOR;
+
+	fix->xpanstep    = 8;
+	fix->ypanstep    = 1;
+	fix->ywrapstep   = 0;
+
+	fix->line_length = par->line_length;
+
+	fix->mmio_start  = sisfb->mmio_base_phy;
+	fix->mmio_len    = sisfb->mmio_size_phy;
+
+	fix->accel       = FB_ACCEL_SIS_GLAMOUR;
+
+	return 0;
+}
+
+/**
+ *	sisfb_decode_var: - Convert @var to @par
+ *	@var: 
+ *	@par:
+ *	@info: Frame Buffer structure
+ *
+ *	Get the video parammeters @par from @var. If a value doesn't fit, round it up,
+ *	if it's too big, return -EINVAL.
+ *
+ *	The device's default par i.e. sisfb->default_par is converted from default_var by
+ *	this function during driver initialization. Default_var is either predefined or
+ *	provided by find_mode().
+ */
+static int 
+sisfb_decode_var(struct fb_var_screeninfo * var,
+		 struct sisfb_par * par, const struct sisfb_info * sisfb)
+{
+	if (var->bits_per_pixel != 8  && var->bits_per_pixel != 16 &&
+	    var->bits_per_pixel != 32) {
+		printk(KERN_ERR "sisfb_lite: depth not supported: %u\n",
+		       var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	/* make sure there is enough video ram for the mode */
+	if ((u32)(var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8) >
+	    sisfb->video_size_virt) {
+		printk(KERN_ERR "sisfb_lite: Not enough memory for mode\n");
+		return -EINVAL;
+	}
+
+	/* FixMe: virtual X resolution can only be 2^N for SiS530/620 */
+
+	memset(par, 0, sizeof(struct sisfb_par));
+
+	par->hdispend 	= var->xres;
+	par->xvirt	= var->xres_virtual;
+	par->hsyncstart = par->hdispend   + var->right_margin;
+	par->hsyncend 	= par->hsyncstart + var->hsync_len;
+	par->htotal   	= par->hsyncend   + var->left_margin;
+
+	par->vdispend 	= var->yres;
+	par->yvirt	= var->yres_virtual;
+	par->vsyncstart = par->vdispend   + var->lower_margin;
+	par->vsyncend 	= par->vsyncstart + var->vsync_len;
+	par->vtotal   	= par->vsyncend   + var->upper_margin;
+
+	par->dot_clock 	= 1E12 / var->pixclock;
+
+	par->bits_per_pixel = var->bits_per_pixel;
+	par->cmap_len	    = (par->bits_per_pixel == 8) ? 256 : 16;
+
+	par->line_length    = var->xres_virtual * (var->bits_per_pixel >> 3);
+
+	/* update screen_offset member of current par structure */
+	par->screen_offset = (var->yoffset * var->xres_virtual + var->xoffset) *
+		(var->bits_per_pixel >> 3);
+
+	if (var->vmode & FB_VMODE_INTERLACED)
+		par->interlace = 1;
+	else
+		par->interlace = 0;
+
+#if 0
+	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+		par->sync_mode |= SISFB_HSYNC_ACT_HIGH;
+	else
+		par->sunc_mode |= SISFB_HSYNC_ACT_LOW;
+	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+		par->sync_mode |= SISFB_VSYNC_ACT_HIGH;
+	else
+		par->sync_mode |= SISFB_VSYNC_ACT_LOW;
+#endif
+
+	return 0;
+}
+
+/**
+ *	sisfb_encode_var: - Convert @par to @var
+ *	@var: 
+ *	@par:
+ *	@info: Frame Buffer structure
+ *
+ *	Fill the @var structure based on the values in the hardware specific @par.
+ */
+static int
+sisfb_encode_var(struct fb_var_screeninfo * var, const struct sisfb_par * par,
+		 const struct sisfb_info * sisfb)
+{
+	memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+	var->xres           = par->hdispend;
+	var->yres           = par->vdispend;
+	var->xres_virtual   = par->xvirt;
+	var->yres_virtual   = par->yvirt;
+	var->right_margin   = par->hsyncstart - par->hdispend;
+	var->hsync_len      = par->hsyncend   - par->hsyncstart;
+	var->left_margin    = par->htotal     - par->hsyncend;
+	var->lower_margin   = par->vsyncstart - par->vdispend;
+	var->vsync_len      = par->vsyncend   - par->vsyncstart;
+	var->upper_margin   = par->vtotal     - par->vsyncend;
+	var->bits_per_pixel = par->bits_per_pixel;
+	var->height         = -1;
+	var->width          = -1;
+
+	switch (par->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		var->red.length     = 6;
+		var->green.length   = 6;
+		var->blue.length    = 6;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 16:		/* RGB 565 */
+		var->red.offset     = 11;
+		var->red.length     = 5;
+		var->green.offset   = 5;
+		var->green.length   = 6;
+		var->blue.offset    = 0;
+		var->blue.length    = 5;
+		var->transp.offset  = 0;
+		var->transp.length  = 0;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		var->red.offset     = 16;
+		var->red.length     = 8;
+		var->green.offset   = 8;
+		var->green.length   = 8;
+		var->blue.offset    = 0;
+		var->blue.length    = 8;
+		var->transp.offset  = 24;
+		var->transp.length  = 8;
+		break;
+#endif
+	}
+
+	var->pixclock = (u32) (1E12 / par->dot_clock);
+
+	if (par->sync_mode & 0x80)
+		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+	else
+		var->sync |= FB_SYNC_VERT_HIGH_ACT;
+
+	if (par->sync_mode & 0x40)
+		var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+	else
+		var->sync |= FB_SYNC_HOR_HIGH_ACT;
+
+	return 0;
+}
+
+/**
+ *	sisfb_getcolreg: - Read color register
+ *	@regno: Color register number
+ *	@red: Red component (return)
+ *	@green: Green component (return)
+ *	@blue: Blue component (return)
+ *	@trans: Alpha component (return)
+ *	@info: Frame Buffer structure
+ *
+ *	Return != 0 for invalid register number.
+ *
+ *	Read a single color register form the driver's color palette and split
+ *	it into colors/transparent components. sisfb_get_cmap() uses this function
+ *	to query the colormap.
+ */
+static int
+sisfb_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
+	      unsigned *transp, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct sisfb_par * par = (struct sisfb_par *) &sisfb->current_par;
+
+	if (regno >= par->cmap_len)
+		return 1;
+
+	*red    = (sisfb->palette[regno].red   << 8) | sisfb->palette[regno].red;
+	*green  = (sisfb->palette[regno].green << 8) | sisfb->palette[regno].green;
+	*blue   = (sisfb->palette[regno].blue  << 8) | sisfb->palette[regno].blue;
+	*transp = 0;
+
+	return 0;
+}
+
+/**
+ *	sisfb_getcolreg: - Set color register
+ *	@regno: Color register number
+ *	@red: Red component (return)
+ *	@green: Green component (return)
+ *	@blue: Blue component (return)
+ *	@trans: Alpha component (return)
+ *	@info: Frame Buffer structure
+ *
+ *	Return != 0 for invalid register number.
+ *
+ *	Set a single color register to the driver's color palette (HW for 256 color
+ *	mode, SW otherwise) according to colors/transparent components supplied.
+ *	The values supplied are already rounded down to the hardware's capabilities
+ *	(according to the entries in the var structure)
+ *	 
+ *	sisfb_set_cmap() uses this function to set the colormap.
+ */
+static int
+sisfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
+	      unsigned transp, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct sisfb_par * par = (struct sisfb_par *) &sisfb->current_par;
+
+	if (regno >= par->cmap_len)
+		return 1;
+
+	red   >>= 8;
+	green >>= 8;
+	blue  >>= 8;
+
+	sisfb->palette[regno].red   = red;
+	sisfb->palette[regno].green = green;
+	sisfb->palette[regno].blue  = blue;
+
+	switch (par->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		sisfb_set_dac_index(sisfb, regno);
+		sisfb_set_dac_rgb(sisfb, red >> 2, green >> 2, blue >> 2);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 15:
+	case 16:
+		sisfb->fbcon_cmap.cfb16[regno] =
+		    ((red   & 0xF8) << 8) |
+		    ((green & 0xFC) << 3) |
+		    ((blue  & 0xF8) >> 3);
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		sisfb->fbcon_cmap.cfb32[regno] = (red << 16) | (green << 8) | (blue);
+		break;
+#endif
+	}
+
+	return 0;
+}
+
+/*
+ *    Switch Console (called by fbcon.c)
+ */
+static int
+sisfb_switch_con(int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct sisfb_par par;
+
+	/* unlock VGA registers, XFree86 3.3.6 leave the registers locked
+	 * during console switch */
+	sisfb_unlock_regs(sisfb);
+
+	/* backup colormap of current console */
+	if (fb_display[sisfb->currcon].cmap.len)
+		fb_get_cmap(&fb_display[sisfb->currcon].cmap,
+			    1, sisfb_getcolreg, info);
+
+	/* same mode, needn't change mode actually */
+	if (!memcmp(&fb_display[con].var, &fb_display[sisfb->currcon].var,
+		    sizeof(struct fb_var_screeninfo))) {
+		sisfb->currcon = con;
+		return 1;
+	}
+
+	sisfb->currcon = con;
+
+	/* convert var to par and set the hardware by set_par */
+	sisfb_decode_var(&fb_display[con].var, &par, sisfb);
+	sisfb->set_par(&par, sisfb);
+
+	/* set display switch for current bits_per_pixel */
+	sisfb->set_disp(&fb_display[con], sisfb, fb_display[con].var.bits_per_pixel, 0);
+
+	/* Install new colormap for current console */
+	do_install_cmap(&fb_display[con], info);
+
+	return 1;
+}
+
+static int
+sisfb_updatevar(int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+
+	if (con == sisfb->currcon)
+		sisfb->pan_display(&fb_display[con].var, sisfb);
+
+	return 0;
+}
+
+/**
+ *	sisfb_blank: -  Blanking or Unblanking the CRT
+ *	@blank: 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off
+ *	@info: Frame Buffer structure
+ *
+ *	The documents on bit 6..7 of SR11 and SR1F are ambigiuos. They are either marked as
+ *	"reserved" or conflicts with each other from different sources. It is possible that
+ *	all these bits are "wired" altogether in the actual circuit implementation (HW bug ??).
+ *	And the VGA guys just choose one to document/program on their own will.
+ *
+ *	In SiS 315 documentation, SR1F is the power management register.
+ */
+static void
+sisfb_blank(int blank, struct fb_info * info)
+{
+	u8 display, power, retrace;
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+
+	display = sisfb_get_seq_reg(sisfb, 0x01);
+	power   = sisfb_get_seq_reg(sisfb, 0x1F);
+	retrace = sisfb_get_crtc_reg(sisfb, 0x17);
+
+	/* Turn the display off */
+	display |= 0x20;
+
+	switch (blank) {
+	case 0:
+		/* Turn the display on */
+		display &= ~0x20;
+		/* Disable DPMS mode */
+		power   &= ~0xC0;
+		/* Enable horizontal and vertical retrace signals */
+		retrace |= 0x80;
+		break;
+	case 1:
+		break;
+	case 2:
+		/* Enter DPMS Suspend Mode -> no vsync */
+		power   |= 0x80;
+		break;
+	case 3:
+		/* Enter DPMS standby Mode -> no hsync */
+		power   |= 0x40;
+		break;
+	case 4:
+	default:
+		/* Enter DPMS Power Off Mode -> no hsync,vsync */
+		power   |= 0xC0;
+		/* Disable horizontal and vertical retrace signals */
+		retrace &= ~0x80;
+		break;
+	}
+
+	sisfb_set_seq_reg(sisfb, 0x01, display);
+	sisfb_set_seq_reg(sisfb, 0x1F, power);
+	sisfb_set_crtc_reg(sisfb, 0x17, retrace);
+}
+
+/**
+ *	sisfb_get_fix: - Get the Fixed Part of the Display
+ *	@fix: Fixed screen info (return)
+ *	@con: Console number
+ *	@info: Frame Buffer structure
+ *
+ *	Return the fixed part of the display information in @fix. The struct of @fix is
+ *	defined in linux/fb.h.
+ *
+ *	This function calls sisfb_encode_fix() to encode @fix from current 'var' or 'par'
+ */
+static int
+sisfb_get_fix(struct fb_fix_screeninfo * fix, int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct sisfb_par par;
+
+	if (con == -1)
+		par = sisfb->default_par;
+	else
+		sisfb_decode_var(&fb_display[con].var, &par, sisfb);
+
+	sisfb_encode_fix(fix, &par, sisfb);
+
+	return 0;
+}
+
+/**
+ *	sisfb_get_var: - Convert @var to @par
+ *	@var: 
+ *	@par:
+ *	@info: Frame Buffer structure
+ *
+ *	Get the video params out of 'var'. If a value doesn't fit, round it up,
+ *	if it's too big, return -EINVAL.
+ *
+ *	The driver's default par i.e. sisfb->default_par is convert from default_var
+ *	during initialization. Default_var is either predefined or provided by find_mode().
+ */
+static int
+sisfb_get_var(struct fb_var_screeninfo * var, int con, struct fb_info * info)
+{
+	const struct sisfb_info * sisfb = (struct sisfb_info *) info;
+
+	if (con == -1)
+		/* initialization, get the var from default_par */
+		sisfb_encode_var(var, &sisfb->default_par, sisfb);
+	else
+		*var = fb_display[con].var;
+	return 0;
+}
+
+/*
+ *    Set the User Defined Part of the Display
+ */
+static int sisfb_set_var(struct fb_var_screeninfo * var, int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct sisfb_par par;
+	struct display * display;
+	int err, oldbpp;
+
+	if (con == -1)
+		display = &sisfb->disp;
+	else
+		display = &fb_display[con];
+
+	/* try to convert var to HW register values (par) */
+	if ((err = sisfb_decode_var(var, &par, sisfb)))
+		/* HW does not support this display mode */
+		return err;
+
+	/* return current mode to user */
+	sisfb_encode_var(var, &par, sisfb);
+
+	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+		return 0;
+
+	oldbpp = display->var.bits_per_pixel;
+
+	if (display->var.xres != var->xres ||
+	    display->var.yres != var->yres ||
+	    display->var.xres_virtual != var->xres_virtual ||
+	    display->var.yres_virtual != var->yres_virtual ||
+	    display->var.bits_per_pixel != var->bits_per_pixel ||
+	    display->var.accel_flags != var->accel_flags) {
+		struct fb_fix_screeninfo fix;
+
+		sisfb_encode_fix(&fix, &par, sisfb);
+
+		display->screen_base = (char *) sisfb->video_base_virt;
+		display->visual = fix.visual;
+		display->type = fix.type;
+		display->type_aux = fix.type_aux;
+		display->ypanstep = fix.ypanstep;
+		display->ywrapstep = fix.ywrapstep;
+		display->line_length = fix.line_length;
+		display->next_line = fix.line_length;
+		display->can_soft_blank = 1;
+		display->inverse = inverse;
+		display->var = *var;
+
+		sisfb->set_disp(display, sisfb, var->bits_per_pixel, 0);
+
+		if (info->changevar)
+			(*info->changevar) (con);
+	}
+
+	/* call sisfb_set_par if the console is visible (foreground) console
+	   or during initialization */
+	if (!sisfb->info.display_fg || sisfb->info.display_fg->vc_num == con || con < 0)
+		sisfb->set_par(&par, sisfb);
+
+	/* clear OnScreen */
+	memset((unsigned char *) sisfb->video_base_virt + par.screen_offset, 0,
+	       par.line_length * var->yres);
+
+	/* if we have changed the color depth, install new colormap
+	   FixME: We only alloc_cmap but never free one ?? */
+	if (oldbpp != var->bits_per_pixel || con < 0) {
+		if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+			return err;
+		do_install_cmap(display, info);
+	}
+
+	return 0;
+}
+
+/**
+ *	sisfb_get_cmap: - Get the Colormap
+ *	@cmap: Colormap to be get (return)
+ *	@kspc:
+ *	@con: Console number
+ *	@info: Frame Buffer structure
+ *
+ *	Get the colormap of console @con to @cmap. If the @con is the current console,
+ *	get the colormap from the hardware registers otherwise we return the private
+ *	colormap of the console. If the console does not have a private colormap we
+ *	return the "default colormap".
+ */
+static int
+sisfb_get_cmap(struct fb_cmap * cmap, int kspc, int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct display *disp;  
+
+	if (con == -1)
+		disp = &sisfb->disp;
+	else
+		disp = &fb_display[con];
+
+	if (con == sisfb->currcon)
+		/* current console, use getcolreg to get the HW colormap */
+		return fb_get_cmap(cmap, kspc, sisfb_getcolreg, info);
+	else if (fb_display[con].cmap.len)
+		/* non default colormap? */
+		fb_copy_cmap(&disp->cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap(fb_default_cmap(sisfb->current_par.cmap_len), cmap,
+			     kspc ? 0 : 2);
+
+	return 0;
+}
+
+/**
+ *	sisfb_set_cmap: - Set the Colormap
+ *	@cmap: Colormap to be set
+ *	@kspc:
+ *	@con: Console number
+ *	@info: Frame Buffer structure
+ *
+ *	Set the colormap of console @con to @cmap. If the colormap of console @con is
+ *	not allocated yet, allocate it. If the @con is the current console, really set
+ *	the hardware registers otherwise only set to the private colormap "in memory".
+ */
+static int
+sisfb_set_cmap(struct fb_cmap * cmap, int kspc, int con, struct fb_info * info)
+{
+	int err = 0;
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct display *disp;  
+
+	if (con == -1)
+		disp = &sisfb->disp;
+	else
+		disp = &fb_display[con];
+
+	if (disp->cmap.len == 0) {
+		/* no colormap allocated, allocate it */
+		err = fb_alloc_cmap(&disp->cmap, sisfb->current_par.cmap_len, 0);
+		if (err)
+			return err;
+	}
+
+	if (con == sisfb->currcon)
+		/* current console, use setcolreg to set the HW colormap */
+		err = fb_set_cmap(cmap, kspc, sisfb_setcolreg, info);
+	else
+		/* not current console, don't touch the HW, make a copy instead */
+		fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
+
+	return err;
+}
+
+/*
+ *  Pan or Wrap the Display
+ *
+ *  This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+static int
+sisfb_pan_display(struct fb_var_screeninfo * var, int con, struct fb_info * info)
+{
+	struct sisfb_info * sisfb = (struct sisfb_info *) info;
+	struct display *disp;
+
+	if (con == -1)
+		disp = &sisfb->disp;
+	else
+		disp = &fb_display[con];
+
+	if (var->xoffset > (var->xres_virtual - var->xres))
+		return -EINVAL;
+	if (var->yoffset > (var->yres_virtual - var->yres))
+		return -EINVAL;
+
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0 ||
+		    var->yoffset >= disp->var.yres_virtual ||
+		    var->xoffset)
+			return -EINVAL;
+	} else {
+		if (var->xoffset + disp->var.xres > disp->var.xres_virtual ||
+		    var->yoffset + disp->var.yres > disp->var.yres_virtual)
+			return -EINVAL;
+	}
+
+	if (con == sisfb->currcon)
+		sisfb->pan_display(var, sisfb);
+
+	/* update xoffset, yoffset and vmode members of var structure for current
+	 * console this is neceressary since this function is called by a seperate
+	 * ioctl function than set_var (actually, set_var doesn't care about these
+	 * members at all) */
+	disp->var.xoffset = var->xoffset;
+	disp->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		disp->var.vmode |= FB_VMODE_YWRAP;
+	else
+		disp->var.vmode &= ~FB_VMODE_YWRAP;
+
+	return 0;
+}
+
+static int sisfb_ioctl(struct inode * inode, struct file * file, unsigned int cmd,
+		       unsigned long arg, int con, struct fb_info * info)
+{
+	return 0;
+}
+
+static struct fb_ops sisfb_ops = {
+	owner:		THIS_MODULE,
+	fb_get_fix:	sisfb_get_fix,
+	fb_get_var:	sisfb_get_var,
+	fb_set_var:	sisfb_set_var,
+	fb_get_cmap:	sisfb_get_cmap,
+	fb_set_cmap:	sisfb_set_cmap,
+	fb_pan_display:	sisfb_pan_display,
+	fb_ioctl:	sisfb_ioctl,
+};
+
+int sisfb_setup(char * options)
+{
+	char *this_opt;
+
+	if (!options || !*options)
+		return 0;
+
+	for (this_opt = strtok(options, ","); this_opt; 
+	     this_opt = strtok(NULL, ",")) {
+		if (!*this_opt)
+			continue;
+
+		if (!strcmp(this_opt, "inverse")) {
+			inverse = 1;
+			fb_invert_cmaps();
+		} else if (!strncmp(this_opt, "font:", 5)) {
+			strncpy(fontname, this_opt + 5, 40);
+		} else {
+			mode_option = this_opt;
+		}
+	}
+	return 0;
+}
+
+static int __devinit
+sisfb_probe(struct pci_dev * pci_dev, const struct pci_device_id * pci_id)
+{
+	struct sisfb_info * sisfb;
+	struct fb_var_screeninfo var;
+
+	if (pci_enable_device(pci_dev))
+		return -ENODEV;
+
+	if ((sisfb = kmalloc(sizeof(struct sisfb_info), GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+	memset(sisfb, 0, sizeof(struct sisfb_info));
+
+	sisfb->pci_dev = pci_dev;
+
+	sisfb->video_base_phy = pci_resource_start(pci_dev, 0);
+	sisfb->video_size_phy = pci_resource_len(pci_dev, 0);
+	if (!request_mem_region(sisfb->video_base_phy, sisfb->video_size_phy, "sisfb FB")) {
+		printk(KERN_ERR "sisfb_lite: cannot reserve frame buffer memory\n");
+		return -ENODEV;
+	}
+
+	sisfb->mmio_base_phy = pci_resource_start(pci_dev, 1);
+	sisfb->mmio_size_phy = pci_resource_len(pci_dev, 1);
+	if (!request_mem_region(sisfb->mmio_base_phy, sisfb->mmio_size_phy, "sisfb MMIO")) {
+		printk(KERN_ERR "sisfb_lite: cannot reserve MMIO region\n");
+		release_mem_region(sisfb->video_base_phy, sisfb->video_size_phy);
+		return -ENODEV;
+	}
+
+	sisfb->vga_io_base = pci_resource_start(pci_dev, 2);
+	sisfb->vga_io_size = pci_resource_len(pci_dev, 2);
+	if (!request_region(sisfb->vga_io_base, sisfb->vga_io_size, "sisfb IO")) {
+		printk(KERN_ERR "sisfb_lite: cannot reserve I/O ports\n");
+		release_mem_region(sisfb->video_base_phy, sisfb->video_size_phy);
+		release_mem_region(sisfb->mmio_base_phy, sisfb->mmio_size_phy);
+		return -ENODEV;
+	}
+
+	sisfb_unlock_regs(sisfb);
+
+	switch (pci_id->driver_data) {
+#ifdef CONFIG_FB_SIS_300
+	case SISFB_LITE_300:
+		sisfb_init_300(sisfb);
+		break;
+#endif /* CONFIG_FB_SIS_300 */
+#ifdef CONFIG_FB_SIS_315
+	case SISFB_LITE_315:
+	        sisfb_init_315(sisfb);
+		break;
+#endif /* CONFIG_FB_SIS_530 */
+	case SISFB_LITE_530:
+	default:
+		printk(KERN_ERR "UnSupupported SiS VGA Core\n");
+		goto failed;
+	}
+
+	strcpy(sisfb->info.modename, "SiSFB Lite");
+
+	sisfb->info.changevar  = NULL;
+	sisfb->info.node       = -1;
+	sisfb->info.fbops      = &sisfb_ops;
+	sisfb->info.disp       = &sisfb->disp;
+	strcpy(sisfb->info.fontname, fontname);
+	sisfb->info.switch_con = &sisfb_switch_con;
+	sisfb->info.updatevar  = &sisfb_updatevar;
+	sisfb->info.blank      = &sisfb_blank;
+	sisfb->info.flags      = FBINFO_FLAG_DEFAULT;
+
+	sisfb->currcon = -1;
+
+	memset(&var, 0, sizeof(var));
+        if (fb_find_mode(&var, &sisfb->info, mode_option, NULL, 0, &sisfb_default_mode, 8) == 0)
+		var = default_var;
+
+	/* get the default_par and make it as our current_par */
+	sisfb_decode_var(&var, &sisfb->default_par, sisfb);
+	sisfb->current_par = sisfb->default_par;
+	sisfb->disp.var = var;
+
+	sisfb->currcon = 0;
+
+	if (register_framebuffer((struct fb_info *) sisfb) < 0) {
+		goto failed;
+	}
+
+	/* make sisfb a driver_data of the PCI device */
+	pci_set_drvdata(pci_dev, sisfb);
+
+	return 0;
+
+ failed:
+	/* clean things up when failed to register frame buffer */
+	pci_dev->driver_data = NULL;
+	release_mem_region(sisfb->video_base_phy, sisfb->video_size_phy);
+	release_mem_region(sisfb->mmio_base_phy, sisfb->mmio_size_phy);
+	release_region(sisfb->vga_io_base, sisfb->vga_io_size);
+
+	iounmap(sisfb->video_base_virt);
+	iounmap(sisfb->mmio_base_virt);
+
+#ifdef CONFIG_MTRR
+	mtrr_del(sisfb->mtrr, sisfb->video_base_phy, sisfb->video_size_virt);
+#endif /* CONFIG_MTRR */
+
+	kfree(sisfb);
+	return -EINVAL;
+}
+
+static void __devexit
+sisfb_remove(struct pci_dev * pci_dev)
+{
+	struct sisfb_info * sisfb = pci_get_drvdata(pci_dev);
+
+	unregister_framebuffer((struct fb_info *) sisfb);
+
+	release_mem_region(sisfb->video_base_phy, sisfb->video_size_phy);
+	release_mem_region(sisfb->mmio_base_phy, sisfb->mmio_size_phy);
+	release_region(sisfb->vga_io_base, sisfb->vga_io_size);
+
+	iounmap(sisfb->video_base_virt);
+	iounmap(sisfb->mmio_base_virt);
+
+#ifdef CONFIG_MTRR
+	mtrr_del(sisfb->mtrr, sisfb->video_base_phy, sisfb->video_size_virt);
+#endif /* CONFIG_MTRR */
+
+	kfree(sisfb);
+	pci_set_drvdata(pci_dev, NULL);
+}
+
+#define SISFB_MODULE_NAME "sisfb_lite"
+
+static struct pci_driver sisfb_pci_driver = {
+	name:		SISFB_MODULE_NAME,
+	id_table:	sisfb_pci_tbl,
+	probe:		sisfb_probe,
+	remove:		sisfb_remove,
+};
+
+static const char * version = "$Id: linux-2.4.19-sis.patch,v 1.1 2002/09/03 02:56:32 ollie Exp $";
+
+int __init sisfb_init(void)
+{
+	printk(KERN_INFO "sisfb_lite: %s\n", version);
+
+	return pci_module_init(&sisfb_pci_driver);
+}
+
+static void __exit sisfb_cleanup(void)
+{
+	pci_unregister_driver(&sisfb_pci_driver);
+}
+
+#ifdef MODULE
+module_init(sisfb_init);
+#endif /* MODULE */
+
+module_exit(sisfb_cleanup);
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_lite.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_lite.h
--- linux-2.4.21/drivers/video/sis/sisfb_lite.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_lite.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,214 @@
+#ifndef __SISFB_LITE__
+#define __SISFB_LITE__
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
+
+enum sisfb_core_generation {
+	SISFB_LITE_530, SISFB_LITE_300, SISFB_LITE_315
+};
+
+#define NR_PALETTE	256
+
+struct sisfb_par {
+	unsigned htotal;
+	unsigned xvirt;
+	unsigned hdispend;
+	unsigned hsyncstart;
+	unsigned hsyncend;
+	unsigned hblankstart;
+	unsigned hblankend;
+
+	unsigned vtotal;
+	unsigned yvirt;
+	unsigned vdispend;
+	unsigned vsyncstart;
+	unsigned vsyncend;
+	unsigned vblankstart;
+	unsigned vblankend;
+
+	/* Video Dot Clock frequence in HZ */
+	unsigned long dot_clock;
+	unsigned fifo_threshold;
+
+	unsigned bits_per_pixel;
+	unsigned cmap_len;
+
+	/* line length, in units of byte = xres_vitrual * bytes_per_pixel */
+	unsigned line_length;
+	/* screen start offset for virtual screen, in units of byte */
+	unsigned screen_offset;
+
+	unsigned interlace;
+
+	unsigned sync_mode;
+};
+
+struct sisfb_info {
+	struct fb_info info;
+	struct pci_dev *pci_dev;
+
+	unsigned long video_size_phy;
+	unsigned long video_base_phy;
+	unsigned long video_size_virt;
+	void * video_base_virt;
+
+	unsigned long mmio_size_phy;
+	unsigned long mmio_base_phy;
+	void * mmio_base_virt;
+
+	unsigned vga_io_base;
+	unsigned vga_io_size;
+
+	/* mtrr register number for Write Combine video memory */
+	unsigned mtrr;
+
+	/* default par, used during driver init */
+	struct sisfb_par default_par;
+	/* current par, changed with switch_con, set_var, pan_display */
+	struct sisfb_par current_par;
+
+	/* default display, used during driver init e.g. fb_info->disp */
+	struct display disp;
+	/* current console number, used for vt switch */
+	unsigned currcon;
+
+	struct {
+		u8 blue, green, red, pad;
+	} palette[NR_PALETTE];
+
+	/* These ifdefs must be last! They differ for module & non-module compiles */
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+	union {
+#ifdef FBCON_HAS_CFB16
+		u16 cfb16[16];
+#endif /* FBCON_HAS_CFB16 */
+#ifdef FBCON_HAS_CFB32
+		u32 cfb32[16];
+#endif /* FBCON_HAS_CFB32 */
+	} fbcon_cmap;
+#endif /* defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32) */
+
+	struct sisfb_accelerator * accelerator;
+
+	void (*set_par)(struct sisfb_par *par, struct sisfb_info * sisfb);
+	int (*pan_display)(struct fb_var_screeninfo *var, struct sisfb_info *sisfb);
+	void (*set_disp)(struct display *disp, struct sisfb_info *sisfb, int bpp, int accel);
+};
+
+/* The Programmable Clock Generator:
+ *
+ * The programmable clock generator is based on Phase Lock Loop (PLL) technology
+ * which requires only one external clock source to generate clock signals with
+ * various frequences. Conceptially, the PLL is just like an OP Amp and is consisted
+ * of a Phase Detector, a Voltage Controlled Oscillator and some frequence dividers.
+ * The clock source Fref is feed to the frequence divider /DeNumerator, then passed
+ * to the Phase Detector (PD). The output of the Phase Detector is used to drive the
+ * Voltage Controlled Oscillator (VCO). The clock signal output of the VCO, called Fvco,
+ * is then feedback to the Pahse Detector after divided by /Divider and /Numerator.
+ * When the PLL is in a stationary state, the 2 inputs of the Phase Detector is the
+ * same. Thus we have equation (1).
+ *
+ * The VCO can only generate a certain range of Fvco, for most case 135 MHz < Fvco < 250 MHz.
+ * If we would like to generate clock frequence Fout that is lower then the lower
+ * bound of Fvco, another frequnce divider called Post Scalar is needed. Then we
+ * have equation (2). By solving equatiuon (1) and (2) we can find the relationship
+ * between clock source Fref and generated clock Fout as in equation (3).
+ *
+ * Note:
+ * 1. From dumping the VGA BIOS data, it seems that the VCO in SiS 630 can generate
+ * frequence in the range of 90 MHZ - 400 MHz. But for the sake of safety, we just
+ * assume that 150 MHz < Fvco < 300 MHz in this implementation.
+ *
+ * 2. The /Divider is in Bit 7 of clock generator I, /Numerator is in Bit 0..6 of
+ * clock generator I and /DeNumerator is in Bit 0..4 of clock generator II. Their
+ * actual values are the values stored in the corresponding register plus 1.
+ *
+ * 3. The /Post Scalar is in Bit 5..7 of clock generator II. The actual meaning of
+ * the values in the register is not clear from the document. We assume that:
+ *	000 => 1,	001 => 2,	010 => 3,	011 => 4
+ *	110 => 6,	111 => 8, others are reserved.
+ *
+ * 4. The document (6326 Spec and Glamour Design Guideline) only states the VCO Gain,
+ * Bit 7 of clock generator register III should be set for "high frequence operation"
+ * but without specifying the definition of "high frequence". From XFree86 3.3.6,
+ * sisfb.c and BIOS dumping, they are always set.
+ *
+ *                                      -------------- 
+ *                               -------| /Numerator |<------
+ *                               |      --------------      |
+ *                               |                     ------------
+ *                               |                     | /Divider |
+ *                               |                     ------------
+ *                               |                          |
+ *            ----------------   V    ------      -------   |    ----------------
+ * Fref ----> | /DeNumerator |---+--->| CP |----->| VCO |------->| /Post Scalar | ----> Fout
+ *            ----------------  PD    ------      -------  Fvco  ----------------
+ *                                                   ^
+ *                                                   |
+ *                                                  Gain
+ *
+ * For
+ *          Fref              Fvco                                 Fvco
+ *       ----------- = -------------------  (1)   and    Fout = -----------  (2) 
+ *       DeNumerator   Divider * Numerator                      Post Scalar
+ *
+ * We have
+ *                 Divider * Numerator
+ *       Fout = ------------------------- Fref (14.318 MHz)  (3)
+ *              Denumerator * Post Scalar
+ *
+ * Reference:
+ *	1. SiS 6326 AGP/PCI Graphics & Video Acclerator. Rev 1.0, May 12, 1997
+ *	2. Graphics Hardware by Geert Uytterhoeven <geert@linux-m86k.org>
+ *	3. sis86c201.c in XFree86 3.3.6
+ *	4. Glamour Design Guideline V0.8
+ */
+
+/* Clock generator source, 14.318 MHz */
+#define CLOCK_SOURCE 14318
+/* Minimium Fvco 150 MHz */
+#define MIN_F_VCO 150000
+/* Maximium Fvco 300 MHz */
+#define MAX_F_VCO 300000
+
+struct sisfb_clock_param {
+	/* parameters for setting clock generator for SiS VGA core */
+	u8 divider;
+	u8 numerator;
+	u8 denumerator;
+	u8 post_scalar;
+	u8 vco_gain;
+};
+
+extern unsigned long sisfb_calc_clock_freq(struct sisfb_clock_param * clock);
+extern int sisfb_calc_clock_param(struct sisfb_clock_param * clock, unsigned long freq);
+extern void sisfb_set_dispsw_fbcon(struct display * disp, struct sisfb_info * sisfb, int bpp, int accel);
+#include "sisfb_legacy_vga.h"
+
+#endif /* __SISFB_LITE__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_mgavid.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_mgavid.c
--- linux-2.4.21/drivers/video/sis/sisfb_mgavid.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_mgavid.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,271 @@
+/* sisfb_vid.c: Generic High-level Driver Module for /dev/mga_vid API
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ */
+
+#include "sisfb_mgavid.h"
+
+static struct sisfb_info * sisfb;
+static mga_vid_config_t mga_config;
+static unsigned long video_src_base = 4 * 1024 * 1024;
+static u32 frame_size;
+static void sisfb_vid_frame_select(int frame);
+
+static int
+sisfb_vid_set_config(mga_vid_config_t * config)
+{
+	/* align source pitch to 32 bytes, for compatable with MGA */
+	u32 src_pitch = (config->src_width + 31) & ~31;
+
+	frame_size = src_pitch * config->src_height;
+
+	sisfb_video_set_geometry(sisfb, config->x_org, config->y_org,
+				 config->src_width, config->src_height,
+				 config->dest_width, config->dest_height);
+
+	sisfb_vid_frame_select(0);
+
+	if (config->colkey_on) {
+		sisfb_video_set_colorkey(sisfb, config->colkey_red,
+					 config->colkey_green,
+					 config->colkey_blue);
+	} else {
+		sisfb_video_set_colorkey_mode(sisfb, ROP_ALWAYS);
+	}
+
+	sisfb_video_set_pixel_format(sisfb, 0x32315659);
+	sisfb_video_set_brightness(sisfb, 0x20);
+
+	return 0;
+}
+
+static void
+sisfb_vid_frame_select(int frame)
+{
+	u32 y_base, u_base, v_base;
+
+	y_base = video_src_base + frame * frame_size * 3 / 2;
+	u_base = y_base + frame_size;
+	v_base = y_base + frame_size * 5 / 4;
+
+	sisfb_video_set_start_offset(sisfb, y_base, u_base, v_base);
+}
+
+static long long
+sisfb_vid_lseek(struct file *file, long long offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static ssize_t
+sisfb_vid_read(struct file *file, char *buf, size_t count, loff_t * ppos)
+{
+	return -EINVAL;
+}
+
+static ssize_t
+sisfb_vid_write(struct file *file, const char *buf, size_t count, loff_t * ppos)
+{
+	return -EINVAL;
+}
+
+static int
+sisfb_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int frame;
+
+	switch (cmd) {
+	case MGA_VID_CONFIG:
+		if (copy_from_user(&mga_config, (mga_vid_config_t *) arg,
+				   sizeof(mga_vid_config_t))) {
+			printk("sisfb_vid: failed copy from userspace\n");
+			return (-EFAULT);
+		}
+
+		mga_config.ram_size = sisfb->video_size_virt;
+		mga_config.card_type = sisfb->pci_dev->device;
+
+		if (copy_to_user ((mga_vid_config_t *) arg, &mga_config,
+				  sizeof(mga_vid_config_t))) {
+			printk("sisfb_vid: failed copy to userspace\n");
+			return (-EFAULT);
+		}
+		return sisfb_vid_set_config(&mga_config);
+		break;
+
+	case MGA_VID_ON:
+		sisfb_video_enable(sisfb);
+		break;
+
+	case MGA_VID_OFF:
+		sisfb_video_disable(sisfb);
+		break;
+
+	case MGA_VID_FSEL:
+		if (copy_from_user(&frame, (int *) arg, sizeof(int))) {
+			printk("sisfb_vid: FSEL failed copy from userspace\n");
+			return (-EFAULT);
+		}
+
+		sisfb_vid_frame_select(frame);
+		break;
+
+	default:
+		printk("sisfb_vid: Invalid ioctl %d\n", cmd);
+		return (-EINVAL);
+	}
+
+	return 0;
+}
+
+static int
+sisfb_vid_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	u32 mem_base = sisfb->video_base_phy  + video_src_base;
+	u32 mem_size = sisfb->video_size_virt - video_src_base;
+	u32 off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > mem_size)
+		return -EINVAL;
+
+	if (remap_page_range(vma->vm_start, mem_base,
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot)) {
+		printk("sisfb_vid: error mapping video memory\n");
+		return (-EAGAIN);
+	}
+
+	return (0);
+}
+
+static int
+sisfb_vid_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+
+	if (minor != 0)
+		return (-ENXIO);
+
+	file->private_data = sisfb;
+
+	return (0);
+}
+
+static int
+sisfb_vid_release(struct inode *inode, struct file *file)
+{
+	sisfb_video_disable(sisfb);
+
+	return 0;
+}
+
+static struct file_operations sisfb_vid_fops = {
+	llseek:	sisfb_vid_lseek,
+	read:	sisfb_vid_read,
+	write:	sisfb_vid_write,
+	ioctl:	sisfb_vid_ioctl,
+	mmap:	sisfb_vid_mmap,
+	open:	sisfb_vid_open,
+	release:sisfb_vid_release
+};
+
+static int
+sisfb_vid_probe_card(void)
+{
+	struct pci_dev * pci_dev = NULL;
+        void (*init)(struct sisfb_info *) = NULL;
+	char * im_funcname = NULL;
+	char * im_modname = NULL;
+	int ret = 0;
+
+	/* find all PCI VGA devices in the system */
+	while ((pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, pci_dev)) != NULL) {
+		if (pci_dev->vendor != PCI_VENDOR_ID_SI) {
+			/* not an SiS VGA, try next one */
+			continue;
+		}
+
+		if ((sisfb = pci_dev->driver_data) == NULL) {
+			/* this SiS VGA device is not managed by SiSFB Lite */
+			continue;
+		}
+
+		switch (pci_dev->device) {
+		case PCI_DEVICE_ID_SI_630_VGA:
+		case PCI_DEVICE_ID_SI_540_VGA:
+			im_funcname = "sisfb_300_overlay_init";
+			im_modname  = "sisfb_300_overlay";
+			break;
+		case PCI_DEVICE_ID_SI_550_VGA:
+			im_funcname = "sisfb_315_overlay_init";
+			im_modname  = "sisfb_315_overlay";
+			break;
+		default:
+			continue;
+		}
+
+		/* insmod for device dependent overlay driver */
+		if (im_funcname != NULL)
+			init = inter_module_get_request(im_funcname, im_modname);
+
+		/* calling init for device dependent overlay driver */
+		if (init != NULL) {
+			init(sisfb);
+			inter_module_put(im_funcname);
+		}
+
+		ret++;
+	}
+
+	return ret;
+}
+
+static int
+sisfb_vid_initialize(void)
+{
+	if (!sisfb_vid_probe_card()) {
+		printk(KERN_ERR "sis_vid: no supported devices found\n");
+		return -EINVAL;
+	}
+
+	if (register_chrdev(SISFB_VID_MAJOR, "sisfb_vid", &sisfb_vid_fops)) {
+		printk(KERN_ERR "sis_vid: unable to get major: %d\n",
+		       SISFB_VID_MAJOR);
+		return -EIO;
+	}
+
+	return (0);
+}
+
+int
+init_module(void)
+{
+	return sisfb_vid_initialize();
+}
+
+void
+cleanup_module(void)
+{
+	unregister_chrdev(SISFB_VID_MAJOR, "sisfb_vid");
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_mgavid.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_mgavid.h
--- linux-2.4.21/drivers/video/sis/sisfb_mgavid.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_mgavid.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,34 @@
+#ifndef __SISFB_VID__
+#define __SISFB_VID__
+
+#include "sisfb_overlay.h"
+
+#define SISFB_VID_MAJOR 178
+
+typedef struct mga_vid_config_s
+{
+	uint16_t card_type;
+	uint32_t ram_size;
+
+	uint32_t src_width;
+	uint32_t src_height;
+
+	uint32_t dest_width;
+	uint32_t dest_height;
+	uint32_t x_org;
+	uint32_t y_org;
+
+	uint8_t  colkey_on;
+	uint8_t  colkey_red;
+	uint8_t  colkey_green;
+	uint8_t  colkey_blue;
+
+} mga_vid_config_t;
+
+#define MGA_VID_CONFIG    _IOR('J', 1, mga_vid_config_t)
+#define MGA_VID_ON        _IO ('J', 2)
+#define MGA_VID_OFF       _IO ('J', 3)
+#define MGA_VID_FSEL      _IOR('J', 4, int)
+
+
+#endif
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_overlay.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_overlay.c
--- linux-2.4.21/drivers/video/sis/sisfb_overlay.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_overlay.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,179 @@
+/* sisfb_video.c: Generic SiSFB Video Acclereator
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ */
+
+#include "sisfb_overlay.h"
+
+/* private interface, scale parameter part */
+/**
+ *	sisfb_video_calc_scale_param: - Calculate video overlay scale parameter
+ *	@sisfb: SiS Frame Buffer structure
+ *	@src_width: Source image width
+ *	@src_height: Source image height
+ *	@dest_width: Destination image width
+ *	@dest_height: Destination image height
+ */
+static void
+sisfb_overlay_calc_scale_param(struct sisfb_overlay_scale_param * overlay_param,
+			       u32 src_width, u32 src_height,
+			       u32 dest_width, u32 dest_height)
+{
+	struct sisfb_video_scale_param * video_param;
+
+	/* get superclass */
+	video_param   = (struct sisfb_video_scale_param *) overlay_param;
+
+	/* set data member of this object */
+	if (video_param->hor_int == 1)
+		overlay_param->hor_dda = 1;
+
+	if (video_param->ver_int == 1)
+		overlay_param->ver_dda = 1;	
+
+	/* FixMe: figure this out */
+	overlay_param->hor_preset_int = 0;
+}
+
+/* public interface, overlay_scale_param part */
+static void
+sisfb_calc_scale_param(struct sisfb_overlay_scale_param * overlay_param,
+			       u32 src_width, u32 src_height,
+			       u32 dest_width, u32 dest_height)
+{
+	struct sisfb_video_scale_param * video_param;
+
+	/* get superclass */
+	video_param   = (struct sisfb_video_scale_param *) overlay_param;
+
+	/* call superclass' method */
+	video_param->video_calc_scale_param(video_param, src_width, src_height,
+					    dest_width, dest_height);
+
+	/* call our own method */
+	overlay_param->overlay_calc_scale_param(overlay_param, src_width, src_height,
+						dest_width, dest_height);
+}
+
+struct sisfb_overlay_scale_param *
+sisfb_overlay_scale_param_new(void)
+{
+	struct sisfb_overlay_scale_param * overlay_param;
+
+	/* allocate memory for this class */
+	overlay_param = kmalloc(sizeof(struct sisfb_overlay_scale_param), GFP_KERNEL);
+	if (overlay_param == NULL)
+		return NULL;
+
+	memset(overlay_param, 0, sizeof(struct sisfb_overlay_scale_param));
+
+	/* FixME: calling _init() method ?? */
+
+	return overlay_param;
+}
+
+void
+sisfb_overlay_scale_param_init(struct sisfb_overlay_scale_param * overlay_param)
+{
+	/* call superclass' constructor */
+	sisfb_video_scale_param_init((struct sisfb_video_scale_param *) overlay_param);
+
+	/* setup superclass' virtual function */
+	(struct sisfb_video_scale_param *) overlay_param->calc_scale_param =
+		sisfb_calc_scale_param;
+
+	/* setup my own private method */
+	overlay_param->overlay_calc_scale_param = sisfb_overlay_calc_scale_param;
+}
+
+void
+sisfb_overlay_scale_param_delete(struct sisfb_overlay_scale_param * overlay_param)
+{
+	/* call superclass's destructor, do nothing */
+	//sisfb_video_scale_param_delete((struct sisfb_video_scale_param *) overlay_param);
+
+	/* delete myself */
+	kfree(overlay_param);
+}
+
+/* public interface, overlay part */
+struct sisfb_overlay_info *
+sisfb_overlay_new(void)
+{
+	struct sisfb_overlay_info * overlay;
+
+	/* allocate memory for this and superclass */
+	overlay = kmalloc(sizeof(struct sisfb_overlay_info), GFP_KERNEL);
+	if (overlay == NULL)
+		return NULL;
+
+	memset(overlay, 0, sizeof(struct sisfb_overlay_info));
+
+	/* FixME: calling _init() method ?? */
+
+	return overlay;
+}
+
+void
+sisfb_overlay_init(struct sisfb_overlay_info * overlay)
+{
+	struct sisfb_video_info * video;
+	struct sisfb_overlay_scale_param * overlay_param;
+
+	/* allocate our data member ?? */
+	overlay_param = sisfb_overlay_scale_param_new();
+	sisfb_overlay_scale_param_init(overlay_param);
+
+	video = (struct sisfb_video_info *) overlay;
+
+	/* call superclass' constructor, do nothing */
+	//sisfb_video_init(video);
+
+	/* override superclass' methods */
+	video->enable      = sisfb_overlay_enable;
+	video->disable	   = sisfb_overlay_disable;
+
+	/* override supercalss' data member */
+	video->num_buffers = DEFAULT_OVERLAY_BUFFERS;
+	video->scale_param = (struct sisfb_video_scale_param *) overlay_param;
+}
+
+void
+sisfb_overlay_delete(struct sisfb_overlay_info * overlay)
+{
+	struct sisfb_video_info * video;
+	struct sisfb_overlay_scale_param * overlay_param;
+
+	video = (struct sisfb_video_info *) overlay;
+	overlay_param = sisfb_overlay_scale_param_new();
+
+	/* call superclass's destructor */
+	//sisfb_video_delete((struct sisfb_overlay_info *) overlay);
+
+	/* delete overriden superclass' data member */
+	sisfb_overlay_scale_param_delete(overlay_param);
+
+	/* delete myself */
+	kfree(overlay);
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_overlay.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_overlay.h
--- linux-2.4.21/drivers/video/sis/sisfb_overlay.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_overlay.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,157 @@
+#ifndef __SISFB_OVERLAY__
+#define __SISFB_OVERLAY__
+
+#include "sisfb_video.h"
+
+enum sisfb_overlay_registers {
+	/* Video Window Horizonal Start/End, in unit of screen pixel */
+	SISFB_OVERLAY_WIN_HOR_DISP_START_LOW	= 0x01,
+	SISFB_OVERLAY_WIN_HOR_DISP_END_LOW	= 0x02,
+	SISFB_OVERLAY_WIN_HOR_DISP_OVERFLOW	= 0x03,
+
+	/* Video Window Horizonal Start/End, in unit of screen pixel*/
+	SISFB_OVERLAY_WIN_VER_DISP_START_LOW	= 0x04,
+	SISFB_OVERLAY_WIN_VER_DISP_END_LOW	= 0x05,
+	SISFB_OVERLAY_WIN_VER_DISP_OVERFLOW	= 0x06,
+
+	/* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, in unit of dword (300) or word (315) */
+	SISFB_OVERLAY_Y_BUF_START_LOW		= 0x07,
+	SISFB_OVERLAY_Y_BUF_START_MIDDLE	= 0x08,
+	SISFB_OVERLAY_Y_BUF_START_HIGH		= 0x09,
+
+	/* U Plane (4:2:0) buffer start address, in unit of dword (300) or word (315) */
+	SISFB_OVERLAY_U_BUF_START_LOW		= 0x0A,
+	SISFB_OVERLAY_U_BUF_START_MIDDLE	= 0x0B,
+	SISFB_OVERLAY_U_BUF_START_HIGH		= 0x0C,
+
+	/* U Plane (4:2:0) buffer start address, in unit of dword (300) or word (315) */
+	SISFB_OVERLAY_V_BUF_START_LOW		= 0x0D,
+	SISFB_OVERLAY_V_BUF_START_MIDDLE	= 0x0E,
+	SISFB_OVERLAY_V_BUF_START_HIGH		= 0x0F,
+
+	/* Ptich for Y, UV Planes, in unit of dword (300) or word (315) */
+	SISFB_OVERLAY_Y_BUF_PITCH_LOW		= 0x10,
+	SISFB_OVERLAY_UV_BUF_PITCH_LOW		= 0x11,
+	SISFB_OVERLAY_Y_UV_BUF_PITCH_MIDDLE	= 0x12,
+
+	/* FixMe: No idea what this is */
+	SISFB_OVERLAY_Y_BUF_PRESET_LOW		= 0x13,
+	SISFB_OVERLAY_Y_BUF_PRESET_MIDDLE	= 0x14,
+
+	SISFB_OVERLAY_UV_BUF_PRESET_LOW		= 0x15,
+	SISFB_OVERLAY_UV_BUF_PRESET_MIDDLE	= 0x16,
+
+	SISFB_OVERLAY_Y_UV_BUF_PRESET_HIGH	= 0x17,
+
+	/* Image Sacling control registers */
+	SISFB_OVERLAY_HOR_SCALE_LOW		= 0x18,
+	SISFB_OVERLAY_HOR_SCALE_HIGH		= 0x19,
+
+	SISFB_OVERLAY_VER_SCALE_LOW		= 0x1A,
+	SISFB_OVERLAY_VER_SCALE_HIGH		= 0x1B,
+
+	SISFB_OVERLAY_SCALE_CONTROL		= 0x1C,
+
+	/* Playback line buffer control */
+	SISFB_OVERLAY_PLAYBACK_THRESHOLD_LOW	= 0x1D,
+	SISFB_OVERLAY_PLAYBACK_THRESHOLD_HIGH	= 0x1E,
+	SISFB_OVERLAY_PLAYBACK_LINE_BUF_SIZE	= 0x1F,
+
+	/* Destination color key, RGB color space */
+	SISFB_OVERLAY_OVERLAY_COLORKEY_RED_MIN	= 0x20,
+	SISFB_OVERLAY_OVERLAY_COLORKEY_GREEN_MIN= 0x21,
+	SISFB_OVERLAY_OVERLAY_COLORKEY_BLUE_MIN	= 0x22,
+	SISFB_OVERLAY_OVERLAY_COLORKEY_RED_MAX	= 0x23,
+	SISFB_OVERLAY_OVERLAY_COLORKEY_GREEN_MAX= 0x24,
+	SISFB_OVERLAY_OVERLAY_COLORKEY_BLUE_MAX	= 0x25,
+
+	/* Source color key, YUV or RGB color space */
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_Y_MIN	= 0x26,
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_U_MIN	= 0x27,
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_V_MIN	= 0x28,
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_Y_MAX	= 0x29,
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_U_MAX	= 0x2A,
+	SISFB_OVERLAY_OVERLAY_CHROMAKEY_V_MAX	= 0x2B,
+
+	/* Contrast Enhancement and Brightness control */
+	SISFB_OVERLAY_CONTRAST_FACTOR		= 0x2C,
+	SISFB_OVERLAY_BRIGHTNESS		= 0x2D,
+	SISFB_OVERLAY_CONTRAST_ENHANCE_CONTROL	= 0x2E,
+
+	SISFB_OVERLAY_OVERLAY_COLORKEY_MODE	= 0x2F,
+
+	/* Misc Control, inclue YUV 422, YUV 420 selectrion */
+	SISFB_OVERLAY_MISC_CONTROL_0		= 0x30,
+	SISFB_OVERLAY_MISC_CONTROL_1		= 0x31,
+	SISFB_OVERLAY_MISC_CONTROL_2		= 0x32,
+};
+
+enum sisfb_overlay_pixel_format {
+	PIXEL_FORMAT_YV12	= (('2'<<24)|('1'<<16)|('V'<<8)|'Y'), /* YVU  420 Planar */
+
+	PIXEL_FORMAT_IYUV	= (('V'<<24)|('U'<<16)|('Y'<<8)|'I'), /* YUV  420 Planar */
+	PIXEL_FORMAT_I420	= (('0'<<24)|('2'<<16)|('4'<<8)|'I'), /* YUV  420 Planar */
+
+	PIXEL_FORMAT_YUY2 	= (('2'<<24)|('Y'<<16)|('U'<<8)|'Y'), /* YUYV 422 Packed */
+	PIXEL_FORMAT_YVYU 	= (('U'<<24)|('Y'<<16)|('V'<<8)|'Y'), /* YVYU 422 Packed */
+	PIXEL_FORMAT_UYVY 	= (('Y'<<24)|('V'<<16)|('Y'<<8)|'U'), /* UYVY 422 Packed */
+	PIXEL_FORMAT_VYUY 	= (('Y'<<24)|('U'<<16)|('Y'<<8)|'V'), /* VYUY 422 Packed */
+
+	PIXEL_FORMAT_RGB565 	= (('B'<<24)|('G'<<16)|('R'<<8)),     /* RGB  565 Packed */
+};
+
+/* FixME: Should we move this to device dependent header files */
+enum sisfb_overlay_index {
+	SISFB_OVERLAY_1,
+	SISFB_OVERLAY_2,	
+};
+
+enum sisfb_monitor_index {
+	SISFB_MONITOR_1,
+	SISFB_MONITOR_2
+};
+
+static inline void
+sisfb_overlay_enable(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SISFB_OVERLAY_MISC_CONTROL_0);
+	sisfb_set_video_reg(sisfb, SISFB_OVERLAY_MISC_CONTROL_0, data | 0x02);
+}
+
+static inline void
+sisfb_overlay_disable(struct sisfb_info * sisfb)
+{
+	u8 data;
+
+	data = sisfb_get_video_reg(sisfb, SISFB_OVERLAY_MISC_CONTROL_0);
+	sisfb_set_video_reg(sisfb, SISFB_OVERLAY_MISC_CONTROL_0, data & ~0x02);
+}
+
+static inline void
+sisfb_overlay_set_brightness(struct sisfb_info * sisfb, u8 birghtness)
+{
+	sisfb_set_video_reg(sisfb, SISFB_OVERLAY_BRIGHTNESS, birghtness);
+}
+
+static inline u8
+sisfb_overlay_get_brightness(struct sisfb_info * sisfb)
+{
+	return sisfb_get_video_reg(sisfb, SISFB_OVERLAY_BRIGHTNESS);
+}
+
+static inline void
+sisfb_overlay_set_contrast(struct sisfb_info * sisfb, u8 contrast)
+{
+	sisfb_set_video_reg(sisfb, SISFB_OVERLAY_CONTRAST_ENHANCE_CONTROL,
+			    contrast);
+}
+
+static inline u8
+sisfb_overlay_get_contrast(struct sisfb_info * sisfb)
+{
+	return sisfb_get_video_reg(sisfb, SISFB_OVERLAY_CONTRAST_ENHANCE_CONTROL);
+}
+
+#endif /* __SISFB_OVERLAY__ */
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_syncfb.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_syncfb.c
--- linux-2.4.21/drivers/video/sis/sisfb_syncfb.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_syncfb.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,367 @@
+/* sisfb_syncfb.c: Generic High-level Driver Module for SyncFB API
+ *
+ * Copyright 2002 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ * Reference:
+ *	sis_video.c in XFree86 4.0.2
+ *	syncfb_matrox.c in SyncFB 0.3a
+ */
+ 
+#include "syncfb.h"
+#include "sisfb_300_video.h"
+#include <linux/interrupt.h>	/* used by task_queue stuff */
+
+static int sisfb_probe_card(void);
+static void sisfb_cleanup(void);
+static void sisfb_enable(void);
+static void sisfb_disable(void);
+static int sisfb_set_config(syncfb_config_t * config);
+static void sisfb_syncfb_pseduo_irq(void * data);
+
+static uint_32 sisfb_mem_size = 8 * 1024 * 1024;
+
+/* 4 frame buffers, each has three plane (YUV or RGB) */
+static uint_32 sisfb_buf_offset[4];
+static uint_32 sisfb_buf_offset_p2[4];
+static uint_32 sisfb_buf_offset_p3[4];
+
+static int brightness = 0;
+static int contrast = 0x70;
+static int enabled = 0;
+
+static struct sisfb_info * sisfb;
+static syncfb_config_t sfb_config;
+
+static const char im_funcname[] = "sisfb_300_overlay_init";
+static const char im_modname[] = "sisfb_300_overlay";
+
+/* task queue is used to simulate HW VSync interrupt */ 
+static struct tq_struct syncfb_tq = {
+	routine:	sisfb_syncfb_pseduo_irq
+};
+
+static syncfb_capability_t sisfb_caps = {
+	name:		"SiSFB Lite",
+	palettes:	0,
+	features:	0,
+	memory_size:	0
+};
+
+static void
+sisfb_config_overlay(syncfb_config_t *config)
+{
+	sisfb_video_set_geometry(sisfb, config->image_xorg, config->image_yorg,
+				 config->src_width, config->src_height,
+				 config->image_width, config->image_height);
+
+	switch (config->src_palette) {
+	case VIDEO_PALETTE_RGB565:
+		/* FixME: implemente RGB565 and other pixel format */
+		break;
+	case VIDEO_PALETTE_YUV420P3:
+	default:
+		sisfb_video_set_pixel_format(sisfb, 0x32315659);
+		break;
+	}
+
+	if (config->syncfb_mode & SYNCFB_FEATURE_COLKEY) {
+		sisfb_video_set_colorkey(sisfb, config->colkey_red,
+					 config->colkey_green,
+					 config->colkey_blue);
+	} else {
+		sisfb_video_set_colorkey_mode(sisfb, ROP_ALWAYS);
+	}
+}
+
+static int
+sisfb_set_config(syncfb_config_t * config)
+{
+	int i;
+	u32 frame_size, video_src_base;
+
+	if (!(sisfb_caps.palettes & ((uint_32) 1 << config->src_palette))) {
+		/* palette not supported */
+		printk(KERN_ERR "syncfb (sisfb): palette not supported: %ld\n",
+		       config->src_palette);
+		return -1;
+	}
+
+	/* pixel align on 32 pix, to be compatable with MGA */
+	config->src_pitch = (config->src_width + 31) & ~31;
+
+	/* Set frame_size == 2 * Y_plane_size, enough for YUV 422 and RGB 565 cases */
+	frame_size = (config->src_pitch * config->src_height * 2);
+
+	if (frame_size * 4 + config->fb_screen_size > sisfb_mem_size) {
+		/* not enough memory to create buffers */
+		printk(KERN_ERR "syncfb (sisfb): not enough buffer space\n");
+		return -1;
+	}
+
+	/* pixel align on 32 pix, to be compatable with MGA */
+	video_src_base = (config->fb_screen_size + 31) & ~31;
+
+	config->buffer_size = frame_size;
+	config->buffers = 4;
+
+	for (i = 0; i < 4; i++) {
+		sisfb_buf_offset[i] = video_src_base + (i * frame_size);
+		sisfb_buf_offset_p2[i] = sisfb_buf_offset[i] +
+			(config->src_pitch * config->src_height);
+		sisfb_buf_offset_p3[i] = sisfb_buf_offset_p2[i] +
+			(config->src_pitch * config->src_height / 2);
+	}
+
+	sisfb_config_overlay(config);
+
+	return 0;
+}
+
+static int
+sisfb_config(uint_8 set, syncfb_config_t * config)
+{
+	int i;
+
+	if (set) {
+		i = sisfb_set_config(config);
+		if (!i) {
+			memcpy(&sfb_config, config, sizeof(syncfb_config_t));
+			return 0;
+		}
+		return i;
+	}
+
+	memcpy(config, &sfb_config, sizeof(syncfb_config_t));
+
+	return 0;
+}
+
+static void
+sisfb_syncfb_set_param(syncfb_config_t * config)
+{
+	sisfb_video_set_geometry(sisfb, config->image_xorg, config->image_yorg,
+				 config->src_width, config->src_height,
+				 config->image_width, config->image_height);
+
+	sisfb_video_set_brightness(sisfb, brightness);
+
+	/* The hardware only accept contrast value from 0 to 7,
+	 * SyncFB defines contrast value from 0 to 1000 */
+	sisfb_video_set_contrast(sisfb, (contrast >> 5) & 0x07);
+}
+
+static int 
+sisfb_params(uint_8 set, syncfb_param_t * param)
+{
+	if (set) {
+		brightness = param->brightness;
+		contrast   = param->contrast;
+
+		sfb_config.image_xorg   = param->image_xorg;
+		sfb_config.image_yorg   = param->image_yorg;
+		sfb_config.image_width  = param->image_width;
+		sfb_config.image_height = param->image_height;
+
+		sisfb_syncfb_set_param(&sfb_config);
+
+		return 0;
+	} else {
+		param->brightness = brightness;
+		param->contrast = contrast;
+
+		return 0;
+	}
+}
+
+static syncfb_capability_t *
+sisfb_capability(void)
+{
+	sisfb_caps.palettes = (1 << VIDEO_PALETTE_RGB565) |
+		(1 << VIDEO_PALETTE_YUV420P);
+
+	sisfb_caps.features = SYNCFB_FEATURE_SCALE | SYNCFB_FEATURE_CROP |
+		SYNCFB_FEATURE_OFFSET | SYNCFB_FEATURE_PROCAMP |
+		SYNCFB_FEATURE_COLKEY;
+
+	sisfb_caps.memory_size = sisfb->video_size_virt;
+
+	return &sisfb_caps;
+}
+
+static void
+sisfb_syncfb_pseduo_irq(void *  data)
+{
+	syncfb_interrupt();
+
+	if (enabled) {
+		syncfb_tq.data = NULL;
+		syncfb_tq.sync = 0;
+		queue_task(&syncfb_tq, &tq_timer);
+	}
+}
+
+static void
+sisfb_enable(void)
+{
+	enabled = 1;
+
+	syncfb_tq.data = NULL;
+	syncfb_tq.sync = 0;
+	queue_task(&syncfb_tq, &tq_immediate);
+	mark_bh(IMMEDIATE_BH);
+
+	sisfb_video_enable(sisfb);
+}
+
+static void
+sisfb_disable(void)
+{
+	enabled = 0;
+	sisfb_video_disable(sisfb);
+}
+
+static void
+sisfb_cleanup()
+{
+	inter_module_put(im_funcname);
+	sisfb_video_disable(sisfb);
+}
+
+static void
+sisfb_request_buffer(syncfb_buffer_info_t * buf)
+{
+	buf->offset = sisfb_buf_offset[buf->id];
+	buf->offset_p2 = sisfb_buf_offset_p2[buf->id];
+	buf->offset_p3 = sisfb_buf_offset_p3[buf->id];
+}
+
+void sisfb_select_buffer(uint_8 buf)
+{
+	u32 y_base, u_base, v_base;
+
+	y_base = sisfb_buf_offset[buf];
+	u_base = sisfb_buf_offset_p2[buf];
+	v_base = sisfb_buf_offset_p3[buf];
+
+	sisfb_video_set_start_offset(sisfb, y_base, u_base, v_base);
+}
+
+static int
+sisfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	    unsigned long arg)
+{
+	return -EINVAL;
+}
+
+static int
+sisfb_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	u32 mem_base = sisfb->video_base_phy;
+	u32 mem_size = sisfb->video_size_virt;
+	u32 off = vma->vm_pgoff << PAGE_SHIFT;
+
+	if ((vma->vm_end - vma->vm_start + off) > mem_size)
+		return -EINVAL;
+
+	if (remap_page_range(vma->vm_start, mem_base,
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot)) {
+		printk("sisfb_vid: error mapping video memory\n");
+		return (-EAGAIN);
+	}
+
+	return (0);
+}
+
+static syncfb_device_t sisfb_device = {
+	sisfb_capability,
+	sisfb_enable,
+	sisfb_disable,
+	sisfb_cleanup,
+	sisfb_request_buffer,
+	sisfb_select_buffer,
+	sisfb_config,
+	sisfb_params,
+	sisfb_ioctl,		/* ioctl */
+	sisfb_mmap		/* mmap */
+};
+
+
+/* returns 0 on success, errcode on failure */
+int
+sisfb_probe_card(void)
+{
+	struct pci_dev * pci_dev = NULL;
+        void (*init)(struct sisfb_info *) = NULL;
+	char * im_funcname = NULL;
+	char * im_modname = NULL;
+
+	/* find all PCI VGA devices in the system */
+	while ((pci_dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, pci_dev)) != NULL) {
+		if (pci_dev->vendor != PCI_VENDOR_ID_SI) {
+			/* not an SiS VGA, try next one */
+			continue;
+		}
+
+		if ((sisfb = pci_dev->driver_data) == NULL) {
+			/* this SiS VGA device is not managed by SiSFB Lite */
+			continue;
+		}
+
+		switch (pci_dev->device) {
+		case PCI_DEVICE_ID_SI_630_VGA:
+		case PCI_DEVICE_ID_SI_540_VGA:
+			im_funcname = "sisfb_300_overlay_init";
+			im_modname  = "sisfb_300_overlay";
+			break;
+		case PCI_DEVICE_ID_SI_550_VGA:
+			im_funcname = "sisfb_315_overlay_init";
+			im_modname  = "sisfb_315_overlay";
+			break;
+		default:
+			continue;
+		}
+
+		/* insmod for device dependent overlay driver */
+		if (im_funcname != NULL)
+			init = inter_module_get_request(im_funcname, im_modname);
+
+		/* calling init for device dependent overlay driver */
+		if (init != NULL) {
+			init(sisfb);
+			inter_module_put(im_funcname);
+		}
+	}
+
+	return 0;
+}
+
+/* extern */
+syncfb_device_t *
+syncfb_get_sisfb_device(void)
+{
+	if (sisfb_probe_card() == 0)
+		/* no error code */
+		return &sisfb_device;
+
+	return NULL;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_utils.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_utils.c
--- linux-2.4.21/drivers/video/sis/sisfb_utils.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_utils.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,179 @@
+#include "sisfb_lite.h"
+
+/**
+ *	sisfb_calc_clock_freq: - Calculate the clock frequence generated by @clock
+ *	@clock: paramters of the clock generator.
+ *
+ *	Calculate the clock frequence that will be generated by the internal clock
+ *	generator given the paremters stated in @clock. The frequence is returned
+ *	in the unit of KHz.
+ */
+unsigned long
+sisfb_calc_clock_freq(struct sisfb_clock_param * clock)
+{
+	unsigned long freq = CLOCK_SOURCE;
+
+	freq *= (clock->divider * clock->numerator);
+	freq /= (clock->denumerator * clock->post_scalar);
+
+	return freq;
+}
+
+/**
+ *	sisfb_calc_clock_param: - Calculate the correct clock generator parameters for @freq
+ *	@clock: Paramters of the clock generator (return)
+ *	@freq: The desired clock frequence in KHz
+ *
+ *	Calculate the clock generator parameters that will generate the clock signal
+ *	with frequence @freq. This is the inverse function of sisfb_calc_clock_freq()
+ *
+ *	Return 0 on success, -EINVAL otherwise.
+ *
+ *	In this function, we are trying to find a set of parmeters (divider, numerator,
+ *	denumerator, post scalar) such that:
+ *
+ *                      |   Divider * Numerator               |
+ *      |Fout - Freq| = |------------------------- Fref - Freq| => 0
+ *                      |Denumerator * Post Scalar            |
+ *
+ *	In order to simplify the alogrithm we have introduced the following contrains:
+ *		1. The Post Scalar can only be power of 2 i.e. 1,2,4,8
+ *		2. The divider is always 1.
+ *		3. The frequence range for the VCO output (Fout * Post Scalar)
+ *		   is 150 MHz - 300 MHZ
+ *
+ *	First we have to find out the proper value for Post Scalar. Due to the
+ *	constrains stated above, for @freq in the following ranges, we set the
+ *	Post Scalar as:
+ *		     freq        post scalar
+ *		  150 -  300 MHz	1
+ *		   75 -  150 MHz	2
+ *		 37.5 -   75 MHz	4
+ *		18.75 - 37.5 MHz	8
+ *	Once the Post Scalar is determined, we try every possible (numerator, denumerator)
+ *	pair such that the error between the generated frequence f_out and desirec
+ *	frequence @freq is minimal.
+ */
+int
+sisfb_calc_clock_param(struct sisfb_clock_param * clock, unsigned long freq)
+{
+	int numerator, denumerator;
+	unsigned long f_vco = freq;
+	long error, min_error = freq;
+
+	/* test if the required frequency is out of range */
+	if ((freq > MAX_F_VCO) || (freq < MIN_F_VCO / 8))
+		return -EINVAL;
+
+	/* find the proper Post Scalar */
+	clock->post_scalar = 8;
+	while (f_vco > MAX_F_VCO / 8) {
+		f_vco /= 2;
+		clock->post_scalar /= 2;
+	}
+
+	/* find the (numerator, denumerator) pair that minimize the error = |f_out - freq| */
+	for (denumerator = 2; denumerator <= 32; denumerator++) {
+		for (numerator = 1; numerator <= 128; numerator++) {
+			unsigned long f_out = CLOCK_SOURCE;
+
+			f_out *= numerator;
+			f_out /= (denumerator * clock->post_scalar);
+			error = f_out - freq;
+			error = (error > 0) ? error : -error;
+			if (error < min_error) {
+				min_error = error;
+				clock->numerator = numerator;
+				clock->denumerator = denumerator;
+			}
+			/* FixMe: return early if we are satisfied with current
+			 * parameters */
+		}
+	}
+
+	/* this is our unfortunate constrain */
+	clock->divider  = 1;
+	clock->vco_gain = 1;
+
+	return 0;
+}
+
+/**
+ *	sisfb_get_shared_memory_size: - Get framebuffer memory size
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	Get the framebuffer memory size from host controller. For SiS 540/630/730 and
+ *	SiS 550 Families, the Shared Memory Area (SMA) is enabled in Bit 7, size is
+ *	stored in Bit 4..6 of Register 0x63, Host Bridge (i.e. PCI 0:0.0).
+ *
+ *	The register is set by DRAM initialzation code during boot process and can
+ *	not be re-configured once the DRAM has been turned on. 
+ */
+#define SIS630_BANKENABLE 0x63
+static int __devinit
+sisfb_get_shared_memory_size(struct sisfb_info * sisfb)
+{
+	struct pci_dev * host = NULL;
+	u8 dram_status, sma_size, sma_size_bits;
+
+	if ((host = pci_find_slot(0, 0)) == NULL) {
+		printk(KERN_EMERG "sisfb_lite: Can not find Host Controller !!!\n");
+		return -ENODEV;
+	}
+
+	/* get SMA configuration from register 0x63 */
+	pci_read_config_byte(host, SIS630_BANKENABLE, &dram_status);
+
+	/* SMA not enabled */
+	if ((dram_status & 0x80) != 0x80)
+		return -ENODEV;
+
+	/* compute Shared Menory Area (SMA) size in Mega Bytes */
+	sma_size_bits = (dram_status >> 4) & 0x7;
+	if (sma_size_bits > 5) {
+		// this is invalid!
+		printk(KERN_EMERG "sisfb_lite: Invalid Shared Memory Area Configuration !!!\n");
+		return -ENODEV;
+	}
+	sma_size = (2 << sma_size_bits);
+	sisfb->video_size_virt = sma_size * 1024 * 1024;
+
+	return 0;
+}
+
+/**
+ *	sisfb_get_memory_size: - Get framebuffer memory size
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Return 0 on Success, -ENODEV if SMA is incorrectly/not configured
+ *
+ *	Get the framebuffer memory size from host controller. For SiS 540/630/730 and
+ *	SiS 550 Families, the Shared Memory Area (SMA) is enabled in Bit 7, size is
+ *	stored in Bit 4..6 of Register 0x63, Host Bridge (i.e. PCI 0:0.0).
+ *
+ *	The register is set by DRAM initialzation code during boot process and can
+ *	not be re-configured once the DRAM has been turned on. 
+ */
+int __devinit
+sisfb_get_memory_size(struct sisfb_info * sisfb)
+{
+	switch (sisfb->pci_dev->device) {
+	case PCI_DEVICE_ID_SI_630_VGA:
+	case PCI_DEVICE_ID_SI_540_VGA:
+	case PCI_DEVICE_ID_SI_550_VGA:
+		sisfb_get_shared_memory_size(sisfb);
+		break;
+	case  PCI_DEVICE_ID_SI_300:
+		//sisfb_300_dram_sizing(sisfb);
+		break;
+	case  PCI_DEVICE_ID_SI_315:
+		//sisfb_315_dram_sizing(sisfb);
+		break;
+	default:
+		return -ENODEV;
+	}
+	return 0;
+}
+
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_video.c linux-2.4.21-init_dyn/drivers/video/sis/sisfb_video.c
--- linux-2.4.21/drivers/video/sis/sisfb_video.c	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_video.c	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,90 @@
+/* sisfb_video.c: Generic SiSFB Video Acclereator
+ *
+ * Copyright 2001 Ollie Lho <ollie@sis.com.tw>
+ *
+ *	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * This driver is implemented by the Author for his own personal interests and is NOT a
+ * commitment NOR supported officially by Silicon Integrated Systems Corp. Please direct
+ * any bug report/question to the Author and don't bother SiS Technical Support Personell.
+ *
+ *
+ */
+
+#include "sisfb_video.h"
+
+/* private interface */
+/**
+ *	sisfb_video_calc_scale_param: - Set the video overlay scale parameter
+ *	@sisfb: SiS Frame Buffer structure
+ *	@src_width: Source image width
+ *	@src_height: Source image height
+ *	@dest_width: Destination image width
+ *	@dest_height: Destination image height
+ *
+ *	  dst              1
+ *	 ----- = ------------------------
+ *	  src     Int_part +  Fract_part
+ *	                     ------------
+ *	                        0x10000
+ *
+ *
+ *	 src
+ *	-----  = 
+ *	 dst
+ */
+static void
+sisfb_video_calc_scale_param(struct sisfb_video_scale_param * scale_param,
+		      u32 src_width, u32 src_height,
+		      u32 dest_width, u32 dest_height)
+{
+	/* Horizontal Scale Factors */
+	if (src_width == dest_width) {
+		scale_param->hor_int   = 0x01;
+		scale_param->hor_fract = 0x00;
+	} else if (src_width < dest_width) {
+		scale_param->hor_int   = 0x00;
+		scale_param->hor_fract =
+			0x10000 * src_width / dest_width;
+	} else {
+		scale_param->hor_int   = 0x01;
+		scale_param->hor_fract =
+			0x10000 * (src_width - dest_width) / dest_width;
+	}
+
+	/* Vertical Scale Factors*/
+	if (src_height == dest_height) {
+		scale_param->ver_int   = 0x01;
+		scale_param->ver_fract = 0x00;
+	} else if (src_height < dest_height) {
+		scale_param->ver_int   = 0x00;
+		scale_param->ver_fract =
+			0x10000 * src_height / dest_height;
+	} else {
+		scale_param->ver_int   = 0x01;
+		scale_param->ver_fract =
+			0x10000 * (src_height - dest_height) / dest_height;
+	}
+}
+
+/* Virtual functions of sisfb_video_scale_param and sisfb_video
+ * Consider moving to sisfb_video.h and make them inline */
+void
+sisfb_video_scale_param_init(struct sisfb_video_scale_param * video_param)
+{
+	/* setup my own method */
+	video_param->video_calc_scale_param = sisfb_video_calc_scale_param;
+}
diff -Nur linux-2.4.21/drivers/video/sis/sisfb_video.h linux-2.4.21-init_dyn/drivers/video/sis/sisfb_video.h
--- linux-2.4.21/drivers/video/sis/sisfb_video.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/sisfb_video.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,210 @@
+#ifndef __SISFB_VIDEO__
+#define __SISFB_VIDEO__
+
+#include "sisfb_lite.h"
+
+/* Abstract base class for all SiS video acceleration functions */
+struct sisfb_video_info {
+	u8 num_buffers;		/* Number of buffers supported by this video class */
+
+	int src_width;		/* source image width in pixel */
+	int src_height;		/* source image height in pixel */
+
+	int src_pitch;		/* source image pitch, FixME in pixel or byte ?? */
+
+	/* source image crop, used for dest_xorg < 0, dest_yorg < 0 */
+	int src_crop_left;	/* source image crop left in pixel, used for dest_xorg < 0 */
+	int src_crop_top;	/* source image crop left in pixel, used for dest_yorg < 0 */
+
+	/* source image crop, used for dest_xorg + dest_width > screen_width,
+	   dest_yorg + dest_height > screen_height, FixME: is it neceressary ?? */
+	int src_crop_right;
+	int src_crop_bottom;
+
+	int dest_xorg;		/* destination window x origin, in pixel */
+	int dest_yorg;		/* destination window y origin, in pixel */
+	int dest_width;		/* destination window width,    in pixel */
+	int dest_height;	/* destination window height,   in pixel */
+
+	struct sisfb_video_scale_param * scale_param;
+
+	struct sisfb_info * sisfb;
+
+	/* Virtual function in C++ sense */
+	void (*enable)(struct sisfb_info * sisfb);
+	void (*disable)(struct sisfb_info * sisfb);
+};
+
+#define DEFAULT_OVERLAY_BUFFERS	4
+struct sisfb_overlay_info {
+	struct sisfb_video_info video;
+
+	/* Pointer to the "main" buffer, for different pixel format,
+	 * we need diferent numbers of planes. These buffers reside
+	 * on VRAM */
+	u32 buffer_offset[DEFAULT_OVERLAY_BUFFERS];
+	u32 buffer_offset_p2[DEFAULT_OVERLAY_BUFFERS];
+	u32 buffer_offset_p3[DEFAULT_OVERLAY_BUFFERS];
+
+	u8 num_planes;		/* Number of planes supported by this overlay class,
+				 * 1 for most cases, 3 for YUV 420 Planar overlay */
+
+	/* We can have at most 2 overlay surfaces on two different CRTs
+	 * currently, we will focus on overlay1 on CRT1 case
+	 * FixMe: Are we going to move this to Device Dependent subclass ?? */
+	//enum sisfb_overlay_index overlay;
+	//enum sisfb_monitor_index monitor;
+
+	//enum sisfb_overlay_pixel_format format;
+
+	/* color key */
+	u8 color_key_rop;
+	u8 color_key_red;
+	u8 color_key_green;
+	u8 color_key_blue;
+
+	u8 contrast;
+	u8 brightness;
+
+	/* FixME: members of sisfb_315_overlay_info */
+	u8 alpha;
+	u8 hue;
+	u8 saturation;
+};
+
+#define DEFAULT_SUBPICT_BUFFERS	2
+struct sisfb_subpict_info {
+	struct sisfb_video_info video;
+
+	/* Offset to the buffer for Subpicture data,
+	 * origin at the start of Video RAM */
+	u32 buffer_offset[DEFAULT_SUBPICT_BUFFERS];
+
+	/* 16 color palette (in RGB555) for subpicture */
+	u16 palette[16];
+};
+
+#include <linux/agp_backend.h>
+#define DEFAULT_MPEG_BUFFERS	8
+struct sisfb_mpeg_info {
+	struct sisfb_video_info video;
+
+	/* Offset to the buffer for Slice layer MPEG data,
+	 * origin at the start of AGP memory */
+	u32 buffer_offset[DEFAULT_MPEG_BUFFERS];
+
+	/* AGP info, kernel internal interface */
+	agp_kern_info agp_info;
+	agp_memory * agp_mem;
+
+	/* allocated AGP memory, size, phiscial and virtual address */ 
+	unsigned long agpmem_size_phy;
+	unsigned long agpmem_base_phy;
+	void * agpmem_base_virt;
+
+	/* Video overlay used to display the output of decoded MPEG data
+	 * FixME: 2 overlay pointers for 2 overlay chips ?? */
+	struct sisfb_overlay_info * overlay;
+};
+
+#define log2(n) ffz(~(n))
+
+struct sisfb_video_scale_param {
+	u16 hor_int;
+	u16 hor_fract;
+	u16 ver_int;
+	u16 ver_fract;
+
+	/* Virtual function in C++ sense */
+	void (*calc_scale_param)(struct sisfb_video_scale_param * scale_param,
+				 u32 src_width, u32 src_height,
+				 u32 dest_width, u32 dest_height);
+	void (*set_scale_param)(struct sisfb_video_scale_param * scale_param);
+
+	/* Protected function in C++ sense */
+	void (*video_calc_scale_param)(struct sisfb_video_scale_param * scale_param,
+				       u32 src_width, u32 src_height,
+				       u32 dest_width, u32 dest_height);
+};
+
+struct sisfb_overlay_scale_param {
+	struct sisfb_video_scale_param;
+
+	/* horizontal decimation */
+	u8 hor_preset_int;
+
+	/* DDA Enable, used for Scale >= 1 */
+	u8 hor_dda;
+	u8 ver_dda;
+
+	/* Private function in C++ sense */
+	void (*overlay_calc_scale_param)(struct sisfb_overlay_scale_param * scale_param,
+					 u32 src_width, u32 src_height,
+					 u32 dest_width, u32 dest_height);
+};
+
+struct sisfb_subpict_scale_param {
+	struct sisfb_video_scale_param;
+
+	/* DDA Enable, used for Scale >= 1 */
+	u8 dda_enable;
+
+	/* Private function in C++ sense */
+	void (*subpict_calc_scale_param)(struct sisfb_subpict_scale_param * scale_param,
+					 u32 src_width, u32 src_height,
+					 u32 dest_width, u32 dest_height);
+};
+
+#define SIS_VIDEO_ADDR		0x02
+#define SIS_VIDEO_DATA		0x03
+#define SIS_VIDEO_PASSWORD	0x00
+
+static inline void
+sisfb_set_video_reg(struct sisfb_info * sisfb, u8 index, u8 data)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + SIS_VIDEO_ADDR);
+	outb(data, port + SIS_VIDEO_DATA);
+}
+
+static inline u8
+sisfb_get_video_reg(struct sisfb_info * sisfb, u8 index)
+{
+	u16 port = sisfb->vga_io_base;
+
+	outb(index, port + SIS_VIDEO_ADDR);
+	return inb(port + SIS_VIDEO_DATA);
+}
+
+/**
+ *	sisfb_lock_video_regs: - Lock the Video Acclerator Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Lock Video Acclerator Registers by writing 0x21 (%SIS_PASSWD_LOCK) to
+ *	SIS_VIDEO_PASSWORD register
+ */
+static inline void
+sisfb_lock_video_regs(struct sisfb_info * sisfb)
+{
+	/* lock the access to Video Accelerator Registers */
+	sisfb_set_video_reg(sisfb, SIS_VIDEO_PASSWORD, SIS_PASSWD_LOCK);
+}
+
+/**
+ *	sisfb_unlock_video_regs: - Unlock the Video Acclerator Registers
+ *	@sisfb: SiS Frame Buffer structure
+ *
+ *	Unlock Video Acclerator Registers by writing 0x86 (%SIS_PASSWD_UNLOCK) to
+ *	SIS_VIDEO_PASSWD register
+ */
+static inline void
+sisfb_unlock_video_regs(struct sisfb_info * sisfb)
+{
+	/* unlock the access to Video Accelerator Registers */
+	sisfb_set_video_reg(sisfb, SIS_VIDEO_PASSWORD, SIS_PASSWD_UNLOCK);
+}
+
+extern void sisfb_video_scale_param_init(struct sisfb_video_scale_param * video_param);
+
+#endif /* __SISFB_VIDEO__ */
diff -Nur linux-2.4.21/drivers/video/sis/syncfb.h linux-2.4.21-init_dyn/drivers/video/sis/syncfb.h
--- linux-2.4.21/drivers/video/sis/syncfb.h	Thu Jan  1 08:00:00 1970
+++ linux-2.4.21-init_dyn/drivers/video/sis/syncfb.h	Sun Jun 29 20:40:33 2003
@@ -0,0 +1,284 @@
+#ifndef __LINUX_SYNCFB_H
+#define __LINUX_SYNCFB_H
+
+#ifdef __KERNEL__
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/videodev.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#define SFB_STATUS_FREE 0
+#define SFB_STATUS_OFFS 1
+#define SFB_STATUS_WAIT 2
+#define SFB_STATUS_LIVE 3
+
+#endif /* KERNEL */
+
+
+#ifndef AARONS_TYPES
+typedef unsigned long uint_32;
+typedef unsigned char uint_8;
+#endif
+
+#define SYNCFB_MAJOR 178
+
+#define SYNCFB_ERROR_NO_ERROR                 0;
+#define SYNCFB_ERROR_NO_BUFFER_AVAILABLE      1;
+#define SYNCFB_ERROR_PALETTE_NOT_SUPPORTED    2;
+#define SYNCFB_ERROR_NOT_ENOUGH_MEMORY        3;
+
+
+
+#ifndef __LINUX_VIDEODEV_H
+#define VIDEO_PALETTE_GREY      1       /* Linear greyscale */
+#define VIDEO_PALETTE_HI240     2       /* High 240 cube (BT848) */
+#define VIDEO_PALETTE_RGB565    3       /* 565 16 bit RGB */
+#define VIDEO_PALETTE_RGB24     4       /* 24bit RGB */
+#define VIDEO_PALETTE_RGB32     5       /* 32bit RGB */
+#define VIDEO_PALETTE_RGB555    6       /* 555 15bit RGB */
+#define VIDEO_PALETTE_YUV422    7       /* YUV422 capture */
+#define VIDEO_PALETTE_YUYV      8
+#define VIDEO_PALETTE_UYVY      9       /* The great thing about standards is ... */
+#define VIDEO_PALETTE_YUV420    10
+#define VIDEO_PALETTE_YUV411    11      /* YUV411 capture */
+#define VIDEO_PALETTE_RAW       12      /* RAW capture (BT848) */
+#define VIDEO_PALETTE_YUV422P   13      /* YUV 4:2:2 Planar */
+#define VIDEO_PALETTE_YUV411P   14      /* YUV 4:1:1 Planar */
+#define VIDEO_PALETTE_YUV420P   15      /* YUV 4:2:0 Planar */
+#define VIDEO_PALETTE_YUV410P   16      /* YUV 4:1:0 Planar */
+#define VIDEO_PALETTE_PLANAR    13      /* start of planar entries */
+#define VIDEO_PALETTE_COMPONENT 7       /* start of component entries */
+#endif
+
+
+#define VIDEO_PALETTE_YUV422P3  13      /* YUV 4:2:2 Planar (3 Plane, same as YUV422P) */
+#define VIDEO_PALETTE_YUV422P2  17      /* YUV 4:2:2 Planar (2 Plane) */
+
+#define VIDEO_PALETTE_YUV411P3  14      /* YUV 4:1:1 Planar (3 Plane, same as YUV411P) */
+#define VIDEO_PALETTE_YUV411P2  18      /* YUV 4:1:1 Planar (2 Plane) */
+
+#define VIDEO_PALETTE_YUV420P3  15      /* YUV 4:2:0 Planar (3 Plane, same as YUV420P) */
+#define VIDEO_PALETTE_YUV420P2  19      /* YUV 4:2:0 Planar (2 Plane) */
+
+#define VIDEO_PALETTE_YUV410P3  16      /* YUV 4:1:0 Planar (3 Plane, same as YUV410P) */
+#define VIDEO_PALETTE_YUV410P2  20      /* YUV 4:1:0 Planar (2 Plane) */
+
+
+
+#define SYNCFB_FEATURE_SCALE_H           1
+#define SYNCFB_FEATURE_SCALE_V           2
+#define SYNCFB_FEATURE_SCALE             3
+#define SYNCFB_FEATURE_CROP              4 
+#define SYNCFB_FEATURE_OFFSET            8
+#define SYNCFB_FEATURE_DEINTERLACE      16 
+#define SYNCFB_FEATURE_PROCAMP          32 
+#define SYNCFB_FEATURE_TRANSITIONS      64 
+#define SYNCFB_FEATURE_COLKEY          128 
+#define SYNCFB_FEATURE_MIRROR_H        256 
+#define SYNCFB_FEATURE_MIRROR_V        512 
+#define SYNCFB_FEATURE_BLOCK_REQUEST  1024 
+#define SYNCFB_FEATURE_FREQDIV2       2048 
+
+
+typedef struct syncfb_config_s
+{
+	uint_32 syncfb_mode;		/* bitfield: turn on/off the available features */
+	uint_32 error_code;		/* RO: returns 0 on successful config calls, error code otherwise */
+
+	uint_32 fb_screen_size;		/* WO, size in bytes of video memory reserved for fbdev */
+	uint_32 fb_screen_width;	/* WO, visible screen width in pixel */
+	uint_32 fb_screen_height;	/* WO, visible screen height in pixel */
+
+	uint_32 buffers;		/* RO, number of available buffers */
+	uint_32 buffer_size;		/* RO, filled in by syncfb */
+
+	uint_32 default_repeat; 	/* default repeat time for a single frame, can be overridden in syncfb_buffer_info_t */
+
+	uint_32 src_width;		/* source image width in pixel */
+	uint_32 src_height;		/* source image height in pixel */
+	uint_32 src_palette;		/* set palette mode, see videodev.h for palettes */
+	uint_32 src_pitch;		/* RO: filled in by ioctl: actual line length in pixel */
+
+	uint_32 image_xorg;		/* x position of the image on the screen */
+	uint_32 image_yorg;		/* y position of the image on the screen */
+
+	/* if syncfb has FEATURE_SCALE */
+	uint_32 scale_filters;		/* 0: no filtering, 255: all filters on */
+	uint_32 image_width;		/* onscreen image width */
+	uint_32 image_height;		/* onscreen image height */
+	
+	/* if syncfb has FEATURE_CROP */
+	uint_32 src_crop_left;		/* */
+	uint_32 src_crop_right;		/* */
+	uint_32 src_crop_top;		/* */
+	uint_32 src_crop_bot;		/* */
+
+	/* if syncfb has FEATURE_OFFSET */
+	uint_32 image_offset_left;	/* */
+	uint_32 image_offset_right;	/* */
+	uint_32 image_offset_top;	/* */
+	uint_32 image_offset_bot;	/* */
+
+	/* if syncfb has FEATURE_COLKEY */
+	uint_8  colkey_red;
+	uint_8  colkey_green;
+	uint_8  colkey_blue;
+
+} syncfb_config_t;
+
+
+/*
+	picture parameters,
+*/
+typedef struct syncfb_param_s
+{
+	/* the idea is to enable smooth transitions between eg. image sizes (not yet implemented) */
+	/* if syncfb has FEATURE_TRANSITIONS */
+	uint_32 transition_time;
+
+	/* if syncfb has FEATURE_PROCAMP */
+	uint_32 contrast;		/* 0: least contrast, 1000: normal contrast,  */
+	uint_32 brightness;
+	uint_32 color;       /*  = saturation: for syncfb_matrox: color=0: b/w else: full color */
+
+	/* if syncfb has FEATURE_SCALE , currently only supported in CONFIG call */
+	uint_8  scale_filters;  /* 0: no filtering, 255: all filters on */
+	uint_32 image_xorg;     /* x position of the image on the screen */
+	uint_32 image_yorg;     /* y position of the image on the screen */
+	uint_32 image_width;    /* onscreen image width */
+	uint_32 image_height;   /* onscreen image height */
+
+} syncfb_param_t;
+
+
+
+typedef struct syncfb_status_info_s
+{
+	uint_32 field_cnt;			/* basically all vbi's since the start of syncfb */
+	uint_32 frame_cnt;			/* number of frames comitted & output */
+
+	uint_32 hold_field_cnt;			/* number of repeated fields becaus no new data was available */
+	uint_32 skip_field_cnt;			/* skipped fields when fifo was about to fill up */
+
+	uint_32 request_frames;			/* number of request_buffer calls */
+	uint_32 commit_frames; 			/* number of commit_buffer calls */
+	
+	uint_32 failed_requests;		/* number of calls to request_buffer that failed */
+
+	uint_32 buffers_waiting;
+	uint_32 buffers_free;
+
+} syncfb_status_info_t;
+
+
+
+
+typedef struct syncfb_capability_s 
+{
+	char name[64];			/* A name for the syncfb ... */
+	uint_32 palettes;		/* supported palettes - see videodev.h for palettes, test the corresponding bit here */
+	uint_32 features;		/* supported features - see SYNCFB_FEATURE_* */
+	uint_32 memory_size;		/* total size of mappable video memory */
+
+} syncfb_capability_t;
+
+
+
+typedef struct syncfb_buffer_info_s
+{
+	int     id;			/* buffer id: a return value of -1 means no buffer available */
+	uint_32 repeat;			/* the buffer will be shown <repeat> times */
+	uint_32 offset;			/* buffer offset from start of video memory */
+	uint_32 offset_p2;		/* yuv plane 2 buffer offset from start of video memory */
+	uint_32 offset_p3;		/* yuv plane 3 buffer offset from start of video memory */
+
+} syncfb_buffer_info_t;
+
+typedef struct syncfb_version_info_s {
+
+    	char name[256];
+
+	uint_32 major;
+	uint_32 minor;
+	uint_32 patch;
+
+
+} syncfb_version_info_t;
+
+
+
+
+
+
+/* get syncfb capabilities */
+#define SYNCFB_GET_CAPS _IOR('J', 1, syncfb_config_t)
+
+#define SYNCFB_GET_CONFIG _IOR('J', 2, syncfb_config_t)
+#define SYNCFB_SET_CONFIG _IOR('J', 3, syncfb_config_t)
+#define SYNCFB_ON     _IO ('J', 4)
+#define SYNCFB_OFF    _IO ('J', 5)
+#define SYNCFB_REQUEST_BUFFER    _IOR ('J', 6, syncfb_buffer_info_t)
+#define SYNCFB_COMMIT_BUFFER    _IOR ('J', 7, syncfb_buffer_info_t)
+#define SYNCFB_STATUS    _IOR ('J', 8, syncfb_status_info_t)
+#define SYNCFB_VBI    _IO ('J', 9)  /* simulate interrupt - debugging only */
+#define SYNCFB_SET_PARAMS _IOR('J', 10, syncfb_param_t)
+#define SYNCFB_GET_PARAMS _IOR('J', 11, syncfb_param_t)
+#define SYNCFB_GET_VERSION _IOR('J', 12, syncfb_version_info_t)
+
+
+
+
+#ifdef __KERNEL__
+
+typedef struct syncfb_device_s
+{
+	syncfb_capability_t *(*capability) (void);
+	void (*enable) (void);
+	void (*disable) (void);
+	void (*cleanup) (void);
+	void (*request_buffer) (syncfb_buffer_info_t *buf);
+	void (*select_buffer) (uint_8 buf_id);
+	int  (*configure) (uint_8 set, syncfb_config_t *config); /* general configuration */
+	int  (*parameter) (uint_8 set, syncfb_param_t *param); /* runtime parameters */
+	int  (*ioctl) (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); /* optional: can be NULL */
+	int  (*mmap) (struct file *file, struct vm_area_struct *vma);
+
+} syncfb_device_t;
+
+
+int syncfb_interrupt(void);
+uint_8 syncfb_get_bpp(uint_8 pal);
+ 
+/*
+	SUPPORTED HARDWARE
+*/
+#ifdef SYNCFB_MATROX_SUPPORT
+syncfb_device_t *syncfb_get_matrox_device(void);
+#endif
+
+#ifdef SYNCFB_GENERIC_SUPPORT
+syncfb_device_t *syncfb_get_generic_device(void); 
+#endif
+
+#endif /* KERNEL */
+#endif /* __LINUX_SYNCFB_H */
+
