mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] vmwarefb 0.6.0
@ 2002-05-19  9:25 Denis Oliver Kropp
  0 siblings, 0 replies; only message in thread
From: Denis Oliver Kropp @ 2002-05-19  9:25 UTC (permalink / raw)
  To: Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 875 bytes --]

Hi,

this is an updated version of the VMware SVGA framebuffer driver.
I added console acceleration for clears and moves, removed all
VGA code (not needed at all in SVGA mode) and did a "Lindent" ;)

The patch applies against Linux 2.4.19-pre8.


Unfortunately acceleration can only be disabled at init time via
kernel/module parameter 'noaccel' (video=vmware:noaccel).
Once acceleration is enabled only a Power Off can reset the virtual
hardware for unaccelerated usage. It's a limitation of all currently
available VMware versions (including Workstation 3.1).

Accelerated text drawing will soon be added.

-- 
Best regards,
  Denis Oliver Kropp

.------------------------------------------.
| DirectFB - Hardware accelerated graphics |
| http://www.directfb.org/                 |
"------------------------------------------"

                            Convergence GmbH

[-- Attachment #2: vmwarefb-0.6.0-linux-2.4.19-pre8.patch --]
[-- Type: text/plain, Size: 60383 bytes --]

diff -uraN linux-2.4.19-pre8/CREDITS linux/CREDITS
--- linux-2.4.19-pre8/CREDITS	Tue May 14 05:10:51 2002
+++ linux/CREDITS	Tue May 14 05:11:35 2002
@@ -1660,7 +1660,7 @@
 
 N: Denis O. Kropp
 E: dok@directfb.org
-D: NeoMagic framebuffer driver
+D: NeoMagic and VMware framebuffer driver
 S: Badensche Str. 46
 S: 10715 Berlin
 S: Germany
diff -uraN linux-2.4.19-pre8/drivers/video/Config.in linux/drivers/video/Config.in
--- linux-2.4.19-pre8/drivers/video/Config.in	Tue May 14 05:11:09 2002
+++ linux/drivers/video/Config.in	Tue May 14 01:37:48 2002
@@ -147,6 +147,7 @@
 	    bool '    SIS 315H/315 support' CONFIG_FB_SIS_315
 	 fi
 	 tristate '  NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
+	 tristate '  VMware SVGA display support (EXPERIMENTAL)' CONFIG_FB_VMWARE_SVGA
 	 tristate '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
 	 tristate '  3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
 	 tristate '  Trident support (EXPERIMENTAL)' CONFIG_FB_TRIDENT
@@ -274,7 +275,8 @@
 	   "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
 	   "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
 	   "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
-	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
+	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
+	   "$CONFIG_FB_VMWARE_SVGA" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB8 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
@@ -295,7 +297,8 @@
 	      "$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
 	      "$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" ]; then
+	      "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
+	      "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
       fi
@@ -313,7 +316,7 @@
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y"  -o \
 	   "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
 	   "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
-	   "$CONFIG_FB_NEOMAGIC" = "y" ]; then
+	   "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_VMWARE_SVGA" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
@@ -330,7 +333,7 @@
 	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
 	      "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
-	      "$CONFIG_FB_NEOMAGIC" = "m" ]; then
+	      "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB16 m
 	 fi
       fi
@@ -339,7 +342,8 @@
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
            "$CONFIG_FB_ATY128" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
-	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
+	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
+	   "$CONFIG_FB_VMWARE_SVGA" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB24 y
       else
 	 if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
@@ -347,7 +351,8 @@
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
 	      "$CONFIG_FB_ATY128" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_PVR2" = "m" -o \
-	      "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
+	      "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
+	      "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB24 m
 	 fi
       fi
@@ -361,7 +366,7 @@
 	   "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
 	   "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
-	   "$CONFIG_FB_VOODOO1" = "y" ]; then
+	   "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_VMWARE_SVGA" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB32 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
@@ -373,7 +378,8 @@
 	      "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
 	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
-	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" ]; then
+	      "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
+	      "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB32 m
 	 fi
       fi
diff -uraN linux-2.4.19-pre8/drivers/video/Makefile linux/drivers/video/Makefile
--- linux-2.4.19-pre8/drivers/video/Makefile	Tue May 14 05:11:09 2002
+++ linux/drivers/video/Makefile	Mon May 13 22:25:41 2002
@@ -99,6 +99,11 @@
 obj-y				  += riva/rivafb.o
 endif
 
+subdir-$(CONFIG_FB_VMWARE_SVGA)	  += vmware
+ifeq ($(CONFIG_FB_VMWARE_SVGA),y)
+obj-y				  += vmware/vmware.o
+endif
+
 subdir-$(CONFIG_FB_SIS)		  += sis
 ifeq ($(CONFIG_FB_SIS),y)
 obj-y				  += sis/sisfb.o
diff -uraN linux-2.4.19-pre8/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- linux-2.4.19-pre8/drivers/video/fbmem.c	Tue May 14 05:11:09 2002
+++ linux/drivers/video/fbmem.c	Mon May 13 02:57:15 2002
@@ -76,6 +76,8 @@
 extern int aty128fb_setup(char*);
 extern int neofb_init(void);
 extern int neofb_setup(char*);
+extern int vmwarefb_init(void);
+extern int vmwarefb_setup(char*);
 extern int igafb_init(void);
 extern int igafb_setup(char*);
 extern int imsttfb_init(void);
@@ -187,6 +189,9 @@
 #endif
 #ifdef CONFIG_FB_NEOMAGIC
 	{ "neo", neofb_init, neofb_setup },
+#endif
+#ifdef CONFIG_FB_VMWARE_SVGA
+	{ "vmware", vmwarefb_init, vmwarefb_setup },
 #endif
 #ifdef CONFIG_FB_VIRGE
 	{ "virge", virgefb_init, virgefb_setup },
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/Makefile linux/drivers/video/vmware/Makefile
--- linux-2.4.19-pre8/drivers/video/vmware/Makefile	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/Makefile	Mon May 13 22:26:27 2002
@@ -0,0 +1,15 @@
+#
+# Makefile for the VMware SVGA framebuffer driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := vmware.o
+
+obj-y    := vmwarefb.o
+obj-m    := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/guest_os.h linux/drivers/video/vmware/guest_os.h
--- linux-2.4.19-pre8/drivers/video/vmware/guest_os.h	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/guest_os.h	Tue May 14 01:32:04 2002
@@ -0,0 +1,27 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/guest_os.h,v 1.1 2001/04/05 19:29:44 dawes Exp $ */
+/* *********************************************************
+ * Copyright (C) 1999-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: guest_os.h,v 1.5 2001/01/26 23:32:15 yoel Exp $
+ * **********************************************************/
+
+#ifndef _GUEST_OS_H_
+#define _GUEST_OS_H_
+
+#define GUEST_OS_BASE  0x5000
+
+#define GUEST_OS_DOS        (GUEST_OS_BASE+1)
+#define GUEST_OS_WIN31      (GUEST_OS_BASE+2)
+#define GUEST_OS_WINDOWS95  (GUEST_OS_BASE+3)
+#define GUEST_OS_WINDOWS98  (GUEST_OS_BASE+4)
+#define GUEST_OS_WINDOWSME  (GUEST_OS_BASE+5)
+#define GUEST_OS_NT         (GUEST_OS_BASE+6)
+#define GUEST_OS_WIN2000    (GUEST_OS_BASE+7)
+#define GUEST_OS_LINUX      (GUEST_OS_BASE+8)
+#define GUEST_OS_OS2        (GUEST_OS_BASE+9)
+#define GUEST_OS_OTHER      (GUEST_OS_BASE+10)
+#define GUEST_OS_FREEBSD    (GUEST_OS_BASE+11)
+#define GUEST_OS_WHISTLER   (GUEST_OS_BASE+12)
+
+
+#endif 
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/svga_limits.h linux/drivers/video/vmware/svga_limits.h
--- linux-2.4.19-pre8/drivers/video/vmware/svga_limits.h	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/svga_limits.h	Tue May 14 01:31:47 2002
@@ -0,0 +1,53 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_limits.h,v 1.1 2001/04/05 19:29:44 dawes Exp $ */
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * Id: svga_limits.h,v 1.8 2001/01/26 23:32:15 yoel Exp $
+ * **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ * SVGA limits
+ */
+
+#ifndef _SVGA_LIMITS_H_
+#define _SVGA_LIMITS_H_
+
+/*
+ * Location and size of SVGA frame buffer.
+ */
+#define SVGA_FB_MAX_SIZE       (16*1024*1024)
+#define SVGA_MEM_SIZE          (256*1024)
+
+/*
+ * SVGA_FB_START is the default starting address of the SVGA frame
+ * buffer in the guest's physical address space.
+ * SVGA_FB_START_BIGMEM is the starting address of the SVGA frame
+ * buffer for VMs that have a large amount of physical memory.
+ *
+ * The address of SVGA_FB_START is set to 2GB - (SVGA_FB_MAX_SIZE + SVGA_MEM_SIZE), 
+ * thus the SVGA frame buffer sits at [SVGA_FB_START .. 2GB-1] in the
+ * physical address space.  Our older SVGA drivers for NT treat the
+ * address of the frame buffer as a signed integer.  For backwards
+ * compatibility, we keep the default location of the frame buffer
+ * at under 2GB in the address space.  This restricts VMs to have "only"
+ * up to ~2031MB (i.e., up to SVGA_FB_START) of physical memory.
+ *
+ * For VMs that want more memory than the ~2031MB, we place the SVGA
+ * frame buffer at SVGA_FB_START_BIGMEM.  This allows VMs to have up
+ * to 3584MB, at least as far as the SVGA frame buffer is concerned
+ * (note that there may be other issues that limit the VM memory
+ * size).  PCI devices use high memory addresses, so we have to put
+ * SVGA_FB_START_BIGMEM low enough so that it doesn't overlap with any
+ * of these devices.  Placing SVGA_FB_START_BIGMEM at 0xE0000000
+ * should leave plenty of room for the PCI devices.
+ *
+ * NOTE: All of that is only true for the 0710 chipset.  As of the 0405
+ * chipset, the framebuffer start is determined solely based on the value
+ * the guest BIOS or OS programs into the PCI base address registers.
+ */
+#define SVGA_FB_LEGACY_START		0x7EFC0000
+#define SVGA_FB_LEGACY_START_BIGMEM	0xE0000000
+
+#endif
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/svga_reg.h linux/drivers/video/vmware/svga_reg.h
--- linux-2.4.19-pre8/drivers/video/vmware/svga_reg.h	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/svga_reg.h	Tue May 14 01:31:27 2002
@@ -0,0 +1,298 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/vmware/svga_reg.h,v 1.4 2001/09/13 08:36:24 alanh Exp $ */
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * $Id: svga_reg.h,v 1.16 2001/07/25 22:41:24 mgoodman Exp $
+ * **********************************************************/
+
+/*
+ * svga_reg.h --
+ *
+ * SVGA hardware definitions
+ */
+
+#ifndef _SVGA_REG_H_
+#define _SVGA_REG_H_
+
+#include "svga_limits.h"
+
+/*
+ * Memory and port addresses and fundamental constants
+ */
+
+#define SVGA_MAX_WIDTH			2364
+#define SVGA_MAX_HEIGHT			1773
+
+#ifdef VMX86_SERVER
+#define SVGA_DEFAULT_MAX_WIDTH		1600
+#define SVGA_DEFAULT_MAX_HEIGHT		1200
+#else
+#define SVGA_DEFAULT_MAX_WIDTH		SVGA_MAX_WIDTH
+#define SVGA_DEFAULT_MAX_HEIGHT		SVGA_MAX_HEIGHT
+#endif
+
+#define SVGA_MAX_BITS_PER_PIXEL		32
+#if SVGA_MAX_WIDTH * SVGA_MAX_HEIGHT * SVGA_MAX_BITS_PER_PIXEL / 8 > \
+    SVGA_FB_MAX_SIZE
+#error "Bad SVGA maximum sizes"
+#endif
+#define SVGA_MAX_PSEUDOCOLOR_DEPTH	8
+#define SVGA_MAX_PSEUDOCOLORS		(1 << SVGA_MAX_PSEUDOCOLOR_DEPTH)
+
+#define SVGA_MAGIC         0x900000
+#define SVGA_MAKE_ID(ver)  (SVGA_MAGIC << 8 | (ver))
+
+/* Version 2 let the address of the frame buffer be unsigned on Win32 */
+#define SVGA_VERSION_2     2
+#define SVGA_ID_2          SVGA_MAKE_ID(SVGA_VERSION_2)
+
+/* Version 1 has new registers starting with SVGA_REG_CAPABILITIES so
+   PALETTE_BASE has moved */
+#define SVGA_VERSION_1     1
+#define SVGA_ID_1          SVGA_MAKE_ID(SVGA_VERSION_1)
+
+/* Version 0 is the initial version */
+#define SVGA_VERSION_0     0
+#define SVGA_ID_0          SVGA_MAKE_ID(SVGA_VERSION_0)
+
+/* Invalid SVGA_ID_ */
+#define SVGA_ID_INVALID    0xFFFFFFFF
+
+/* More backwards compatibility, old location of color map: */
+#define SVGA_OLD_PALETTE_BASE	 17
+
+/* Base and Offset gets us headed the right way for PCI Base Addr Registers */
+#define SVGA_LEGACY_BASE_PORT	0x4560
+#define SVGA_INDEX_PORT		0x0
+#define SVGA_VALUE_PORT		0x1
+#define SVGA_BIOS_PORT		0x2
+#define SVGA_NUM_PORTS		0x3
+
+/* This port is deprecated, but retained because of old drivers. */
+#define SVGA_LEGACY_ACCEL_PORT	0x3
+
+/* Legal values for the SVGA_REG_CURSOR_ON register in cursor bypass mode */
+#define SVGA_CURSOR_ON_HIDE               0x0    /* Must be 0 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_SHOW               0x1    /* Must be 1 to maintain backward compatibility */
+#define SVGA_CURSOR_ON_REMOVE_FROM_FB     0x2    /* Remove the cursor from the framebuffer because we need to see what's under it */
+#define SVGA_CURSOR_ON_RESTORE_TO_FB      0x3    /* Put the cursor back in the framebuffer so the user can see it */
+
+/*
+ * Registers
+ */
+
+enum {
+   SVGA_REG_ID = 0,
+   SVGA_REG_ENABLE = 1,
+   SVGA_REG_WIDTH = 2,
+   SVGA_REG_HEIGHT = 3,
+   SVGA_REG_MAX_WIDTH = 4,
+   SVGA_REG_MAX_HEIGHT = 5,
+   SVGA_REG_DEPTH = 6,
+   SVGA_REG_BITS_PER_PIXEL = 7,     /* Current bpp in the guest */
+   SVGA_REG_PSEUDOCOLOR = 8,
+   SVGA_REG_RED_MASK = 9,
+   SVGA_REG_GREEN_MASK = 10,
+   SVGA_REG_BLUE_MASK = 11,
+   SVGA_REG_BYTES_PER_LINE = 12,
+   SVGA_REG_FB_START = 13,
+   SVGA_REG_FB_OFFSET = 14,
+   SVGA_REG_FB_MAX_SIZE = 15,
+   SVGA_REG_FB_SIZE = 16,
+
+   SVGA_REG_CAPABILITIES = 17,
+   SVGA_REG_MEM_START = 18,	   /* Memory for command FIFO and bitmaps */
+   SVGA_REG_MEM_SIZE = 19,
+   SVGA_REG_CONFIG_DONE = 20,      /* Set when memory area configured */
+   SVGA_REG_SYNC = 21,             /* Write to force synchronization */
+   SVGA_REG_BUSY = 22,             /* Read to check if sync is done */
+   SVGA_REG_GUEST_ID = 23,	   /* Set guest OS identifier */
+   SVGA_REG_CURSOR_ID = 24,	   /* ID of cursor */
+   SVGA_REG_CURSOR_X = 25,	   /* Set cursor X position */
+   SVGA_REG_CURSOR_Y = 26,	   /* Set cursor Y position */
+   SVGA_REG_CURSOR_ON = 27,	   /* Turn cursor on/off */
+   SVGA_REG_HOST_BITS_PER_PIXEL = 28, /* Current bpp in the host */
+
+   SVGA_REG_TOP = 30,		   /* Must be 1 greater than the last register */
+
+   SVGA_PALETTE_BASE = 1024	   /* Base of SVGA color map */ 
+};
+
+
+/*
+ *  Capabilities
+ */
+
+#define	SVGA_CAP_RECT_FILL	 0x0001
+#define	SVGA_CAP_RECT_COPY	 0x0002
+#define	SVGA_CAP_RECT_PAT_FILL   0x0004
+#define	SVGA_CAP_OFFSCREEN       0x0008
+#define	SVGA_CAP_RASTER_OP	 0x0010
+#define	SVGA_CAP_CURSOR		 0x0020
+#define	SVGA_CAP_CURSOR_BYPASS	 0x0040
+#define	SVGA_CAP_CURSOR_BYPASS_2 0x0080
+#define	SVGA_CAP_8BIT_EMULATION  0x0100
+#define SVGA_CAP_ALPHA_CURSOR    0x0200
+
+
+/*
+ *  Raster op codes (same encoding as X) used by FIFO drivers.
+ */
+
+#define SVGA_ROP_CLEAR          0x00     /* 0 */
+#define SVGA_ROP_AND            0x01     /* src AND dst */
+#define SVGA_ROP_AND_REVERSE    0x02     /* src AND NOT dst */
+#define SVGA_ROP_COPY           0x03     /* src */
+#define SVGA_ROP_AND_INVERTED   0x04     /* NOT src AND dst */
+#define SVGA_ROP_NOOP           0x05     /* dst */
+#define SVGA_ROP_XOR            0x06     /* src XOR dst */
+#define SVGA_ROP_OR             0x07     /* src OR dst */
+#define SVGA_ROP_NOR            0x08     /* NOT src AND NOT dst */
+#define SVGA_ROP_EQUIV          0x09     /* NOT src XOR dst */
+#define SVGA_ROP_INVERT         0x0a     /* NOT dst */
+#define SVGA_ROP_OR_REVERSE     0x0b     /* src OR NOT dst */
+#define SVGA_ROP_COPY_INVERTED  0x0c     /* NOT src */
+#define SVGA_ROP_OR_INVERTED    0x0d     /* NOT src OR dst */
+#define SVGA_ROP_NAND           0x0e     /* NOT src OR NOT dst */
+#define SVGA_ROP_SET            0x0f     /* 1 */
+#define SVGA_ROP_UNSUPPORTED    0x10
+
+#define SVGA_NUM_SUPPORTED_ROPS   16
+#define SVGA_ROP_ALL            0x0000ffff
+
+/*
+ *  Memory area offsets (viewed as an array of 32-bit words)
+ */
+
+/*
+ *  The distance from MIN to MAX must be at least 10K
+ */
+
+#define	 SVGA_FIFO_MIN	      0
+#define	 SVGA_FIFO_MAX	      1
+#define	 SVGA_FIFO_NEXT_CMD   2
+#define	 SVGA_FIFO_STOP	      3
+
+#define	 SVGA_FIFO_USER_DEFINED	    4
+
+/*
+ *  Drawing object ID's, in the range 0 to SVGA_MAX_ID
+ */
+
+#define	 SVGA_MAX_ID	      499
+
+/*
+ *  Macros to compute variable length items (sizes in 32-bit words)
+ */
+
+#define SVGA_BITMAP_SIZE(w,h) ((((w)+31) >> 5) * (h))
+#define SVGA_BITMAP_SCANLINE_SIZE(w) (( (w)+31 ) >> 5)
+#define SVGA_PIXMAP_SIZE(w,h,d) ((( ((w)*(d))+31 ) >> 5) * (h))
+#define SVGA_PIXMAP_SCANLINE_SIZE(w,d) (( ((w)*(d))+31 ) >> 5)
+
+/*
+ *  Increment from one scanline to the next of a bitmap or pixmap
+ */
+#define SVGA_BITMAP_INCREMENT(w) ((( (w)+31 ) >> 5) * sizeof (uint32))
+#define SVGA_PIXMAP_INCREMENT(w,d) ((( ((w)*(d))+31 ) >> 5) * sizeof (uint32))
+
+/*
+ *  Commands in the command FIFO
+ */
+
+#define	 SVGA_CMD_UPDATE		   1
+	 /* FIFO layout:
+	    X, Y, Width, Height */
+
+#define	 SVGA_CMD_RECT_FILL		   2
+	 /* FIFO layout:
+	    Color, X, Y, Width, Height */
+
+#define	 SVGA_CMD_RECT_COPY		   3
+	 /* FIFO layout:
+	    Source X, Source Y, Dest X, Dest Y, Width, Height */
+
+#define	 SVGA_CMD_DEFINE_BITMAP		   4
+	 /* FIFO layout:
+	    Pixmap ID, Width, Height, <scanlines> */
+
+#define	 SVGA_CMD_DEFINE_BITMAP_SCANLINE   5
+	 /* FIFO layout:
+	    Pixmap ID, Width, Height, Line #, scanline */
+
+#define	 SVGA_CMD_DEFINE_PIXMAP		   6
+	 /* FIFO layout:
+	    Pixmap ID, Width, Height, Depth, <scanlines> */
+
+#define	 SVGA_CMD_DEFINE_PIXMAP_SCANLINE   7
+	 /* FIFO layout:
+	    Pixmap ID, Width, Height, Depth, Line #, scanline */
+
+#define	 SVGA_CMD_RECT_BITMAP_FILL	   8
+	 /* FIFO layout:
+	    Bitmap ID, X, Y, Width, Height, Foreground, Background */
+
+#define	 SVGA_CMD_RECT_PIXMAP_FILL	   9
+	 /* FIFO layout:
+	    Pixmap ID, X, Y, Width, Height */
+
+#define	 SVGA_CMD_RECT_BITMAP_COPY	  10
+	 /* FIFO layout:
+	    Bitmap ID, Source X, Source Y, Dest X, Dest Y,
+	    Width, Height, Foreground, Background */
+
+#define	 SVGA_CMD_RECT_PIXMAP_COPY	  11
+	 /* FIFO layout:
+	    Pixmap ID, Source X, Source Y, Dest X, Dest Y, Width, Height */
+
+#define	 SVGA_CMD_FREE_OBJECT		  12
+	 /* FIFO layout:
+	    Object (pixmap, bitmap, ...) ID */
+
+#define	 SVGA_CMD_RECT_ROP_FILL           13
+         /* FIFO layout:
+            Color, X, Y, Width, Height, ROP */
+
+#define	 SVGA_CMD_RECT_ROP_COPY           14
+         /* FIFO layout:
+            Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
+
+#define	 SVGA_CMD_RECT_ROP_BITMAP_FILL    15
+         /* FIFO layout:
+            ID, X, Y, Width, Height, Foreground, Background, ROP */
+
+#define	 SVGA_CMD_RECT_ROP_PIXMAP_FILL    16
+         /* FIFO layout:
+            ID, X, Y, Width, Height, ROP */
+
+#define	 SVGA_CMD_RECT_ROP_BITMAP_COPY    17
+         /* FIFO layout:
+            ID, Source X, Source Y,
+            Dest X, Dest Y, Width, Height, Foreground, Background, ROP */
+
+#define	 SVGA_CMD_RECT_ROP_PIXMAP_COPY    18
+         /* FIFO layout:
+            ID, Source X, Source Y, Dest X, Dest Y, Width, Height, ROP */
+
+#define	SVGA_CMD_DEFINE_CURSOR		  19
+	/* FIFO layout:
+	   ID, Hotspot X, Hotspot Y, Width, Height,
+	   Depth for AND mask, Depth for XOR mask,
+	   <scanlines for AND mask>, <scanlines for XOR mask> */
+
+#define	SVGA_CMD_DISPLAY_CURSOR		  20
+	/* FIFO layout:
+	   ID, On/Off (1 or 0) */
+
+#define	SVGA_CMD_MOVE_CURSOR		  21
+	/* FIFO layout:
+	   X, Y */
+
+#define SVGA_CMD_DEFINE_ALPHA_CURSOR      22
+	/* FIFO layout:
+	   ID, Hotspot X, Hotspot Y, Width, Height,
+	   <scanlines> */
+
+#define	SVGA_CMD_MAX			  23
+
+#endif
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/vmwarefb.c linux/drivers/video/vmware/vmwarefb.c
--- linux-2.4.19-pre8/drivers/video/vmware/vmwarefb.c	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/vmwarefb.c	Sun May 19 11:05:10 2002
@@ -0,0 +1,1508 @@
+/*
+ * linux/drivers/video/vmwarefb.c -- VMware SVGA Framebuffer Driver
+ *
+ * Copyright (c) 2002  Denis Oliver Kropp <dok@directfb.org>
+ *
+ *
+ * Card specific code is based on XFree86's VMware driver.
+ * Framebuffer framework code is based on code of neofb.
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ *
+ * 0.6.0
+ *  - added accelerated clear and move for console acceleration (dok)
+ *  - removed VGA code that isn't needed at all in SVGA mode (dok)
+ *  - disabling acceleration is only possible after power off via "noaccel" (dok)
+ *  - added a workaround to fix console after running X (dok)
+ *
+ * 0.5.2
+ *  - take care of fb offset, fixes non-standard resolutions (dok)
+ *
+ * 0.5.1
+ *  - fixed undeclared integer when built as a module (dok)
+ *
+ * 0.5.0
+ *  - initial version (dok)
+ *
+ *
+ * TODO
+ * - support for changing bits per pixel (using 8bit emulation capability)
+ * - panning (yet unsupported by WMware)
+ * - disabling accel after bootup (requires yet unreleased VMware above 3.1)
+ *
+ */
+
+#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/pci.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "vmwarefb.h"
+
+#include "svga_reg.h"
+#include "guest_os.h"
+
+#define VMWAREFB_VERSION "0.6.0"
+
+/* --------------------------------------------------------------------- */
+
+static int disabled = 0;
+static int noaccel = 0;
+
+MODULE_AUTHOR("(c) 2002  Denis Oliver Kropp <dok@directfb.org>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FBDev driver for VMware Virtual SVGA Card");
+MODULE_PARM(disabled, "i");
+MODULE_PARM_DESC(disabled, "Disable this driver's initialization.");
+MODULE_PARM(noaccel, "i");
+MODULE_PARM_DESC(noaccel, "Disable console acceleration.");
+
+static struct fb_var_screeninfo __devinitdata vmwarefb_var640x480x8 = {
+	accel_flags:0,
+	xres:640,
+	yres:480,
+	xres_virtual:640,
+	yres_virtual:480,
+	bits_per_pixel:8,
+	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_var_screeninfo __devinitdata vmwarefb_var800x600x8 = {
+	accel_flags:0,
+	xres:800,
+	yres:600,
+	xres_virtual:800,
+	yres_virtual:600,
+	bits_per_pixel:8,
+	pixclock:25000,
+	left_margin:88,
+	right_margin:40,
+	upper_margin:23,
+	lower_margin:1,
+	hsync_len:128,
+	vsync_len:4,
+	sync:FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo __devinitdata vmwarefb_var1024x768x8 = {
+	accel_flags:0,
+	xres:1024,
+	yres:768,
+	xres_virtual:1024,
+	yres_virtual:768,
+	bits_per_pixel:8,
+	pixclock:15385,
+	left_margin:160,
+	right_margin:24,
+	upper_margin:29,
+	lower_margin:3,
+	hsync_len:136,
+	vsync_len:6,
+	sync:FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+	vmode:FB_VMODE_NONINTERLACED
+};
+
+static struct fb_var_screeninfo *vmwarefb_var = &vmwarefb_var800x600x8;
+
+/* ------------------------ VMware specific functions ------------------------ */
+
+static volatile u32
+vmwareReadReg(const struct vmwarefb_info *info, int index)
+{
+	outl(index, info->indexReg);
+
+	return inl(info->valueReg);
+}
+
+static void
+vmwareWriteReg(const struct vmwarefb_info *info, int index, u32 value)
+{
+	outl(index, info->indexReg);
+	outl(value, info->valueReg);
+}
+
+static void
+vmwareWriteWordToFIFO(const struct vmwarefb_info *info, u32 value)
+{
+	u32 *vmwareFIFO = info->vmwareFIFO;
+
+	if (!vmwareFIFO)
+		return;
+
+	/* Need to sync? */
+	if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof (u32) ==
+	     vmwareFIFO[SVGA_FIFO_STOP])
+	    || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] ==
+		vmwareFIFO[SVGA_FIFO_MAX] - sizeof (u32)
+		&& vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) {
+		vmwareWriteReg(info, SVGA_REG_SYNC, 1);
+		while (vmwareReadReg(info, SVGA_REG_BUSY)) ;
+	}
+
+	vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof (u32)] = value;
+	vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof (u32);
+
+	if (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX])
+		vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];
+}
+
+static void
+vmwareWaitForFB(struct vmwarefb_info *info)
+{
+	if (info->vmwareFIFOMarkSet) {
+		vmwareWriteReg(info, SVGA_REG_SYNC, 1);
+
+		while (vmwareReadReg(info, SVGA_REG_BUSY)) ;
+
+		info->vmwareFIFOMarkSet = 0;
+	}
+}
+
+static void
+vmwareSendSVGACmdUpdate(const struct vmwarefb_info *info,
+			int x, int y, int width, int height)
+{
+	vmwareWriteWordToFIFO(info, SVGA_CMD_UPDATE);
+	vmwareWriteWordToFIFO(info, x);
+	vmwareWriteWordToFIFO(info, y);
+	vmwareWriteWordToFIFO(info, width);
+	vmwareWriteWordToFIFO(info, height);
+}
+
+static u32
+vmwareCalculateWeight(u32 mask)
+{
+	u32 weight;
+
+	for (weight = 0; mask; mask >>= 1) {
+		if (mask & 1)
+			weight++;
+	}
+
+	return weight;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMXGetVMwareSvgaId --
+ *
+ *    Retrieve the SVGA_ID of the VMware SVGA adapter.
+ *    This function should hide any backward compatibility mess.
+ *
+ * Results:
+ *    The SVGA_ID_* of the present VMware adapter.
+ *
+ * Side effects:
+ *    ins/outs
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static u32
+VMXGetVMwareSvgaId(const struct vmwarefb_info *info)
+{
+	u32 vmware_svga_id;
+
+	/* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID
+	 * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0.
+	 *
+	 * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register.
+	 *
+	 * Versions of SVGA_ID_1 will allow us to overwrite the content
+	 * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1.
+	 *
+	 * Versions of SVGA_ID_2 will allow us to overwrite the content
+	 * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1
+	 * or SVGA_ID_2.
+	 */
+
+	vmwareWriteReg(info, SVGA_REG_ID, SVGA_ID_2);
+	vmware_svga_id = vmwareReadReg(info, SVGA_REG_ID);
+	if (vmware_svga_id == SVGA_ID_2) {
+		return SVGA_ID_2;
+	}
+
+	vmwareWriteReg(info, SVGA_REG_ID, SVGA_ID_1);
+	vmware_svga_id = vmwareReadReg(info, SVGA_REG_ID);
+	if (vmware_svga_id == SVGA_ID_1) {
+		return SVGA_ID_1;
+	}
+
+	if (vmware_svga_id == SVGA_ID_0) {
+		return SVGA_ID_0;
+	}
+
+	/* No supported VMware SVGA devices found */
+	return SVGA_ID_INVALID;
+}
+
+static void
+VMWAREInitFIFO(struct vmwarefb_info *info)
+{
+	u32 *vmwareFIFO = info->vmwareFIFO;
+
+	if (vmwareFIFO)
+		return;
+
+	vmwareFIFO = (u32 *) info->mmio.vbase;
+
+	vmwareFIFO[SVGA_FIFO_MIN] = 4 * sizeof (u32);
+	vmwareFIFO[SVGA_FIFO_MAX] = info->mmio.len;
+	vmwareFIFO[SVGA_FIFO_NEXT_CMD] = 4 * sizeof (u32);
+	vmwareFIFO[SVGA_FIFO_STOP] = 4 * sizeof (u32);
+
+	info->vmwareFIFO = vmwareFIFO;
+	info->vmwareFIFOMarkSet = 0;
+
+	vmwareWriteReg(info, SVGA_REG_CONFIG_DONE, 1);
+}
+
+static void
+VMWAREStopFIFO(struct vmwarefb_info *info)
+{
+	u32 *vmwareFIFO = info->vmwareFIFO;
+
+	if (!vmwareFIFO)
+		return;
+
+	vmwareWaitForFB(info);
+
+	/* doesn't work in current version of VMware */
+	vmwareWriteReg(info, SVGA_REG_CONFIG_DONE, 0);
+
+	info->vmwareFIFO = NULL;
+}
+
+/* -------------------------- Hardware Acceleration -------------------------- */
+
+static void
+vmware_rectfill(struct vmwarefb_info *info,
+		int x, int y, int width, int height, u32 color)
+{
+	vmwareWriteWordToFIFO(info, SVGA_CMD_RECT_FILL);
+	vmwareWriteWordToFIFO(info, color);
+	vmwareWriteWordToFIFO(info, x);
+	vmwareWriteWordToFIFO(info, y);
+	vmwareWriteWordToFIFO(info, width);
+	vmwareWriteWordToFIFO(info, height);
+
+	info->vmwareFIFOMarkSet = 1;
+
+	vmwareSendSVGACmdUpdate(info, x, y, width, height);
+}
+
+static void
+vmware_accel_setup(struct display *p)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+
+	info->dispsw.setup(p);
+}
+
+static void
+vmware_accel_bmove(struct display *p,
+		   int sy, int sx, int dy, int dx, int height, int width)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+	unsigned int fh, fw;
+
+	fw = fontwidth(p);
+	sx *= fw;
+	dx *= fw;
+	width *= fw;
+
+	fh = fontheight(p);
+	sy *= fh;
+	dy *= fh;
+	height *= fh;
+
+	vmwareWriteWordToFIFO(info, SVGA_CMD_RECT_COPY);
+	vmwareWriteWordToFIFO(info, sx);
+	vmwareWriteWordToFIFO(info, sy);
+	vmwareWriteWordToFIFO(info, dx);
+	vmwareWriteWordToFIFO(info, dy);
+	vmwareWriteWordToFIFO(info, width);
+	vmwareWriteWordToFIFO(info, height);
+
+	info->vmwareFIFOMarkSet = 1;
+
+	vmwareSendSVGACmdUpdate(info, dx, dy, width, height);
+}
+
+static void
+vmware_accel_clear(struct vc_data *conp, struct display *p,
+		   int y, int x, int height, int width)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+	unsigned int fw, fh;
+	u32 bgx = attr_bgcol_ec(p, conp);
+
+	fw = fontwidth(p);
+	x *= fw;
+	width *= fw;
+
+	fh = fontheight(p);
+	y *= fh;
+	height *= fh;
+
+	vmware_rectfill(info, x, y, width, height, bgx);
+}
+
+static void
+vmware_accel_putc(struct vc_data *conp, struct display *p, int c, int y, int x)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+	unsigned int fw, fh;
+
+	fw = fontwidth(p);
+	fh = fontheight(p);
+
+	vmwareWaitForFB(info);
+
+	info->dispsw.putc(conp, p, c, y, x);
+
+	vmwareSendSVGACmdUpdate(info, x * fw, y * fh, fw, fh);
+}
+
+static void
+vmware_accel_putcs(struct vc_data *conp, struct display *p,
+		   const unsigned short *s, int count, int y, int x)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+	unsigned int fw, fh;
+
+	fw = fontwidth(p);
+	fh = fontheight(p);
+
+	vmwareWaitForFB(info);
+
+	info->dispsw.putcs(conp, p, s, count, y, x);
+
+	vmwareSendSVGACmdUpdate(info, x * fw, y * fh, fw * count, fh);
+}
+
+static void
+vmware_accel_revc(struct display *p, int x, int y)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+	unsigned int fw, fh;
+
+	fw = fontwidth(p);
+	fh = fontheight(p);
+
+	vmwareWaitForFB(info);
+
+	info->dispsw.revc(p, x, y);
+
+	vmwareSendSVGACmdUpdate(info, x * fw, y * fh, fw, fh);
+}
+
+static void
+vmware_accel_clear_margins(struct vc_data *conp, struct display *p,
+			   int bottom_only)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) p->fb_info;
+
+	unsigned int right_start = conp->vc_cols * fontwidth(p);
+	unsigned int bottom_start = conp->vc_rows * fontheight(p);
+	unsigned int right_width, bottom_height;
+
+	u32 bgx = attr_bgcol_ec(p, conp);
+
+	if (!bottom_only && (right_width = p->var.xres - right_start))
+		vmware_rectfill(info, right_start, 0,
+				right_width, p->var.yres_virtual, bgx);
+
+	if ((bottom_height = p->var.yres - bottom_start))
+		vmware_rectfill(info, 0, p->var.yoffset + bottom_start,
+				right_start, bottom_height, bgx);
+}
+
+static struct display_switch fbcon_vmware_accel = {
+	setup:vmware_accel_setup,
+	bmove:vmware_accel_bmove,
+	clear:vmware_accel_clear,
+	putc:vmware_accel_putc,
+	putcs:vmware_accel_putcs,
+	revc:vmware_accel_revc,
+	clear_margins:vmware_accel_clear_margins,
+	fontwidthmask:FONTWIDTH(8) | FONTWIDTH(16)
+};
+
+/* --------------------------------------------------------------------- */
+
+/*
+ *    Set a single color register. Return != 0 for invalid regno.
+ */
+static int
+vmware_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+		 u_int transp, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+
+	if (regno >= NR_PALETTE)
+		return -EINVAL;
+
+	info->palette[regno].red = red;
+	info->palette[regno].green = green;
+	info->palette[regno].blue = blue;
+	info->palette[regno].transp = transp;
+
+	switch (fb->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		vmwareWriteReg(info, SVGA_PALETTE_BASE + regno + 0, red >> 8);
+		vmwareWriteReg(info, SVGA_PALETTE_BASE + regno + 1, green >> 8);
+		vmwareWriteReg(info, SVGA_PALETTE_BASE + regno + 2, blue >> 8);
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		if (regno < 16)
+			((u16 *) fb->pseudo_palette)[regno] = ((red & 0xf800)) |
+			    ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		if (regno < 16)
+			((u32 *) fb->pseudo_palette)[regno] =
+			    ((red & 0xff00) << 8) | ((green & 0xff00)) |
+			    ((blue & 0xff00) >> 8);
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		if (regno < 16)
+			((u32 *) fb->pseudo_palette)[regno] =
+			    ((transp & 0xff00) << 16) | ((red & 0xff00) << 8) |
+			    ((green & 0xff00)) | ((blue & 0xff00) >> 8);
+		break;
+#endif
+
+	default:
+		return 1;
+	}
+
+	return 0;
+}
+
+static void
+vmwarefb_set_par(struct vmwarefb_info *info, const struct vmwarefb_par *par)
+{
+	DBG("vmwarefb_set_par");
+
+	vmwareWaitForFB(info);
+
+	/* Write SVGA mode registers */
+	vmwareWriteReg(info, SVGA_REG_WIDTH, par->svga_reg_width);
+	vmwareWriteReg(info, SVGA_REG_HEIGHT, par->svga_reg_height);
+	vmwareWriteReg(info, SVGA_REG_ENABLE, 1);
+	vmwareWriteReg(info, SVGA_REG_CURSOR_ON, 0);
+	vmwareWriteReg(info, SVGA_REG_GUEST_ID, GUEST_OS_LINUX);
+}
+
+static void
+vmwarefb_update_start(struct vmwarefb_info *info, struct fb_var_screeninfo *var)
+{
+}
+
+/*
+ * Set the Colormap
+ */
+static int
+vmwarefb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+	struct display *disp = (con < 0) ? fb->disp : (fb_display + con);
+	struct fb_cmap *dcmap = &disp->cmap;
+	int err = 0;
+
+	/* no colormap allocated? */
+	if (!dcmap->len) {
+		int size;
+
+		if (fb->var.bits_per_pixel == 8)
+			size = NR_PALETTE;
+		else
+			size = 32;
+
+		err = fb_alloc_cmap(dcmap, size, 0);
+	}
+
+	/*
+	 * we should be able to remove this test once fbcon has been
+	 * "improved" --rmk
+	 */
+	if (!err && con == info->currcon) {
+		err = fb_set_cmap(cmap, kspc, vmware_setcolreg, fb);
+		dcmap = &fb->cmap;
+	}
+
+	if (!err)
+		fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
+
+	return err;
+}
+
+static int
+vmwarefb_decode_var(struct fb_var_screeninfo *var,
+		    const struct vmwarefb_info *info, struct vmwarefb_par *par)
+{
+	int memlen, vramlen;
+	unsigned int pixclock = var->pixclock;
+
+	DBG("vmwarefb_decode_var");
+
+	if (!pixclock)
+		pixclock = 10000;	/* 10ns = 100MHz */
+
+	pixclock = 1000000000 / pixclock;
+
+	if (pixclock < 1)
+		pixclock = 1;
+
+	if (pixclock > info->maxClock)
+		return -EINVAL;
+
+	/* No double scan or interlaced support */
+	if (var->vmode & (FB_VMODE_DOUBLE | FB_VMODE_INTERLACED)) {
+		printk(KERN_INFO "vmwarefb: Double scan and interlaced "
+		       "modes are not supported\n");
+		return -EINVAL;
+	}
+
+	/* Is the mode larger than the maximum screen resolution? */
+	if (var->xres > info->maxWidth || var->yres > info->maxHeight) {
+		printk(KERN_INFO
+		       "vmwarefb: Mode (%dx%d) larger than the maximum "
+		       "screen resolution (%dx%d)\n", var->xres, var->yres,
+		       info->maxWidth, info->maxHeight);
+		return -EINVAL;
+	}
+
+	/* The right bits per pixel? (TODO: Add switching support) */
+	if (var->bits_per_pixel != info->hostBitsPerPixel) {
+		printk(KERN_INFO "vmwarefb: %d bits per pixel not supported, "
+		       "only %d bits per pixel available for now\n",
+		       var->bits_per_pixel, info->hostBitsPerPixel);
+		return -EINVAL;
+	}
+
+	/* (TODO: Add virtual resolution support if possible) */
+	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres) {
+		printk(KERN_INFO
+		       "vmwarefb: Virtual resolutions are not supported yet\n");
+		return -EINVAL;
+	}
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		break;
+#endif
+
+	default:
+		return -EINVAL;
+	}
+
+	vramlen = info->video.len;
+
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+
+	memlen =
+	    var->xres_virtual * var->bits_per_pixel * var->yres_virtual / 8;
+	if (memlen > vramlen) {
+		var->yres_virtual =
+		    vramlen * 8 / (var->xres_virtual * var->bits_per_pixel);
+		memlen =
+		    var->xres_virtual * var->bits_per_pixel *
+		    var->yres_virtual / 8;
+	}
+
+	/* we must round yres/xres down, we already rounded y/xres_virtual up
+	   if it was possible. We should return -EINVAL, but I disagree */
+	if (var->yres_virtual < var->yres)
+		var->yres = var->yres_virtual;
+	if (var->xres_virtual < var->xres)
+		var->xres = var->xres_virtual;
+	if (var->xoffset + var->xres > var->xres_virtual)
+		var->xoffset = var->xres_virtual - var->xres;
+	if (var->yoffset + var->yres > var->yres_virtual)
+		var->yoffset = var->yres_virtual - var->yres;
+
+	/*
+	 * SVGA mode registers
+	 */
+	par->svga_reg_width = var->xres;
+	par->svga_reg_height = var->yres;
+
+	return 0;
+}
+
+static int
+vmwarefb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+	struct display *display;
+	struct display_switch *dispsw;
+	struct vmwarefb_par par;
+	int err, chgvar = 0;
+
+	DBG("vmwarefb_set_var");
+
+	err = vmwarefb_decode_var(var, info, &par);
+	if (err)
+		return err;
+
+	if (var->activate & FB_ACTIVATE_TEST)
+		return 0;
+
+	if (con < 0) {
+		display = fb->disp;
+		chgvar = 0;
+	} else {
+		display = fb_display + con;
+
+		if (fb->var.xres != var->xres)
+			chgvar = 1;
+		if (fb->var.yres != var->yres)
+			chgvar = 1;
+		if (fb->var.xres_virtual != var->xres_virtual)
+			chgvar = 1;
+		if (fb->var.yres_virtual != var->yres_virtual)
+			chgvar = 1;
+		if (fb->var.bits_per_pixel != var->bits_per_pixel)
+			chgvar = 1;
+		if (fb->var.accel_flags != var->accel_flags)
+			chgvar = 1;
+
+		/* cannot disable acceleration in current VMware version */
+		if (fb->var.accel_flags && !var->accel_flags) {
+			printk(KERN_INFO "vmwarefb: Acceleration cannot be "
+			       "disabled once it it's initialized\n");
+			return -EINVAL;
+		}
+	}
+
+	if ((info->capabilities & (SVGA_CAP_RECT_FILL | SVGA_CAP_RECT_COPY)) !=
+	    (SVGA_CAP_RECT_FILL | SVGA_CAP_RECT_COPY))
+		var->accel_flags &= ~FB_ACCELF_TEXT;
+
+	if (con == info->currcon) {
+#if 0				/* work around X server, always reinitialize FIFO and mode */
+		if (chgvar || con < 0)
+			vmwarefb_set_par(info, &par);
+#else
+		VMWAREStopFIFO(info);
+		vmwarefb_set_par(info, &par);
+#endif
+
+		vmwarefb_update_start(info, var);
+
+		if (con < 0)
+			fb_copy_cmap(fb_default_cmap
+				     (var->bits_per_pixel >
+				      8 ? 16 : NR_PALETTE), &fb->cmap, 0);
+
+		fb_set_cmap(&fb->cmap, 1, vmware_setcolreg, fb);
+	}
+
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	var->red.length =
+	    vmwareCalculateWeight(vmwareReadReg(info, SVGA_REG_RED_MASK));
+	var->green.length =
+	    vmwareCalculateWeight(vmwareReadReg(info, SVGA_REG_GREEN_MASK));
+	var->blue.length =
+	    vmwareCalculateWeight(vmwareReadReg(info, SVGA_REG_BLUE_MASK));
+	var->red.offset = var->green.length + var->green.offset;
+	var->green.offset = var->blue.length;
+	var->blue.offset = 0;
+
+	fb->fix.line_length = vmwareReadReg(info, SVGA_REG_BYTES_PER_LINE);
+
+	var->red.msb_right = 0;
+	var->green.msb_right = 0;
+	var->blue.msb_right = 0;
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		var->red.length = 8;
+		var->green.length = 8;
+		var->blue.length = 8;
+		var->red.offset = 0;
+		var->green.offset = 0;
+		var->blue.offset = 0;
+
+		fb->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		dispsw = &fbcon_cfb8;
+		display->dispsw_data = NULL;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		fb->fix.visual = FB_VISUAL_TRUECOLOR;
+		dispsw = &fbcon_cfb16;
+		display->dispsw_data = fb->pseudo_palette;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		fb->fix.visual = FB_VISUAL_TRUECOLOR;
+		dispsw = &fbcon_cfb24;
+		display->dispsw_data = fb->pseudo_palette;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		fb->fix.visual = FB_VISUAL_TRUECOLOR;
+		dispsw = &fbcon_cfb32;
+		display->dispsw_data = fb->pseudo_palette;
+		break;
+#endif
+
+	default:
+		printk(KERN_WARNING "vmwarefb: no support for %dbpp\n",
+		       var->bits_per_pixel);
+		dispsw = &fbcon_dummy;
+		var->accel_flags &= ~FB_ACCELF_TEXT;
+		break;
+	}
+
+	/* Copy default console text drawing functions */
+	memcpy(&info->dispsw, dispsw, sizeof (struct display_switch));
+
+	/* Using acceleration? */
+	if (var->accel_flags & FB_ACCELF_TEXT) {
+		VMWAREInitFIFO(info);
+
+		vmwareSendSVGACmdUpdate(info, 0, 0, var->xres, var->yres);
+
+		/* move content */
+		if (chgvar)
+			display->scrollmode = 0;
+
+		/* use accelerated functions */
+		dispsw = &fbcon_vmware_accel;
+	} else {
+		VMWAREStopFIFO(info);
+
+		/* redraw content */
+		display->scrollmode = SCROLL_YREDRAW;
+		info->dispsw.bmove = fbcon_redraw_bmove;
+
+		/* use (modified) default functions */
+		dispsw = &info->dispsw;
+	}
+
+	/* Setup display information */
+	display->dispsw = dispsw;
+	display->screen_base =
+	    fb->screen_base + vmwareReadReg(info, SVGA_REG_FB_OFFSET);
+	display->next_line = display->line_length = fb->fix.line_length;
+	display->visual = fb->fix.visual;
+	display->type = fb->fix.type;
+	display->type_aux = fb->fix.type_aux;
+	display->ypanstep = fb->fix.ypanstep;
+	display->ywrapstep = fb->fix.ywrapstep;
+	display->can_soft_blank = 1;
+	display->inverse = 0;
+
+	/* Update var info */
+	fb->var = *var;
+	fb->var.activate &= ~FB_ACTIVATE_ALL;
+
+	/*
+	 * Update the old var.  The fbcon drivers still use this.
+	 * Once they are using cfb->fb.var, this can be dropped.
+	 *                                    --rmk
+	 */
+	display->var = fb->var;
+
+	/*
+	 * If we are setting all the virtual consoles, also set the
+	 * defaults used to create new consoles.
+	 */
+	if (var->activate & FB_ACTIVATE_ALL)
+		fb->disp->var = fb->var;
+
+	if (chgvar && fb && fb->changevar)
+		fb->changevar(con);
+
+	return 0;
+}
+
+/*
+ *    Pan or Wrap the Display
+ */
+static int
+vmwarefb_pan_display(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+	u_int y_bottom;
+
+	y_bottom = var->yoffset;
+
+	if (!(var->vmode & FB_VMODE_YWRAP))
+		y_bottom += var->yres;
+
+	if (var->xoffset > (var->xres_virtual - var->xres))
+		return -EINVAL;
+	if (y_bottom > fb->var.yres_virtual)
+		return -EINVAL;
+
+	vmwarefb_update_start(info, var);
+
+	fb->var.xoffset = var->xoffset;
+	fb->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		fb->var.vmode |= FB_VMODE_YWRAP;
+	else
+		fb->var.vmode &= ~FB_VMODE_YWRAP;
+
+	return 0;
+}
+
+/*
+ *    Update the `var' structure (called by fbcon.c)
+ *
+ *    This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
+ *    Since it's called by a kernel driver, no range checking is done.
+ */
+static int
+vmwarefb_updatevar(int con, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+
+	vmwarefb_update_start(info, &fb_display[con].var);
+
+	return 0;
+}
+
+static int
+vmwarefb_switch(int con, struct fb_info *fb)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) fb;
+	struct display *disp;
+	struct fb_cmap *cmap;
+
+	if (info->currcon >= 0) {
+		disp = fb_display + info->currcon;
+
+		/*
+		 * Save the old colormap and video mode.
+		 */
+		disp->var = fb->var;
+		if (disp->cmap.len)
+			fb_copy_cmap(&fb->cmap, &disp->cmap, 0);
+	}
+
+	info->currcon = con;
+	disp = fb_display + con;
+
+	/*
+	 * Install the new colormap and change the video mode.  By default,
+	 * fbcon sets all the colormaps and video modes to the default
+	 * values at bootup.
+	 *
+	 * Really, we want to set the colourmap size depending on the
+	 * depth of the new video mode.  For now, we leave it at its
+	 * default 256 entry.
+	 */
+	if (disp->cmap.len)
+		cmap = &disp->cmap;
+	else
+		cmap =
+		    fb_default_cmap(disp->var.bits_per_pixel >
+				    8 ? 16 : NR_PALETTE);
+
+	fb_copy_cmap(cmap, &fb->cmap, 0);
+
+	disp->var.activate = FB_ACTIVATE_NOW;
+	vmwarefb_set_var(&disp->var, con, fb);
+
+	return 0;
+}
+
+/*
+ *    (Un)Blank the display.
+ */
+static void
+vmwarefb_blank(int blank, struct fb_info *fb)
+{
+	//  struct vmwarefb_info *info = (struct vmwarefb_info *)fb;
+
+	/*
+	 *  Blank the screen if blank_mode != 0, else unblank. If
+	 *  blank == NULL then the caller blanks by setting the CLUT
+	 *  (Color Look Up Table) to all black. Return 0 if blanking
+	 *  succeeded, != 0 if un-/blanking failed due to e.g. a
+	 *  video mode which doesn't support it. Implements VESA
+	 *  suspend and powerdown modes on hardware that supports
+	 *  disabling hsync/vsync:
+	 *    blank_mode == 2: suspend vsync
+	 *    blank_mode == 3: suspend hsync
+	 *    blank_mode == 4: powerdown
+	 *
+	 *  wms...Enable VESA DMPS compatible powerdown mode
+	 *  run "setterm -powersave powerdown" to take advantage
+	 */
+
+	switch (blank) {
+	case 4:		/* powerdown - both sync lines down */
+		break;
+	case 3:		/* hsync off */
+		break;
+	case 2:		/* vsync off */
+		break;
+	case 1:		/* just software blanking of screen */
+		break;
+	default:		/* case 0, or anything else: unblank */
+		break;
+	}
+}
+
+/*
+ * Get the currently displayed virtual consoles colormap.
+ */
+static int
+gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *fb)
+{
+	fb_copy_cmap(&fb->cmap, cmap, kspc ? 0 : 2);
+	return 0;
+}
+
+/*
+ * Get the currently displayed virtual consoles fixed part of the display.
+ */
+static int
+gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
+{
+	*fix = fb->fix;
+	return 0;
+}
+
+/*
+ * Get the current user defined part of the display.
+ */
+static int
+gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+	*var = fb->var;
+	return 0;
+}
+
+static struct fb_ops vmwarefb_ops = {
+	owner:THIS_MODULE,
+	fb_set_var:vmwarefb_set_var,
+	fb_set_cmap:vmwarefb_set_cmap,
+	fb_pan_display:vmwarefb_pan_display,
+	fb_get_fix:gen_get_fix,
+	fb_get_var:gen_get_var,
+	fb_get_cmap:gen_get_cmap,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit
+vmware_map_mmio(struct vmwarefb_info *info)
+{
+	DBG("vmware_map_mmio");
+
+	info->mmio.pbase = vmwareReadReg(info, SVGA_REG_MEM_START);
+	info->mmio.len = vmwareReadReg(info, SVGA_REG_MEM_SIZE) & ~3;
+
+	if (!request_mem_region
+	    (info->mmio.pbase, info->mmio.len, "memory mapped I/O")) {
+		printk(KERN_ERR "vmwarefb: memory mapped IO at 0x%08x in use\n",
+		       info->mmio.pbase);
+		return -EBUSY;
+	}
+
+	info->mmio.vbase = ioremap(info->mmio.pbase, info->mmio.len);
+	if (!info->mmio.vbase) {
+		printk(KERN_ERR
+		       "vmwarefb: unable to map memory mapped IO at 0x%08x\n",
+		       info->mmio.pbase);
+		release_mem_region(info->mmio.pbase, info->mmio.len);
+		return -ENOMEM;
+	} else
+		printk(KERN_INFO "vmwarefb: mapped io at 0x%08x -> %p\n",
+		       info->mmio.pbase, info->mmio.vbase);
+
+	info->fb.fix.mmio_start = info->mmio.pbase;
+	info->fb.fix.mmio_len = info->mmio.len;
+
+	return 0;
+}
+
+static void __devexit
+vmware_unmap_mmio(struct vmwarefb_info *info)
+{
+	DBG("vmware_unmap_mmio");
+
+	VMWAREStopFIFO(info);
+
+	if (info->mmio.vbase) {
+		iounmap(info->mmio.vbase);
+		info->mmio.vbase = NULL;
+
+		release_mem_region(info->mmio.pbase, info->mmio.len);
+	}
+}
+
+static int __devinit
+vmware_map_video(struct vmwarefb_info *info)
+{
+	DBG("vmware_map_video");
+
+	info->video.pbase = vmwareReadReg(info, SVGA_REG_FB_START);
+	info->video.len = vmwareReadReg(info, SVGA_REG_FB_MAX_SIZE);
+
+	if (!request_mem_region
+	    (info->video.pbase, info->video.len, "frame buffer")) {
+		printk(KERN_ERR "vmwarefb: frame buffer at 0x%08x in use\n",
+		       info->video.pbase);
+		return -EBUSY;
+	}
+
+	info->video.vbase = ioremap(info->video.pbase, info->video.len);
+	if (!info->video.vbase) {
+		printk(KERN_ERR
+		       "vmwarefb: unable to map screen memory at 0x%08x\n",
+		       info->video.pbase);
+		release_mem_region(info->video.pbase, info->video.len);
+		return -ENOMEM;
+	} else
+		printk(KERN_INFO
+		       "vmwarefb: mapped framebuffer at 0x%08x -> %p\n",
+		       info->video.pbase, info->video.vbase);
+
+	info->fb.fix.smem_start = info->video.pbase;
+	info->fb.fix.smem_len = info->video.len;
+	info->fb.screen_base = info->video.vbase;
+
+	return 0;
+}
+
+static void __devexit
+vmware_unmap_video(struct vmwarefb_info *info)
+{
+	DBG("vmware_unmap_video");
+
+	if (info->video.vbase) {
+		iounmap(info->video.vbase);
+		info->video.vbase = NULL;
+		info->fb.screen_base = NULL;
+
+		release_mem_region(info->video.pbase, info->video.len);
+	}
+}
+
+static int __devinit
+vmware_init_hw(struct vmwarefb_info *info)
+{
+	u32 id;
+
+	DBG("vmware_init_hw");
+
+	/* Figure out SVGA ports */
+	switch (info->accel) {
+	case FB_ACCEL_VMWARE_SVGA:
+		info->indexReg =
+		    SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT * sizeof (u32);
+		info->valueReg =
+		    SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT * sizeof (u32);
+		break;
+
+	case FB_ACCEL_VMWARE_SVGA2:
+		info->indexReg =
+		    pci_resource_start(info->pcidev, 0) + SVGA_INDEX_PORT;
+		info->valueReg =
+		    pci_resource_start(info->pcidev, 0) + SVGA_VALUE_PORT;
+		break;
+	}
+
+	/* Check for supported SVGA id */
+	id = VMXGetVMwareSvgaId(info);
+	if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
+		printk(KERN_ERR "vmwarefb: No supported "
+		       "VMware SVGA found (read ID 0x%08x).\n", id);
+		return -ENOTSUPP;
+	}
+
+	/* Maximum dot clock in kHz */
+	info->maxClock = 400000;
+
+	/* Maximum screen resolution */
+	info->maxWidth = vmwareReadReg(info, SVGA_REG_MAX_WIDTH);
+	info->maxHeight = vmwareReadReg(info, SVGA_REG_MAX_HEIGHT);
+
+	/* Bits per pixel in host format */
+	info->hostBitsPerPixel =
+	    vmwareReadReg(info, SVGA_REG_HOST_BITS_PER_PIXEL);
+
+	/* Capabilities like 8bit emulation */
+	info->capabilities = vmwareReadReg(info, SVGA_REG_CAPABILITIES);
+
+	printk(KERN_INFO
+	       "vmwarefb: Maximum screen resolution is %dx%d, host bpp is %d\n",
+	       info->maxWidth, info->maxHeight, info->hostBitsPerPixel);
+
+	return 0;
+}
+
+static struct vmwarefb_info *__devinit
+vmware_alloc_fb_info(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct vmwarefb_info *info;
+
+	info = kmalloc(sizeof (struct vmwarefb_info) + sizeof (struct display) +
+		       sizeof (u32) * 16, GFP_KERNEL);
+
+	if (!info)
+		return NULL;
+
+	memset(info, 0,
+	       sizeof (struct vmwarefb_info) + sizeof (struct display));
+
+	info->currcon = -1;
+	info->pcidev = dev;
+	info->accel = id->driver_data;
+
+	switch (info->accel) {
+	case FB_ACCEL_VMWARE_SVGA:
+		sprintf(info->fb.fix.id, "VMware SVGA");
+		break;
+
+	case FB_ACCEL_VMWARE_SVGA2:
+		sprintf(info->fb.fix.id, "VMware SVGA2");
+		break;
+	}
+
+	info->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+	info->fb.fix.type_aux = 0;
+	info->fb.fix.xpanstep = 0;
+	info->fb.fix.ypanstep = 0;	/* No virtual resolution support yet */
+	info->fb.fix.ywrapstep = 0;
+	info->fb.fix.accel = id->driver_data;
+
+	info->fb.var.nonstd = 0;
+	info->fb.var.activate = FB_ACTIVATE_NOW;
+	info->fb.var.height = -1;
+	info->fb.var.width = -1;
+	info->fb.var.accel_flags = 0;
+
+	strcpy(info->fb.modename, info->fb.fix.id);
+
+	info->fb.fbops = &vmwarefb_ops;
+	info->fb.changevar = NULL;
+	info->fb.switch_con = vmwarefb_switch;
+	info->fb.updatevar = vmwarefb_updatevar;
+	info->fb.blank = vmwarefb_blank;
+	info->fb.flags = FBINFO_FLAG_DEFAULT;
+	info->fb.disp = (struct display *) (info + 1);
+	info->fb.pseudo_palette = (void *) (info->fb.disp + 1);
+
+	fb_alloc_cmap(&info->fb.cmap, NR_PALETTE, 0);
+
+	return info;
+}
+
+static void __devexit
+vmware_free_fb_info(struct vmwarefb_info *info)
+{
+	if (info) {
+		/*
+		 * Free the colourmap
+		 */
+		fb_alloc_cmap(&info->fb.cmap, 0, 0);
+
+		kfree(info);
+	}
+}
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit
+vmwarefb_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct vmwarefb_info *info;
+	u_int h_sync, v_sync;
+	int err;
+
+	DBG("vmwarefb_probe");
+
+	err = pci_enable_device(dev);
+	if (err)
+		return err;
+
+	err = -ENOMEM;
+	info = vmware_alloc_fb_info(dev, id);
+	if (!info)
+		goto failed;
+
+	err = vmware_init_hw(info);
+	if (err)
+		goto failed;
+
+	err = vmware_map_mmio(info);
+	if (err)
+		goto failed;
+
+	err = vmware_map_video(info);
+	if (err)
+		goto failed;
+
+	/* Use bits per pixel of host */
+	vmwarefb_var->bits_per_pixel = info->hostBitsPerPixel;
+
+	/* Use acceleration? */
+	if (!noaccel)
+		vmwarefb_var->accel_flags = FB_ACCELF_TEXT;
+
+	/* Set initial mode */
+	vmwarefb_set_var(vmwarefb_var, -1, &info->fb);
+
+	/*
+	 * Calculate the hsync and vsync frequencies.  Note that
+	 * we split the 1e12 constant up so that we can preserve
+	 * the precision and fit the results into 32-bit registers.
+	 *  (1953125000 * 512 = 1e12)
+	 */
+	h_sync = 1953125000 / info->fb.var.pixclock;
+	h_sync = h_sync * 512 / (info->fb.var.xres + info->fb.var.left_margin +
+				 info->fb.var.right_margin +
+				 info->fb.var.hsync_len);
+	v_sync =
+	    h_sync / (info->fb.var.yres + info->fb.var.upper_margin +
+		      info->fb.var.lower_margin + info->fb.var.vsync_len);
+
+	printk(KERN_INFO "vmwarefb v" VMWAREFB_VERSION ": "
+	       "%dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
+	       info->fb.fix.smem_len >> 10,
+	       info->fb.var.xres, info->fb.var.yres,
+	       h_sync / 1000, h_sync % 1000, v_sync);
+
+	err = register_framebuffer(&info->fb);
+	if (err < 0)
+		goto failed;
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       GET_FB_IDX(info->fb.node), info->fb.modename);
+
+	/*
+	 * Our driver data
+	 */
+	dev->driver_data = info;
+
+	return 0;
+
+      failed:
+	vmware_unmap_video(info);
+	vmware_unmap_mmio(info);
+	vmware_free_fb_info(info);
+
+	return err;
+}
+
+static void __devexit
+vmwarefb_remove(struct pci_dev *dev)
+{
+	struct vmwarefb_info *info = (struct vmwarefb_info *) dev->driver_data;
+
+	DBG("vmwarefb_remove");
+
+	if (info) {
+		/*
+		 * If unregister_framebuffer fails, then
+		 * we will be leaving hooks that could cause
+		 * oopsen laying around.
+		 */
+		if (unregister_framebuffer(&info->fb))
+			printk(KERN_WARNING
+			       "vmwarefb: danger danger!  Oopsen imminent!\n");
+
+		vmware_unmap_video(info);
+		vmware_unmap_mmio(info);
+		vmware_free_fb_info(info);
+
+		/*
+		 * Ensure that the driver data is no longer
+		 * valid.
+		 */
+		dev->driver_data = NULL;
+	}
+}
+
+static struct pci_device_id vmwarefb_devices[] __devinitdata = {
+	{PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_VMWARE_SVGA},
+
+	{PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_SVGA2,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_VMWARE_SVGA2},
+
+	{0, 0, 0, 0, 0, 0, 0}
+};
+
+MODULE_DEVICE_TABLE(pci, vmwarefb_devices);
+
+static struct pci_driver vmwarefb_driver = {
+	name:"vmwarefb",
+	id_table:vmwarefb_devices,
+	probe:vmwarefb_probe,
+	remove:vmwarefb_remove
+};
+
+/* **************************** init-time only **************************** */
+
+static void __init
+vmware_init(void)
+{
+	DBG("vmware_init");
+	pci_register_driver(&vmwarefb_driver);
+}
+
+/* **************************** exit-time only **************************** */
+
+static void __exit
+vmware_done(void)
+{
+	DBG("vmware_done");
+	pci_unregister_driver(&vmwarefb_driver);
+}
+
+/* ************************* init in-kernel code ************************** */
+
+#ifndef MODULE
+
+static int initialized = 0;
+
+int __init
+vmwarefb_setup(char *options)
+{
+	char *this_opt;
+
+	DBG("vmwarefb_setup");
+
+	if (!options || !*options)
+		return 0;
+
+	for (this_opt = strtok(options, ","); this_opt;
+	     this_opt = strtok(NULL, ",")) {
+		if (!*this_opt)
+			continue;
+
+		if (!strncmp(this_opt, "disabled", 8))
+			disabled = 1;
+		if (!strncmp(this_opt, "noaccel", 8))
+			noaccel = 1;
+		if (!strncmp(this_opt, "640x480", 7))
+			vmwarefb_var = &vmwarefb_var640x480x8;
+		if (!strncmp(this_opt, "800x600", 7))
+			vmwarefb_var = &vmwarefb_var800x600x8;
+		if (!strncmp(this_opt, "1024x768", 8))
+			vmwarefb_var = &vmwarefb_var1024x768x8;
+	}
+
+	return 0;
+}
+
+int __init
+vmwarefb_init(void)
+{
+	DBG("vmwarefb_init");
+
+	if (disabled)
+		return -ENXIO;
+
+	if (!initialized) {
+		initialized = 1;
+		vmware_init();
+	}
+
+	/* never return failure, user can hotplug card later... */
+	return 0;
+}
+
+#else
+
+/* *************************** init module code **************************** */
+
+int __init
+init_module(void)
+{
+	DBG("init_module");
+
+	if (disabled)
+		return -ENXIO;
+
+	vmware_init();
+
+	/* never return failure; user can hotplug card later... */
+	return 0;
+}
+
+#endif				/* MODULE */
+
+module_exit(vmware_done);
diff -uraN linux-2.4.19-pre8/drivers/video/vmware/vmwarefb.h linux/drivers/video/vmware/vmwarefb.h
--- linux-2.4.19-pre8/drivers/video/vmware/vmwarefb.h	Thu Jan  1 01:00:00 1970
+++ linux/drivers/video/vmware/vmwarefb.h	Sun May 19 11:05:18 2002
@@ -0,0 +1,88 @@
+/*
+ * linux/drivers/video/vmwarefb.h -- VMware SVGA Framebuffer Driver
+ *
+ * Copyright (c) 2002  Denis Oliver Kropp <dok@directfb.org>
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License.  See the file COPYING in the main directory of this
+ * archive for more details.
+ */
+
+#ifdef VMWAREFB_DEBUG
+# define DBG(x)		printk (KERN_DEBUG "vmwarefb: %s\n", (x));
+#else
+# define DBG(x)
+#endif
+
+#define PCI_VENDOR_ID_VMWARE        0x15AD
+#define PCI_DEVICE_ID_VMWARE_SVGA2  0x0405
+#define PCI_DEVICE_ID_VMWARE_SVGA   0x0710
+
+/* --------------------------------------------------------------------- */
+
+#define NR_PALETTE	256
+
+struct vmwarefb_par {
+
+	/* SVGA registers */
+	u32 svga_reg_width;
+	u32 svga_reg_height;
+};
+
+struct vmwarefb_info {
+
+	/* Base struct */
+	struct fb_info fb;
+
+	/* Console drawing functions */
+	struct display_switch dispsw;
+
+	/* VMware VGA PCI device */
+	struct pci_dev *pcidev;
+
+	/* Current active console */
+	int currcon;
+
+	/* Accelerator id */
+	int accel;
+
+	/* Video memory */
+	struct {
+		u8 *vbase;
+		u32 pbase;
+		u32 len;
+	} video;
+
+	/* Memory mapped IO for acceleration */
+	struct {
+		u8 *vbase;
+		u32 pbase;
+		u32 len;
+	} mmio;
+
+	/* FIFO handling */
+	u32 *vmwareFIFO;
+	int vmwareFIFOMarkSet;
+
+	/* SVGA ports */
+	u32 indexReg;
+	u32 valueReg;
+
+	/* Maximum screen resolution */
+	int maxWidth;
+	int maxHeight;
+
+	/* Maximum dot clock */
+	int maxClock;
+
+	/* Bits per pixel in host format */
+	unsigned int hostBitsPerPixel;
+
+	/* Capabilities of the virtual card */
+	unsigned int capabilities;
+
+	/* Text color map */
+	struct {
+		u16 red, green, blue, transp;
+	} palette[NR_PALETTE];
+};
diff -uraN linux-2.4.19-pre8/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.4.19-pre8/include/linux/fb.h	Tue May 14 05:11:14 2002
+++ linux/include/linux/fb.h	Tue May 14 01:24:06 2002
@@ -96,6 +96,8 @@
 #define FB_ACCEL_3DLABS_PERMEDIA3 37	/* 3Dlabs Permedia 3		*/
 #define FB_ACCEL_ATI_RADEON	38	/* ATI Radeon family		*/
 
+#define FB_ACCEL_VMWARE_SVGA	50	/* VMware Virtual SVGA Graphics */
+#define FB_ACCEL_VMWARE_SVGA2	51	/* VMware Virtual SVGA Graphics */
 
 #define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
 #define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-05-19  9:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-19  9:25 [PATCH] vmwarefb 0.6.0 Denis Oliver Kropp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®