lkml.org 
[lkml]   [2002]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] vmwarefb 0.5.0

Hi,

this is the initial release (code is a few hours old)
of a framebuffer driver for VMware SVGA display.

Successfully tested on Workstation 3.1 for Linux.

The patch applies against Linux 2.4.19-pre8.

--
Best regards,
Denis Oliver Kropp

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

Convergence GmbH
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 Tue May 14 05:05:22 2002
@@ -0,0 +1,1524 @@
+/*
+ * linux/drivers/video/vmwarefb.c -- Vmware 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.5.0
+ * - initial version (dok)
+ *
+ *
+ * TODO
+ * - support for changing bits per pixel (using 8bit emulation capability)
+ * - panning (can SVGA_REG_FB_OFFSET be written to?)
+ * - console acceleration
+ *
+ */
+
+#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.5.0"
+
+/* --------------------------------------------------------------------- */
+
+#ifdef MODULE
+
+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.");
+
+#endif
+
+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 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);
+}
+
+#if 0 /* Useless until acceleration is used */
+static void
+vmwareWriteWordToFIFO (const struct vmwarefb_info *info, u32 value)
+{
+ u32* vmwareFIFO = info->vmwareFIFO;
+
+ /* 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 (const struct vmwarefb_info *info)
+{
+ if (info->vmwareFIFOMarkSet)
+ {
+ vmwareWriteReg(info, SVGA_REG_SYNC, 1);
+ while (vmwareReadReg(info, SVGA_REG_BUSY)) ;
+ info->vmwareFIFOMarkSet = FALSE;
+ }
+}
+
+static void
+vmwareSendSVGACmdUpdate (const struct vmwarefb_info *info, BoxPtr pBB)
+{
+ vmwareWriteWordToFIFO(info, SVGA_CMD_UPDATE);
+ vmwareWriteWordToFIFO(info, pBB->x1);
+ vmwareWriteWordToFIFO(info, pBB->y1);
+ vmwareWriteWordToFIFO(info, pBB->x2 - pBB->x1);
+ vmwareWriteWordToFIFO(info, pBB->y2 - pBB->y1);
+}
+
+static void
+vmwareSendSVGACmdUpdateFullScreen (const struct vmwarefb_info *info)
+{
+ BoxRec BB;
+
+ BB.x1 = 0;
+ BB.y1 = 0;
+ BB.x2 = info->ModeReg.svga_reg_width;
+ BB.y2 = info->ModeReg.svga_reg_height;
+
+ vmwareSendSVGACmdUpdate(info, &BB);
+}
+#endif
+
+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
+vgaHWLock (void)
+{
+ /* Protect CRTC[0-7] */
+ VGAwCR (0x11, VGArCR (0x11) | 0x80);
+}
+
+static void
+vgaHWUnlock (void)
+{
+ /* Unprotect CRTC[0-7] */
+ VGAwCR (0x11, VGArCR (0x11) & ~0x80);
+}
+
+static void
+vmwareLock (void)
+{
+ VGAwGR (0x09, 0x00);
+ vgaHWLock();
+}
+
+static void
+vmwareUnlock (void)
+{
+ vgaHWUnlock();
+ VGAwGR (0x09, 0x26);
+}
+
+static void
+vgaHWSeqReset (int start)
+{
+ if (start)
+ VGAwSEQ (0x00, 0x01); /* Synchronous Reset */
+ else
+ VGAwSEQ (0x00, 0x03); /* End Reset */
+}
+
+static void
+vgaHWProtect (int on)
+{
+ unsigned char tmp;
+
+ if (on)
+ {
+ /*
+ * Turn off screen and disable sequencer.
+ */
+ tmp = VGArSEQ (0x01);
+
+ vgaHWSeqReset (1); /* start synchronous reset */
+ VGAwSEQ (0x01, tmp | 0x20); /* disable the display */
+
+ VGAenablePalette();
+ }
+ else
+ {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+
+ tmp = VGArSEQ (0x01);
+
+ VGAwSEQ (0x01, tmp & ~0x20); /* reenable display */
+ vgaHWSeqReset (0); /* clear synchronousreset */
+
+ VGAdisablePalette();
+ }
+}
+
+static void
+vgaHWRestore (const struct vmwarefb_info *info,
+ const struct vmwarefb_par *par)
+{
+ int i;
+
+ VGAwMISC (par->MiscOutReg);
+
+ for (i = 1; i < 5; i++)
+ VGAwSEQ (i, par->Sequencer[i]);
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
+ VGAwCR (17, par->CRTC[17] & ~0x80);
+
+ for (i = 0; i < 25; i++)
+ VGAwCR (i, par->CRTC[i]);
+
+ for (i = 0; i < 9; i++)
+ VGAwGR (i, par->Graphics[i]);
+
+ VGAenablePalette();
+
+ for (i = 0; i < 21; i++)
+ VGAwATTR (i, par->Attribute[i]);
+
+ VGAdisablePalette();
+}
+
+static int
+vgaHWInit (const struct fb_var_screeninfo *var,
+ const struct vmwarefb_info *info,
+ struct vmwarefb_par *par,
+ struct xtimings *timings)
+{
+ par->MiscOutReg = 0x23;
+
+ if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT))
+ par->MiscOutReg |= 0x40;
+
+ if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT))
+ par->MiscOutReg |= 0x80;
+
+ /*
+ * Time Sequencer
+ */
+ par->Sequencer[0] = 0x00;
+ par->Sequencer[1] = 0x01;
+ par->Sequencer[2] = 0x0F;
+ par->Sequencer[3] = 0x00; /* Font select */
+ par->Sequencer[4] = 0x0E; /* Misc */
+
+ /*
+ * CRTC Controller
+ */
+ par->CRTC[0] = (timings->HTotal >> 3) - 5;
+ par->CRTC[1] = (timings->HDisplay >> 3) - 1;
+ par->CRTC[2] = (timings->HDisplay >> 3) - 1;
+ par->CRTC[3] = (((timings->HTotal >> 3) - 1) & 0x1F) | 0x80;
+ par->CRTC[4] = (timings->HSyncStart >> 3);
+ par->CRTC[5] = ((((timings->HTotal >> 3) - 1) & 0x20) << 2)
+ | (((timings->HSyncEnd >> 3)) & 0x1F);
+ par->CRTC[6] = (timings->VTotal - 2) & 0xFF;
+ par->CRTC[7] = (((timings->VTotal - 2) & 0x100) >> 8)
+ | (((timings->VDisplay - 1) & 0x100) >> 7)
+ | ((timings->VSyncStart & 0x100) >> 6)
+ | (((timings->VDisplay - 1) & 0x100) >> 5)
+ | 0x10
+ | (((timings->VTotal - 2) & 0x200) >> 4)
+ | (((timings->VDisplay - 1) & 0x200) >> 3)
+ | ((timings->VSyncStart & 0x200) >> 2);
+ par->CRTC[8] = 0x00;
+ par->CRTC[9] = (((timings->VDisplay - 1) & 0x200) >> 4) | 0x40;
+
+ if (timings->dblscan)
+ par->CRTC[9] |= 0x80;
+
+ par->CRTC[10] = 0x00;
+ par->CRTC[11] = 0x00;
+ par->CRTC[12] = 0x00;
+ par->CRTC[13] = 0x00;
+ par->CRTC[14] = 0x00;
+ par->CRTC[15] = 0x00;
+ par->CRTC[16] = timings->VSyncStart & 0xFF;
+ par->CRTC[17] = (timings->VSyncEnd & 0x0F) | 0x20;
+ par->CRTC[18] = (timings->VDisplay - 1) & 0xFF;
+ par->CRTC[19] = var->xres_virtual >> 4;
+ par->CRTC[20] = 0x00;
+ par->CRTC[21] = (timings->VDisplay - 1) & 0xFF;
+ par->CRTC[22] = (timings->VTotal - 1) & 0xFF;
+ par->CRTC[23] = 0xC3;
+ par->CRTC[24] = 0xFF;
+
+ /*
+ * are these unnecessary?
+ * vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+ * vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+ */
+
+ /*
+ * Graphics Display Controller
+ */
+ par->Graphics[0] = 0x00;
+ par->Graphics[1] = 0x00;
+ par->Graphics[2] = 0x00;
+ par->Graphics[3] = 0x00;
+ par->Graphics[4] = 0x00;
+ par->Graphics[5] = 0x40;
+ par->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
+ par->Graphics[7] = 0x0F;
+ par->Graphics[8] = 0xFF;
+
+
+ par->Attribute[0] = 0x00; /* standard colormap translation */
+ par->Attribute[1] = 0x01;
+ par->Attribute[2] = 0x02;
+ par->Attribute[3] = 0x03;
+ par->Attribute[4] = 0x04;
+ par->Attribute[5] = 0x05;
+ par->Attribute[6] = 0x06;
+ par->Attribute[7] = 0x07;
+ par->Attribute[8] = 0x08;
+ par->Attribute[9] = 0x09;
+ par->Attribute[10] = 0x0A;
+ par->Attribute[11] = 0x0B;
+ par->Attribute[12] = 0x0C;
+ par->Attribute[13] = 0x0D;
+ par->Attribute[14] = 0x0E;
+ par->Attribute[15] = 0x0F;
+ par->Attribute[16] = 0x41;
+ par->Attribute[17] = 0xFF;
+ par->Attribute[18] = 0x0F;
+ par->Attribute[19] = 0x00;
+ par->Attribute[20] = 0x00;
+
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * 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");
+
+ vmwareUnlock();
+
+ /* Blank the screen */
+ vgaHWProtect (1);
+
+ /* This function handles restoring the generic VGA registers. */
+ vgaHWRestore (info, par);
+
+ /* 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_GUEST_ID, GUEST_OS_LINUX);
+
+ /* Turn on screen */
+ vgaHWProtect (0);
+
+ /* Calling this also locks offset registers required in update_start */
+ vmwareLock();
+}
+
+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)
+{
+ struct xtimings timings;
+ int memlen, vramlen;
+ unsigned int pixclock = var->pixclock;
+
+ DBG("vmwarefb_decode_var");
+
+ if (!pixclock) pixclock = 10000; /* 10ns = 100MHz */
+ timings.pixclock = 1000000000 / pixclock;
+ if (timings.pixclock < 1) timings.pixclock = 1;
+ timings.dblscan = var->vmode & FB_VMODE_DOUBLE;
+ timings.interlaced = var->vmode & FB_VMODE_INTERLACED;
+ timings.HDisplay = var->xres;
+ timings.HSyncStart = timings.HDisplay + var->right_margin;
+ timings.HSyncEnd = timings.HSyncStart + var->hsync_len;
+ timings.HTotal = timings.HSyncEnd + var->left_margin;
+ timings.VDisplay = var->yres;
+ timings.VSyncStart = timings.VDisplay + var->lower_margin;
+ timings.VSyncEnd = timings.VSyncStart + var->vsync_len;
+ timings.VTotal = timings.VSyncEnd + var->upper_margin;
+ timings.sync = var->sync;
+
+ if (timings.pixclock > info->maxClock)
+ return -EINVAL;
+
+ /* No double scan or interlaced support */
+ if (timings.dblscan || timings.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 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;
+
+
+ /*
+ * This will allocate the datastructure and initialize all of the
+ * generic VGA registers.
+ */
+
+ if (vgaHWInit (var, info, par, &timings))
+ return -EINVAL;
+
+ /*
+ * 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 (con == info->currcon)
+ {
+ if (chgvar || con < 0)
+ vmwarefb_set_par (info, &par);
+
+ 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);
+ }
+
+ if (vmwareReadReg(info, SVGA_REG_FB_OFFSET))
+ printk(KERN_DEBUG "vmwarefb: unhandled fbOffset %d\n",
+ vmwareReadReg(info, SVGA_REG_FB_OFFSET));
+
+ 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;
+ break;
+ }
+
+ /* Copy and modify console text drawing functions */
+ memcpy (&info->dispsw, dispsw, sizeof(struct display_switch));
+
+ info->dispsw.bmove = fbcon_redraw_bmove;
+
+ /* Set display information */
+ display->dispsw = &info->dispsw;
+ display->scrollmode = SCROLL_YREDRAW;
+
+ display->screen_base = fb->screen_base;
+ 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");
+
+ 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;
+
+ /* 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);
+}
+
+
+#ifndef MODULE
+
+/* ************************* init in-kernel code ************************** */
+
+static int disabled = 0;
+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, "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 Tue May 14 02:39:49 2002
@@ -0,0 +1,192 @@
+/*
+ * 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
+
+/*
+ * Converted timings in X format for vgaHW functions
+ */
+struct xtimings {
+ unsigned int pixclock;
+ unsigned int HDisplay;
+ unsigned int HSyncStart;
+ unsigned int HSyncEnd;
+ unsigned int HTotal;
+ unsigned int VDisplay;
+ unsigned int VSyncStart;
+ unsigned int VSyncEnd;
+ unsigned int VTotal;
+ unsigned int sync;
+ int dblscan;
+ int interlaced;
+};
+
+
+/* --------------------------------------------------------------------- */
+
+#define NR_PALETTE 256
+
+
+struct vmwarefb_par {
+
+ /* VGA registers */
+ unsigned char MiscOutReg; /* Misc */
+ unsigned char CRTC[25]; /* Crtc Controller */
+ unsigned char Sequencer[5]; /* Video Sequencer */
+ unsigned char Graphics[9]; /* Video Graphics */
+ unsigned char Attribute[21]; /* Video Atribute */
+
+ /* 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;
+
+ /* 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];
+};
+
+
+
+
+/* vga IO functions */
+static inline u8 VGArCR (u8 index)
+{
+ outb (index, 0x3d4);
+ return inb (0x3d5);
+}
+
+static inline void VGAwCR (u8 index, u8 val)
+{
+ outb (index, 0x3d4);
+ outb (val, 0x3d5);
+}
+
+static inline u8 VGArGR (u8 index)
+{
+ outb (index, 0x3ce);
+ return inb (0x3cf);
+}
+
+static inline void VGAwGR (u8 index, u8 val)
+{
+ outb (index, 0x3ce);
+ outb (val, 0x3cf);
+}
+
+static inline u8 VGArSEQ (u8 index)
+{
+ outb (index, 0x3c4);
+ return inb (0x3c5);
+}
+
+static inline void VGAwSEQ (u8 index, u8 val)
+{
+ outb (index, 0x3c4);
+ outb (val, 0x3c5);
+}
+
+
+static int paletteEnabled = 0;
+
+static inline void VGAenablePalette (void)
+{
+ u8 tmp;
+
+ tmp = inb (0x3da);
+ outb (0x00, 0x3c0);
+ paletteEnabled = 1;
+}
+
+static inline void VGAdisablePalette (void)
+{
+ u8 tmp;
+
+ tmp = inb (0x3da);
+ outb (0x20, 0x3c0);
+ paletteEnabled = 0;
+}
+
+static inline void VGAwATTR (u8 index, u8 value)
+{
+ u8 tmp;
+
+ if (paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ tmp = inb (0x3da);
+ outb (index, 0x3c0);
+ outb (value, 0x3c0);
+}
+
+static inline void VGAwMISC (u8 value)
+{
+ outb (value, 0x3c2);
+}
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 */
\
 
 \ /
  Last update: 2005-03-22 13:26    [W:0.062 / U:9.940 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site