diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2010-06-01 05:38:17 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-06-02 23:13:35 -0400 |
commit | 7c4f77801f103c9eb0465bf42313d5e1721d2991 (patch) | |
tree | 6ba1419dbd4fa9f7a98e06e10ec34ea4fbd5ccda /drivers | |
parent | c0db9cbc73338d8e2987a19a02388d67aeec0bfe (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 48 |
2 files changed, 56 insertions, 7 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1341adef408d..e577af5bb3d6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 47 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
48 | #define VMWGFX_MAX_RELOCATIONS 2048 | 48 | #define VMWGFX_MAX_RELOCATIONS 2048 |
49 | #define VMWGFX_MAX_GMRS 2048 | 49 | #define VMWGFX_MAX_GMRS 2048 |
50 | #define VMWGFX_MAX_DISPLAYS 16 | ||
50 | 51 | ||
51 | struct vmw_fpriv { | 52 | struct vmw_fpriv { |
52 | struct drm_master *locked_master; | 53 | struct drm_master *locked_master; |
@@ -152,6 +153,14 @@ struct vmw_master { | |||
152 | struct ttm_lock lock; | 153 | struct ttm_lock lock; |
153 | }; | 154 | }; |
154 | 155 | ||
156 | struct vmw_vga_topology_state { | ||
157 | uint32_t width; | ||
158 | uint32_t height; | ||
159 | uint32_t primary; | ||
160 | uint32_t pos_x; | ||
161 | uint32_t pos_y; | ||
162 | }; | ||
163 | |||
155 | struct vmw_private { | 164 | struct vmw_private { |
156 | struct ttm_bo_device bdev; | 165 | struct ttm_bo_device bdev; |
157 | struct ttm_bo_global_ref bo_global_ref; | 166 | struct ttm_bo_global_ref bo_global_ref; |
@@ -179,16 +188,20 @@ struct vmw_private { | |||
179 | * VGA registers. | 188 | * VGA registers. |
180 | */ | 189 | */ |
181 | 190 | ||
191 | struct vmw_vga_topology_state vga_save[VMWGFX_MAX_DISPLAYS]; | ||
182 | uint32_t vga_width; | 192 | uint32_t vga_width; |
183 | uint32_t vga_height; | 193 | uint32_t vga_height; |
184 | uint32_t vga_depth; | 194 | uint32_t vga_depth; |
185 | uint32_t vga_bpp; | 195 | uint32_t vga_bpp; |
186 | uint32_t vga_pseudo; | 196 | uint32_t vga_pseudo; |
187 | uint32_t vga_red_mask; | 197 | uint32_t vga_red_mask; |
188 | uint32_t vga_blue_mask; | ||
189 | uint32_t vga_green_mask; | 198 | uint32_t vga_green_mask; |
199 | uint32_t vga_blue_mask; | ||
200 | uint32_t vga_bpl; | ||
190 | uint32_t vga_pitchlock; | 201 | uint32_t vga_pitchlock; |
191 | 202 | ||
203 | uint32_t num_displays; | ||
204 | |||
192 | /* | 205 | /* |
193 | * Framebuffer info. | 206 | * Framebuffer info. |
194 | */ | 207 | */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b78dcf001858..648ba044f6f8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -865,30 +865,52 @@ void vmw_kms_write_svga(struct vmw_private *vmw_priv, | |||
865 | 865 | ||
866 | int vmw_kms_save_vga(struct vmw_private *vmw_priv) | 866 | int vmw_kms_save_vga(struct vmw_private *vmw_priv) |
867 | { | 867 | { |
868 | struct vmw_vga_topology_state *save; | ||
869 | uint32_t i; | ||
870 | |||
868 | vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); | 871 | vmw_priv->vga_width = vmw_read(vmw_priv, SVGA_REG_WIDTH); |
869 | vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); | 872 | vmw_priv->vga_height = vmw_read(vmw_priv, SVGA_REG_HEIGHT); |
870 | vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); | ||
871 | vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); | 873 | vmw_priv->vga_depth = vmw_read(vmw_priv, SVGA_REG_DEPTH); |
874 | vmw_priv->vga_bpp = vmw_read(vmw_priv, SVGA_REG_BITS_PER_PIXEL); | ||
872 | vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); | 875 | vmw_priv->vga_pseudo = vmw_read(vmw_priv, SVGA_REG_PSEUDOCOLOR); |
873 | vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); | 876 | vmw_priv->vga_red_mask = vmw_read(vmw_priv, SVGA_REG_RED_MASK); |
874 | vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); | ||
875 | vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); | 877 | vmw_priv->vga_blue_mask = vmw_read(vmw_priv, SVGA_REG_BLUE_MASK); |
878 | vmw_priv->vga_green_mask = vmw_read(vmw_priv, SVGA_REG_GREEN_MASK); | ||
876 | if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) | 879 | if (vmw_priv->capabilities & SVGA_CAP_PITCHLOCK) |
877 | vmw_priv->vga_pitchlock = | 880 | vmw_priv->vga_pitchlock = |
878 | vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); | 881 | vmw_read(vmw_priv, SVGA_REG_PITCHLOCK); |
879 | else if (vmw_fifo_have_pitchlock(vmw_priv)) | 882 | else if (vmw_fifo_have_pitchlock(vmw_priv)) |
880 | vmw_priv->vga_pitchlock = | 883 | vmw_priv->vga_pitchlock = ioread32(vmw_priv->mmio_virt + |
881 | ioread32(vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); | 884 | SVGA_FIFO_PITCHLOCK); |
885 | |||
886 | if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) | ||
887 | return 0; | ||
882 | 888 | ||
889 | vmw_priv->num_displays = vmw_read(vmw_priv, | ||
890 | SVGA_REG_NUM_GUEST_DISPLAYS); | ||
891 | |||
892 | for (i = 0; i < vmw_priv->num_displays; ++i) { | ||
893 | save = &vmw_priv->vga_save[i]; | ||
894 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i); | ||
895 | save->primary = vmw_read(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY); | ||
896 | save->pos_x = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_X); | ||
897 | save->pos_y = vmw_read(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y); | ||
898 | save->width = vmw_read(vmw_priv, SVGA_REG_DISPLAY_WIDTH); | ||
899 | save->height = vmw_read(vmw_priv, SVGA_REG_DISPLAY_HEIGHT); | ||
900 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | ||
901 | } | ||
883 | return 0; | 902 | return 0; |
884 | } | 903 | } |
885 | 904 | ||
886 | int vmw_kms_restore_vga(struct vmw_private *vmw_priv) | 905 | int vmw_kms_restore_vga(struct vmw_private *vmw_priv) |
887 | { | 906 | { |
907 | struct vmw_vga_topology_state *save; | ||
908 | uint32_t i; | ||
909 | |||
888 | vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); | 910 | vmw_write(vmw_priv, SVGA_REG_WIDTH, vmw_priv->vga_width); |
889 | vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); | 911 | vmw_write(vmw_priv, SVGA_REG_HEIGHT, vmw_priv->vga_height); |
890 | vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp); | ||
891 | vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); | 912 | vmw_write(vmw_priv, SVGA_REG_DEPTH, vmw_priv->vga_depth); |
913 | vmw_write(vmw_priv, SVGA_REG_BITS_PER_PIXEL, vmw_priv->vga_bpp); | ||
892 | vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); | 914 | vmw_write(vmw_priv, SVGA_REG_PSEUDOCOLOR, vmw_priv->vga_pseudo); |
893 | vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); | 915 | vmw_write(vmw_priv, SVGA_REG_RED_MASK, vmw_priv->vga_red_mask); |
894 | vmw_write(vmw_priv, SVGA_REG_GREEN_MASK, vmw_priv->vga_green_mask); | 916 | 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 | iowrite32(vmw_priv->vga_pitchlock, | 922 | iowrite32(vmw_priv->vga_pitchlock, |
901 | vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); | 923 | vmw_priv->mmio_virt + SVGA_FIFO_PITCHLOCK); |
902 | 924 | ||
925 | if (!(vmw_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) | ||
926 | return 0; | ||
927 | |||
928 | for (i = 0; i < vmw_priv->num_displays; ++i) { | ||
929 | save = &vmw_priv->vga_save[i]; | ||
930 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, i); | ||
931 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_IS_PRIMARY, save->primary); | ||
932 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_X, save->pos_x); | ||
933 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_POSITION_Y, save->pos_y); | ||
934 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_WIDTH, save->width); | ||
935 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_HEIGHT, save->height); | ||
936 | vmw_write(vmw_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID); | ||
937 | } | ||
938 | |||
903 | return 0; | 939 | return 0; |
904 | } | 940 | } |