summaryrefslogtreecommitdiff
path: root/driver/xf86-video-vmware/src/vmware.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/xf86-video-vmware/src/vmware.c')
-rw-r--r--driver/xf86-video-vmware/src/vmware.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/driver/xf86-video-vmware/src/vmware.c b/driver/xf86-video-vmware/src/vmware.c
index 80224384a..0b1050425 100644
--- a/driver/xf86-video-vmware/src/vmware.c
+++ b/driver/xf86-video-vmware/src/vmware.c
@@ -18,7 +18,9 @@ char rcsId_vmware[] =
#include "xf86.h"
#include "xf86_OSproc.h"
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
#include "xf86Resources.h"
+#endif
#include "compiler.h" /* inb/outb */
@@ -83,7 +85,7 @@ char rcsId_vmware[] =
#define VMWARE_DRIVER_NAME "vmware"
#define VMWARE_MAJOR_VERSION 10
#define VMWARE_MINOR_VERSION 16
-#define VMWARE_PATCHLEVEL 6
+#define VMWARE_PATCHLEVEL 8
#define VMWARE_DRIVER_VERSION \
(VMWARE_MAJOR_VERSION * 65536 + VMWARE_MINOR_VERSION * 256 + VMWARE_PATCHLEVEL)
#define VMWARE_DRIVER_VERSION_STRING \
@@ -109,11 +111,15 @@ static SymTabRec VMWAREChipsets[] = {
{ -1, NULL }
};
+#ifndef XSERVER_LIBPCIACCESS
static resRange vmwareLegacyRes[] = {
{ ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
_VGA_EXCLUSIVE, _END
};
+#else
+#define vmwareLegacyRes NULL
+#endif
#if XSERVER_LIBPCIACCESS
@@ -306,7 +312,7 @@ vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB)
vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1);
}
-static void
+void
vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)
{
BoxRec BB;
@@ -652,6 +658,7 @@ VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
"No supported VMware SVGA found (read ID 0x%08x).\n", id);
return FALSE;
}
+ pVMWARE->suspensionSavedRegId = id;
#if !XSERVER_LIBPCIACCESS
pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
@@ -1162,8 +1169,40 @@ VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
vgaHWProtect(pScrn, FALSE);
/*
- * XXX -- If we want to check that we got the mode we asked for, this
- * would be a good place.
+ * Push the new Xinerama state to X clients and the hardware,
+ * synchronously with the mode change. Note that this must happen
+ * AFTER we write the new width and height to the hardware
+ * registers, since updating the WIDTH and HEIGHT registers will
+ * reset the device's multimon topology.
+ */
+ vmwareNextXineramaState(pVMWARE);
+
+ return TRUE;
+}
+
+void
+vmwareNextXineramaState(VMWAREPtr pVMWARE)
+{
+ VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+ /*
+ * Switch to the next Xinerama state (from pVMWARE->xineramaNextState).
+ *
+ * This new state will be available to X clients via the Xinerama
+ * extension, and we push the new state to the virtual hardware,
+ * in order to configure a number of virtual monitors within the
+ * device's framebuffer.
+ *
+ * This function can be called at any time, but it should usually be
+ * called just after a mode switch. This is for two reasons:
+ *
+ * 1) We don't want X clients to see a Xinerama topology and a video
+ * mode that are inconsistent with each other, so we'd like to switch
+ * both at the same time.
+ *
+ * 2) We must set the host's display topology registers after setting
+ * the new video mode, since writes to WIDTH/HEIGHT will reset the
+ * hardware display topology.
*/
/*
@@ -1177,7 +1216,14 @@ VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
pVMWARE->xineramaNextState = NULL;
pVMWARE->xineramaNextNumOutputs = 0;
+
} else {
+ /*
+ * There is no next state pending. Switch back to
+ * single-monitor mode. This is necessary for resetting the
+ * Xinerama state if we get a mode change which doesn't
+ * follow a VMwareCtrlDoSetTopology call.
+ */
VMWAREXineramaPtr basicState =
(VMWAREXineramaPtr)xcalloc(1, sizeof (VMWAREXineramaRec));
if (basicState) {
@@ -1194,7 +1240,8 @@ VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
}
/*
- * Update host's view of guest topology.
+ * Update host's view of guest topology. This tells the device
+ * how we're carving up its framebuffer into virtual screens.
*/
if (pVMWARE->vmwareCapability & SVGA_CAP_DISPLAY_TOPOLOGY) {
if (pVMWARE->xinerama) {
@@ -1222,14 +1269,13 @@ VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE);
vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 0);
vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 0);
- vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, mode->HDisplay);
- vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, mode->VDisplay);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, vmwareReg->svga_reg_width);
+ vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, vmwareReg->svga_reg_height);
}
+ /* Done. */
vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, SVGA_INVALID_DISPLAY_ID);
}
-
- return TRUE;
}
static void
@@ -1435,6 +1481,7 @@ VMWAREAddDisplayMode(ScrnInfoPtr pScrn,
DisplayModeRec *mode;
mode = xalloc(sizeof(DisplayModeRec));
+ memset(mode, 0, sizeof *mode);
mode->name = xalloc(strlen(name) + 1);
strcpy(mode->name, name);
@@ -1820,7 +1867,13 @@ VMWAREEnterVT(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
- if (!pVMWARE->SavedReg.svga_fifo_enabled) {
+ /*
+ * After system resumes from hiberation, EnterVT will be called and this
+ * is a good place to restore the SVGA ID register.
+ */
+ vmwareWriteReg(pVMWARE, SVGA_REG_ID, pVMWARE->suspensionSavedRegId);
+
+ if (!pVMWARE->SavedReg.svga_fifo_enabled) {
VMWAREInitFIFO(pScrn);
}
@@ -1831,6 +1884,14 @@ static void
VMWARELeaveVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+ /*
+ * Before shutting down system for hibneration, LeaveVT will be called,
+ * we save the ID register value here and later restore it in EnterVT.
+ */
+ pVMWARE->suspensionSavedRegId = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+
VMWARERestore(pScrn);
}