From 6987427a3953c5038dc14d2a090b5a6c93669428 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 2 Nov 2011 09:43:11 +0100 Subject: [PATCH] vmwgfx: Infrastructure for explicit placement Make it possible to use explicit placement (although not hooked up with a user-space interface yet) and relax the single framebuffer limit to only apply to implicit placement. Signed-off-by: Thomas Hellstrom Reviewed-by: Jakob Bornecrantz Signed-off-by: Dave Airlie --- drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | 52 +++++++++++++++------------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index 815cf99ce06..af8e6e5bd96 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h @@ -102,6 +102,7 @@ struct vmw_display_unit { */ int gui_x; int gui_y; + bool is_implicit; }; #define vmw_crtc_to_du(x) \ diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index bbfe3819491..90c5e392849 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -337,6 +337,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ldu->base.pref_width = 800; ldu->base.pref_height = 600; ldu->base.pref_mode = NULL; + ldu->base.is_implicit = true; drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index ea6583433a1..4defdcf1c72 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -36,9 +36,9 @@ container_of(x, struct vmw_screen_object_unit, base.connector) struct vmw_screen_object_display { - unsigned num_active; + unsigned num_implicit; - struct vmw_framebuffer *fb; + struct vmw_framebuffer *implicit_fb; }; /** @@ -51,7 +51,7 @@ struct vmw_screen_object_unit { struct vmw_dma_buffer *buffer; /**< Backing store buffer */ bool defined; - bool active; + bool active_implicit; }; static void vmw_sou_destroy(struct vmw_screen_object_unit *sou) @@ -75,10 +75,10 @@ static void vmw_sou_del_active(struct vmw_private *vmw_priv, { struct vmw_screen_object_display *ld = vmw_priv->sou_priv; - if (sou->active) { - if (--(ld->num_active) == 0) - ld->fb = NULL; - sou->active = false; + if (sou->active_implicit) { + if (--(ld->num_implicit) == 0) + ld->implicit_fb = NULL; + sou->active_implicit = false; } } @@ -88,12 +88,12 @@ static void vmw_sou_add_active(struct vmw_private *vmw_priv, { struct vmw_screen_object_display *ld = vmw_priv->sou_priv; - BUG_ON(!ld->num_active && ld->fb); + BUG_ON(!ld->num_implicit && ld->implicit_fb); - if (!sou->active) { - ld->fb = vfb; - sou->active = true; - ld->num_active++; + if (!sou->active_implicit && sou->base.is_implicit) { + ld->implicit_fb = vfb; + sou->active_implicit = true; + ld->num_implicit++; } } @@ -132,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, (sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0); cmd->obj.size.width = mode->hdisplay; cmd->obj.size.height = mode->vdisplay; - cmd->obj.root.x = x; - cmd->obj.root.y = y; + if (sou->base.is_implicit) { + cmd->obj.root.x = x; + cmd->obj.root.y = y; + } else { + cmd->obj.root.x = sou->base.gui_x; + cmd->obj.root.y = sou->base.gui_y; + } /* Ok to assume that buffer is pinned in vram */ vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); @@ -280,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set) } /* sou only supports one fb active at the time */ - if (dev_priv->sou_priv->fb && vfb && - !(dev_priv->sou_priv->num_active == 1 && - sou->active) && - dev_priv->sou_priv->fb != vfb) { + if (sou->base.is_implicit && + dev_priv->sou_priv->implicit_fb && vfb && + !(dev_priv->sou_priv->num_implicit == 1 && + sou->active_implicit) && + dev_priv->sou_priv->implicit_fb != vfb) { DRM_ERROR("Multiple framebuffers not supported\n"); return -EINVAL; } @@ -439,12 +445,13 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) encoder = &sou->base.encoder; connector = &sou->base.connector; - sou->active = false; + sou->active_implicit = false; sou->base.pref_active = (unit == 0); sou->base.pref_width = 800; sou->base.pref_height = 600; sou->base.pref_mode = NULL; + sou->base.is_implicit = true; drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, DRM_MODE_CONNECTOR_VIRTUAL); @@ -488,8 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv) if (unlikely(!dev_priv->sou_priv)) goto err_no_mem; - dev_priv->sou_priv->num_active = 0; - dev_priv->sou_priv->fb = NULL; + dev_priv->sou_priv->num_implicit = 0; + dev_priv->sou_priv->implicit_fb = NULL; ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS); if (unlikely(ret != 0)) @@ -524,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv) drm_vblank_cleanup(dev); - if (dev_priv->sou_priv->num_active > 0) - DRM_ERROR("Still have active outputs when unloading driver"); - kfree(dev_priv->sou_priv); return 0; -- 2.20.1