drm/vmwgfx: Break out implicit fb code
authorThomas Hellstrom <thellstrom@vmware.com>
Fri, 12 Feb 2016 08:00:26 +0000 (09:00 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Mon, 14 Mar 2016 13:57:56 +0000 (14:57 +0100)
Preparation for supporting explicit fbs for screen objects and screen
targets.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c

index 5cb1b16..b92521d 100644 (file)
@@ -407,8 +407,9 @@ struct vmw_private {
        void *fb_info;
        enum vmw_display_unit_type active_display_unit;
        struct vmw_legacy_display *ldu_priv;
-       struct vmw_screen_object_display *sou_priv;
        struct vmw_overlay *overlay_priv;
+       unsigned num_implicit;
+       struct vmw_framebuffer *implicit_fb;
 
        /*
         * Context and surface management.
index 29bec97..26c2e9e 100644 (file)
@@ -2095,3 +2095,95 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
 
        return 0;
 }
+
+/**
+ * vmw_kms_del_active - unregister a crtc binding to the implicit framebuffer
+ *
+ * @dev_priv: Pointer to a device private struct.
+ * @du: The display unit of the crtc.
+ */
+void vmw_kms_del_active(struct vmw_private *dev_priv,
+                       struct vmw_display_unit *du)
+{
+       lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+
+       if (du->active_implicit) {
+               if (--(dev_priv->num_implicit) == 0)
+                       dev_priv->implicit_fb = NULL;
+               du->active_implicit = false;
+       }
+}
+
+/**
+ * vmw_kms_add_active - register a crtc binding to an implicit framebuffer
+ *
+ * @vmw_priv: Pointer to a device private struct.
+ * @du: The display unit of the crtc.
+ * @vfb: The implicit framebuffer
+ *
+ * Registers a binding to an implicit framebuffer.
+ */
+void vmw_kms_add_active(struct vmw_private *dev_priv,
+                       struct vmw_display_unit *du,
+                       struct vmw_framebuffer *vfb)
+{
+       lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+
+       WARN_ON_ONCE(!dev_priv->num_implicit && dev_priv->implicit_fb);
+
+       if (!du->active_implicit && du->is_implicit) {
+               dev_priv->implicit_fb = vfb;
+               du->active_implicit = true;
+               dev_priv->num_implicit++;
+       }
+}
+
+/**
+ * vmw_kms_screen_object_flippable - Check whether we can page-flip a crtc.
+ *
+ * @dev_priv: Pointer to device-private struct.
+ * @crtc: The crtc we want to flip.
+ *
+ * Returns true or false depending whether it's OK to flip this crtc
+ * based on the criterion that we must not have more than one implicit
+ * frame-buffer at any one time.
+ */
+bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
+                           struct drm_crtc *crtc)
+{
+       struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
+
+       lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+
+       if (!du->is_implicit)
+               return true;
+
+       if (dev_priv->num_implicit != 1)
+               return false;
+
+       return true;
+}
+
+/**
+ * vmw_kms_update_implicit_fb - Update the implicit fb.
+ *
+ * @dev_priv: Pointer to device-private struct.
+ * @crtc: The crtc the new implicit frame-buffer is bound to.
+ */
+void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
+                               struct drm_crtc *crtc)
+{
+       struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
+       struct vmw_framebuffer *vfb;
+
+       lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+
+       if (!du->is_implicit)
+               return;
+
+       vfb = vmw_framebuffer_to_vfb(crtc->primary->fb);
+       WARN_ON_ONCE(dev_priv->num_implicit != 1 &&
+                    dev_priv->implicit_fb != vfb);
+
+       dev_priv->implicit_fb = vfb;
+}
index d41928c..0b5c9ab 100644 (file)
@@ -178,6 +178,7 @@ struct vmw_display_unit {
        int gui_x;
        int gui_y;
        bool is_implicit;
+       bool active_implicit;
 };
 
 #define vmw_crtc_to_du(x) \
@@ -254,6 +255,17 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
                            struct drm_crtc **p_crtc,
                            struct drm_display_mode **p_mode);
 void vmw_guess_mode_timing(struct drm_display_mode *mode);
+void vmw_kms_del_active(struct vmw_private *dev_priv,
+                       struct vmw_display_unit *du);
+void vmw_kms_add_active(struct vmw_private *dev_priv,
+                       struct vmw_display_unit *du,
+                       struct vmw_framebuffer *vfb);
+bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
+                           struct drm_crtc *crtc);
+void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
+                               struct drm_crtc *crtc);
+
+
 
 /*
  * Legacy display unit functions - vmwgfx_ldu.c
index c0de3b8..c11b196 100644 (file)
@@ -74,19 +74,6 @@ struct vmw_kms_sou_dirty_cmd {
        SVGA3dCmdBlitSurfaceToScreen body;
 };
 
-
-/*
- * Other structs.
- */
-
-struct vmw_screen_object_display {
-       unsigned num_implicit;
-
-       struct vmw_framebuffer *implicit_fb;
-       SVGAFifoCmdDefineGMRFB cur;
-       struct vmw_dma_buffer *pinned_gmrfb;
-};
-
 /**
  * Display unit using screen objects.
  */
@@ -97,7 +84,6 @@ struct vmw_screen_object_unit {
        struct vmw_dma_buffer *buffer; /**< Backing store buffer */
 
        bool defined;
-       bool active_implicit;
 };
 
 static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
@@ -116,33 +102,6 @@ static void vmw_sou_crtc_destroy(struct drm_crtc *crtc)
        vmw_sou_destroy(vmw_crtc_to_sou(crtc));
 }
 
-static void vmw_sou_del_active(struct vmw_private *vmw_priv,
-                              struct vmw_screen_object_unit *sou)
-{
-       struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
-
-       if (sou->active_implicit) {
-               if (--(ld->num_implicit) == 0)
-                       ld->implicit_fb = NULL;
-               sou->active_implicit = false;
-       }
-}
-
-static void vmw_sou_add_active(struct vmw_private *vmw_priv,
-                              struct vmw_screen_object_unit *sou,
-                              struct vmw_framebuffer *vfb)
-{
-       struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
-
-       BUG_ON(!ld->num_implicit && ld->implicit_fb);
-
-       if (!sou->active_implicit && sou->base.is_implicit) {
-               ld->implicit_fb = vfb;
-               sou->active_implicit = true;
-               ld->num_implicit++;
-       }
-}
-
 /**
  * Send the fifo command to create a screen.
  */
@@ -323,13 +282,13 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
                return -EINVAL;
        }
 
-       /* sou only supports one fb active at the time */
+       /* Only one active implicit frame-buffer at a time. */
        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");
+           dev_priv->implicit_fb && vfb &&
+           !(dev_priv->num_implicit == 1 &&
+             sou->base.active_implicit) &&
+           dev_priv->implicit_fb != vfb) {
+               DRM_ERROR("Multiple implicit framebuffers not supported.\n");
                return -EINVAL;
        }
 
@@ -351,7 +310,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
                crtc->y = 0;
                crtc->enabled = false;
 
-               vmw_sou_del_active(dev_priv, sou);
+               vmw_kms_del_active(dev_priv, &sou->base);
 
                vmw_sou_backing_free(dev_priv, sou);
 
@@ -415,7 +374,7 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
                return ret;
        }
 
-       vmw_sou_add_active(dev_priv, sou, vfb);
+       vmw_kms_add_active(dev_priv, &sou->base, vfb);
 
        connector->encoder = encoder;
        encoder->crtc = crtc;
@@ -428,39 +387,6 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
        return 0;
 }
 
-/**
- * Returns if this unit can be page flipped.
- * Must be called with the mode_config mutex held.
- */
-static bool vmw_sou_screen_object_flippable(struct vmw_private *dev_priv,
-                                           struct drm_crtc *crtc)
-{
-       struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
-
-       if (!sou->base.is_implicit)
-               return true;
-
-       if (dev_priv->sou_priv->num_implicit != 1)
-               return false;
-
-       return true;
-}
-
-/**
- * Update the implicit fb to the current fb of this crtc.
- * Must be called with the mode_config mutex held.
- */
-static void vmw_sou_update_implicit_fb(struct vmw_private *dev_priv,
-                                      struct drm_crtc *crtc)
-{
-       struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
-
-       BUG_ON(!sou->base.is_implicit);
-
-       dev_priv->sou_priv->implicit_fb =
-               vmw_framebuffer_to_vfb(sou->base.crtc.primary->fb);
-}
-
 static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
                                  struct drm_framebuffer *fb,
                                  struct drm_pending_vblank_event *event,
@@ -473,11 +399,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
        struct drm_vmw_rect vclips;
        int ret;
 
-       /* require ScreenObject support for page flipping */
-       if (!dev_priv->sou_priv)
-               return -ENOSYS;
-
-       if (!vmw_sou_screen_object_flippable(dev_priv, crtc))
+       if (!vmw_kms_crtc_flippable(dev_priv, crtc))
                return -EINVAL;
 
        crtc->primary->fb = fb;
@@ -522,7 +444,7 @@ static int vmw_sou_crtc_page_flip(struct drm_crtc *crtc,
        vmw_fence_obj_unreference(&fence);
 
        if (vmw_crtc_to_du(crtc)->is_implicit)
-               vmw_sou_update_implicit_fb(dev_priv, crtc);
+               vmw_kms_update_implicit_fb(dev_priv, crtc);
 
        return ret;
 
@@ -587,8 +509,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
        encoder = &sou->base.encoder;
        connector = &sou->base.connector;
 
-       sou->active_implicit = false;
-
+       sou->base.active_implicit = false;
        sou->base.pref_active = (unit == 0);
        sou->base.pref_width = dev_priv->initial_width;
        sou->base.pref_height = dev_priv->initial_height;
@@ -623,11 +544,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
        struct drm_device *dev = dev_priv->dev;
        int i, ret;
 
-       if (dev_priv->sou_priv) {
-               DRM_INFO("sou system already on\n");
-               return -EINVAL;
-       }
-
        if (!(dev_priv->capabilities & SVGA_CAP_SCREEN_OBJECT_2)) {
                DRM_INFO("Not using screen objects,"
                         " missing cap SCREEN_OBJECT_2\n");
@@ -635,16 +551,12 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
        }
 
        ret = -ENOMEM;
-       dev_priv->sou_priv = kmalloc(sizeof(*dev_priv->sou_priv), GFP_KERNEL);
-       if (unlikely(!dev_priv->sou_priv))
-               goto err_no_mem;
-
-       dev_priv->sou_priv->num_implicit = 0;
-       dev_priv->sou_priv->implicit_fb = NULL;
+       dev_priv->num_implicit = 0;
+       dev_priv->implicit_fb = NULL;
 
        ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
        if (unlikely(ret != 0))
-               goto err_free;
+               return ret;
 
        ret = drm_mode_create_dirty_info_property(dev);
        if (unlikely(ret != 0))
@@ -661,10 +573,6 @@ int vmw_kms_sou_init_display(struct vmw_private *dev_priv)
 
 err_vblank_cleanup:
        drm_vblank_cleanup(dev);
-err_free:
-       kfree(dev_priv->sou_priv);
-       dev_priv->sou_priv = NULL;
-err_no_mem:
        return ret;
 }
 
@@ -672,13 +580,8 @@ int vmw_kms_sou_close_display(struct vmw_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
 
-       if (!dev_priv->sou_priv)
-               return -ENOSYS;
-
        drm_vblank_cleanup(dev);
 
-       kfree(dev_priv->sou_priv);
-
        return 0;
 }