drm/vmwgfx: Support older hardware.
V2: Fix a couple of typos. Signed-off-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:

committed by
Dave Airlie

parent
1ae1ddd5e9
commit
d7e1958dbe
@@ -38,6 +38,7 @@ struct vmw_legacy_display {
|
||||
struct list_head active;
|
||||
|
||||
unsigned num_active;
|
||||
unsigned last_num_active;
|
||||
|
||||
struct vmw_framebuffer *fb;
|
||||
};
|
||||
@@ -88,12 +89,37 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
|
||||
{
|
||||
struct vmw_legacy_display *lds = dev_priv->ldu_priv;
|
||||
struct vmw_legacy_display_unit *entry;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_framebuffer *fb = NULL;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
int i = 0;
|
||||
|
||||
/* to stop the screen from changing size on resize */
|
||||
vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, 0);
|
||||
for (i = 0; i < lds->num_active; i++) {
|
||||
/* If there is no display topology the host just assumes
|
||||
* that the guest will set the same layout as the host.
|
||||
*/
|
||||
if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)) {
|
||||
int w = 0, h = 0;
|
||||
list_for_each_entry(entry, &lds->active, active) {
|
||||
crtc = &entry->base.crtc;
|
||||
w = max(w, crtc->x + crtc->mode.hdisplay);
|
||||
h = max(h, crtc->y + crtc->mode.vdisplay);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (crtc == NULL)
|
||||
return 0;
|
||||
fb = entry->base.crtc.fb;
|
||||
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE, 0);
|
||||
vmw_kms_write_svga(dev_priv, w, h, fb->pitch,
|
||||
fb->bits_per_pixel, fb->depth);
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE, 0);
|
||||
|
||||
for (i = 0; i < lds->last_num_active; i++) {
|
||||
vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, i);
|
||||
vmw_write(dev_priv, SVGA_REG_DISPLAY_IS_PRIMARY, !i);
|
||||
vmw_write(dev_priv, SVGA_REG_DISPLAY_POSITION_X, 0);
|
||||
@@ -103,8 +129,14 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
|
||||
vmw_write(dev_priv, SVGA_REG_DISPLAY_ID, SVGA_ID_INVALID);
|
||||
}
|
||||
|
||||
/* Now set the mode */
|
||||
vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, lds->num_active);
|
||||
if (!list_empty(&lds->active)) {
|
||||
entry = list_entry(lds->active.next, typeof(*entry), active);
|
||||
fb = entry->base.crtc.fb;
|
||||
|
||||
vmw_kms_write_svga(dev_priv, fb->width, fb->height, fb->pitch,
|
||||
fb->bits_per_pixel, fb->depth);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
list_for_each_entry(entry, &lds->active, active) {
|
||||
crtc = &entry->base.crtc;
|
||||
@@ -120,6 +152,14 @@ static int vmw_ldu_commit_list(struct vmw_private *dev_priv)
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Make sure we always show something. */
|
||||
vmw_write(dev_priv, SVGA_REG_NUM_GUEST_DISPLAYS, i ? i : 1);
|
||||
vmw_write(dev_priv, SVGA_REG_ENABLE, 1);
|
||||
|
||||
BUG_ON(i != lds->num_active);
|
||||
|
||||
lds->last_num_active = lds->num_active;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -491,18 +531,22 @@ int vmw_kms_init_legacy_display_system(struct vmw_private *dev_priv)
|
||||
|
||||
INIT_LIST_HEAD(&dev_priv->ldu_priv->active);
|
||||
dev_priv->ldu_priv->num_active = 0;
|
||||
dev_priv->ldu_priv->last_num_active = 0;
|
||||
dev_priv->ldu_priv->fb = NULL;
|
||||
|
||||
drm_mode_create_dirty_info_property(dev_priv->dev);
|
||||
|
||||
vmw_ldu_init(dev_priv, 0);
|
||||
vmw_ldu_init(dev_priv, 1);
|
||||
vmw_ldu_init(dev_priv, 2);
|
||||
vmw_ldu_init(dev_priv, 3);
|
||||
vmw_ldu_init(dev_priv, 4);
|
||||
vmw_ldu_init(dev_priv, 5);
|
||||
vmw_ldu_init(dev_priv, 6);
|
||||
vmw_ldu_init(dev_priv, 7);
|
||||
/* for old hardware without multimon only enable one display */
|
||||
if (dev_priv->capabilities & SVGA_CAP_MULTIMON) {
|
||||
vmw_ldu_init(dev_priv, 1);
|
||||
vmw_ldu_init(dev_priv, 2);
|
||||
vmw_ldu_init(dev_priv, 3);
|
||||
vmw_ldu_init(dev_priv, 4);
|
||||
vmw_ldu_init(dev_priv, 5);
|
||||
vmw_ldu_init(dev_priv, 6);
|
||||
vmw_ldu_init(dev_priv, 7);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user