Commit 7c4f7780 authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie

drm/vmwgfx: Fix vga save / restore with display topology.

vga save / restore previously didn't handle the display topology case.
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent c0db9cbc
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024) #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
#define VMWGFX_MAX_RELOCATIONS 2048 #define VMWGFX_MAX_RELOCATIONS 2048
#define VMWGFX_MAX_GMRS 2048 #define VMWGFX_MAX_GMRS 2048
#define VMWGFX_MAX_DISPLAYS 16
struct vmw_fpriv { struct vmw_fpriv {
struct drm_master *locked_master; struct drm_master *locked_master;
...@@ -152,6 +153,14 @@ struct vmw_master { ...@@ -152,6 +153,14 @@ struct vmw_master {
struct ttm_lock lock; struct ttm_lock lock;
}; };
struct vmw_vga_topology_state {
uint32_t width;
uint32_t height;
uint32_t primary;
uint32_t pos_x;
uint32_t pos_y;
};
struct vmw_private { struct vmw_private {
struct ttm_bo_device bdev; struct ttm_bo_device bdev;
struct ttm_bo_global_ref bo_global_ref; struct ttm_bo_global_ref bo_global_ref;
...@@ -179,16 +188,20 @@ struct vmw_private { ...@@ -179,16 +188,20 @@ struct vmw_private {
* VGA registers. * VGA registers.
*/ */
struct vmw_vga_topology_state vga_save[VMWGFX_MAX_DISPLAYS];
uint32_t vga_width; uint32_t vga_width;
uint32_t vga_height; uint32_t vga_height;
uint32_t vga_depth; uint32_t vga_depth;
uint32_t vga_bpp; uint32_t vga_bpp;
uint32_t vga_pseudo; uint32_t vga_pseudo;
uint32_t vga_red_mask; uint32_t vga_red_mask;
uint32_t vga_blue_mask;
uint32_t vga_green_mask; uint32_t vga_green_mask;
uint32_t vga_blue_mask;
uint32_t vga_bpl;
uint32_t vga_pitchlock; uint32_t vga_pitchlock;
uint32_t num_displays;
/* /*
* Framebuffer info. * Framebuffer info.
*/ */
......
...@@ -865,30 +865,52 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, ...@@ -865,30 +865,52 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv,
int vmw_kms_save_vga(struct vmw_private *vmw_priv) int vmw_kms_save_vga(struct vmw_private *vmw_priv)
{ {
struct vmw_vga_topology_state *save;
uint32_t i;
vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH);
vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT);
vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH);
vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL);
vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR);
vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK);
vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK);
vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK);
if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK)
vmw_priv->vga_pitchlock = vmw_priv->vga_pitchlock =
vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); vmw_read(vmw_priv, SVGA_REG_PITCHLOCK);
else if (vmw_fifo_have_pitchlock(vmw_priv)) else if (vmw_fifo_have_pitchlock(vmw_priv))
vmw_priv->vga_pitchlock = vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt +
ioread32(vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); SVGA_FIFO_PITCHLOCK);
if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
return 0;
vmw_priv->num_displays = vmw_read(vmw_priv,
SVGA_REG_NUM_GUEST_DISPLAYS);
for (i = 0; i < vmw_priv->num_displays; ++i) {
save = &vmw_priv->vga_save[i];
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY);
save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X);
save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y);
save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH);
save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
}
return 0; return 0;
} }
int vmw_kms_restore_vga(struct vmw_private *vmw_priv) int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
{ {
struct vmw_vga_topology_state *save;
uint32_t i;
vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width);
vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height);
vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth);
vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp);
vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo);
vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask);
vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask);
...@@ -900,5 +922,19 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv) ...@@ -900,5 +922,19 @@ int vmw_kms_restore_vga(struct vmw_private *vmw_priv)
iowrite32(vmw_priv->vga_pitchlock, iowrite32(vmw_priv->vga_pitchlock,
vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK);
if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY))
return 0;
for (i = 0; i < vmw_priv->num_displays; ++i) {
save = &vmw_priv->vga_save[i];
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height);
vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
}
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment