mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-11-01 09:13:37 +00:00
drm/vmwgfx: Fix vga save / restore with display topology.
vga save / restore previously didn't handle the display topology case. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
c0db9cbc73
commit
7c4f77801f
2 changed files with 56 additions and 7 deletions
|
|
@ -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 {
|
||||||
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 {
|
||||||
* 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,
|
||||||
|
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue