* [PATCH] vmwarefb 0.6.0 (Linux 2.4.20)
@ 2002-11-29 13:58 Denis Oliver Kropp
0 siblings, 0 replies; only message in thread
From: Denis Oliver Kropp @ 2002-11-29 13:58 UTC (permalink / raw)
To: linux-kernel; +Cc: marcelo
[-- Attachment #1: Type: text/plain, Size: 451 bytes --]
Hi,
this is an updated patch of the vmware framebuffer driver.
Copyright headers are fixed now. Some users asked me to
post this patch here to have it included in the official
tree.
--
Best regards,
Denis Oliver Kropp
.------------------------------------------.
| DirectFB - Hardware accelerated graphics |
| http://www.directfb.org/ |
"------------------------------------------"
Convergence GmbH
[-- Attachment #2: vmwarefb-0.6.0-linux-2.4.20.patch --]
[-- Type: text/plain, Size: 64402 bytes --]
diff -uraN linux-2.4.20/CREDITS linux-2.4.20-vmwarefb/CREDITS
--- linux-2.4.20/CREDITS 2002-11-29 13:18:20.000000000 +0100
+++ linux-2.4.20-vmwarefb/CREDITS 2002-11-29 13:25:32.000000000 +0100
@@ -1688,6 +1688,7 @@
E: dok@directfb.org
D: NeoMagic framebuffer driver
D: CyberPro 32 bit support, fixes
+D: VMware framebuffer driver
S: Badensche Str. 46
S: 10715 Berlin
S: Germany
diff -uraN linux-2.4.20/drivers/video/Config.in linux-2.4.20-vmwarefb/drivers/video/Config.in
--- linux-2.4.20/drivers/video/Config.in 2002-11-29 13:18:42.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/Config.in 2002-11-29 13:28:40.000000000 +0100
@@ -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
@@ -292,7 +293,8 @@
"$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" -o \
- "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" ]; then
+ "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "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 \
@@ -314,7 +316,7 @@
"$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" -o \
- "$CONFIG_FB_STI" = "m" ]; then
+ "$CONFIG_FB_STI" = "m" -o "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m
fi
fi
@@ -332,7 +334,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 \
@@ -349,7 +351,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
@@ -358,7 +360,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" -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 \
@@ -366,7 +369,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" = "m" ]; then
+ "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
+ "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
define_tristate CONFIG_FBCON_CFB24 m
fi
fi
@@ -381,7 +385,7 @@
"$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
- "$CONFIG_FB_STI" = "y" ]; then
+ "$CONFIG_FB_STI" = "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 \
@@ -394,7 +398,8 @@
"$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" -o \
- "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_STI" = "y" ]; then
+ "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_STI" = "y" -o \
+ "$CONFIG_FB_VMWARE_SVGA" = "m" ]; then
define_tristate CONFIG_FBCON_CFB32 m
fi
fi
diff -uraN linux-2.4.20/drivers/video/Makefile linux-2.4.20-vmwarefb/drivers/video/Makefile
--- linux-2.4.20/drivers/video/Makefile 2002-11-29 13:18:42.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/Makefile 2002-11-29 13:24:53.000000000 +0100
@@ -107,6 +107,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.20/drivers/video/fbmem.c linux-2.4.20-vmwarefb/drivers/video/fbmem.c
--- linux-2.4.20/drivers/video/fbmem.c 2002-11-29 13:18:43.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/fbmem.c 2002-11-29 13:24:53.000000000 +0100
@@ -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);
@@ -190,6 +192,9 @@
#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 },
#endif
diff -uraN linux-2.4.20/drivers/video/vmware/Makefile linux-2.4.20-vmwarefb/drivers/video/vmware/Makefile
--- linux-2.4.20/drivers/video/vmware/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/Makefile 2002-11-29 13:24:53.000000000 +0100
@@ -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.20/drivers/video/vmware/guest_os.h linux-2.4.20-vmwarefb/drivers/video/vmware/guest_os.h
--- linux-2.4.20/drivers/video/vmware/guest_os.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/guest_os.h 2002-11-29 13:35:53.000000000 +0100
@@ -0,0 +1,35 @@
+/*
+ * linux/drivers/video/vmware/guest_os.h -- 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.
+ *
+ */
+
+#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.20/drivers/video/vmware/svga_limits.h linux-2.4.20-vmwarefb/drivers/video/vmware/svga_limits.h
--- linux-2.4.20/drivers/video/vmware/svga_limits.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/svga_limits.h 2002-11-29 13:35:50.000000000 +0100
@@ -0,0 +1,55 @@
+/*
+ * linux/drivers/video/vmware/svga_limits.h -- 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.
+ *
+ */
+
+#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.20/drivers/video/vmware/svga_reg.h linux-2.4.20-vmwarefb/drivers/video/vmware/svga_reg.h
--- linux-2.4.20/drivers/video/vmware/svga_reg.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/svga_reg.h 2002-11-29 13:35:50.000000000 +0100
@@ -0,0 +1,300 @@
+/*
+ * linux/drivers/video/vmware/svga_reg.h -- 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.
+ *
+ */
+
+#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.20/drivers/video/vmware/vmwarefb.c linux-2.4.20-vmwarefb/drivers/video/vmware/vmwarefb.c
--- linux-2.4.20/drivers/video/vmware/vmwarefb.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/vmwarefb.c 2002-11-29 13:35:53.000000000 +0100
@@ -0,0 +1,1529 @@
+/*
+ * linux/drivers/video/vmware/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.20/drivers/video/vmware/vmwarefb.h linux-2.4.20-vmwarefb/drivers/video/vmware/vmwarefb.h
--- linux-2.4.20/drivers/video/vmware/vmwarefb.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-vmwarefb/drivers/video/vmware/vmwarefb.h 2002-11-29 13:34:28.000000000 +0100
@@ -0,0 +1,95 @@
+/*
+ * linux/drivers/video/vmware/vmwarefb.h -- 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.
+ *
+ */
+
+
+#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.20/include/linux/fb.h linux-2.4.20-vmwarefb/include/linux/fb.h
--- linux-2.4.20/include/linux/fb.h 2002-11-01 13:33:02.000000000 +0100
+++ linux-2.4.20-vmwarefb/include/linux/fb.h 2002-11-29 13:24:53.000000000 +0100
@@ -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-11-29 13:52 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-29 13:58 [PATCH] vmwarefb 0.6.0 (Linux 2.4.20) 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;
as well as URLs for NNTP newsgroup(s).