summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
diff options
context:
space:
mode:
authorSinclair Yeh <syeh@vmware.com>2017-03-23 14:18:32 -0700
committerSinclair Yeh <syeh@vmware.com>2017-03-31 13:37:03 -0700
commit060e2ad57041b42ccecd0047ef4d893f200692c2 (patch)
treec81a5a4b61edb5017d0aa1b3c79f102c271f98e7 /drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
parent06ec41909e31be3347f8679e9667d12ac6f7ee6e (diff)
downloadlinux-060e2ad57041b42ccecd0047ef4d893f200692c2.tar.gz
linux-060e2ad57041b42ccecd0047ef4d893f200692c2.tar.bz2
linux-060e2ad57041b42ccecd0047ef4d893f200692c2.zip
drm/vmwgfx: Add and connect plane helper functions
Refactor previous FB and cursor plane update code into their atomic counterparts: check, update, prepare, cleanup, and disable. These helpers won't be called until we flip on the atomic support flag or set drm_crtc_funcs->set_config to using the atomic helper. v2: * Removed unnecessary pinning of cursor surface * Added a few function headers v3: * Set clip region equal to the destination region * Fixed surface pinning policy * Enable SVGA mode in vmw_sou_primary_plane_prepare_fb Signed-off-by: Sinclair Yeh <syeh@vmware.com> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index 662024c9f351..eca055ec27c8 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -612,6 +612,100 @@ static const struct drm_connector_funcs vmw_sou_connector_funcs = {
* Screen Object Display Plane Functions
*/
+/**
+ * vmw_sou_primary_plane_cleanup_fb - Frees sou backing buffer
+ *
+ * @plane: display plane
+ * @old_state: Contains the FB to clean up
+ *
+ * Unpins the display surface
+ *
+ * Returns 0 on success
+ */
+static void
+vmw_sou_primary_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
+
+ vmw_dmabuf_unreference(&vps->dmabuf);
+ vps->dmabuf_size = 0;
+
+ vmw_du_plane_cleanup_fb(plane, old_state);
+}
+
+
+/**
+ * vmw_sou_primary_plane_prepare_fb - allocate backing buffer
+ *
+ * @plane: display plane
+ * @new_state: info on the new plane state, including the FB
+ *
+ * The SOU backing buffer is our equivalent of the display plane.
+ *
+ * Returns 0 on success
+ */
+static int
+vmw_sou_primary_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *new_state)
+{
+ struct drm_framebuffer *new_fb = new_state->fb;
+ struct drm_crtc *crtc = plane->state->crtc ?: new_state->crtc;
+ struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
+ struct vmw_private *dev_priv;
+ size_t size;
+ int ret;
+
+
+ if (!new_fb) {
+ vmw_dmabuf_unreference(&vps->dmabuf);
+ vps->dmabuf_size = 0;
+
+ return 0;
+ }
+
+ size = new_state->crtc_w * new_state->crtc_h * 4;
+
+ if (vps->dmabuf) {
+ if (vps->dmabuf_size == size)
+ return 0;
+
+ vmw_dmabuf_unreference(&vps->dmabuf);
+ vps->dmabuf_size = 0;
+ }
+
+ vps->dmabuf = kzalloc(sizeof(*vps->dmabuf), GFP_KERNEL);
+ if (!vps->dmabuf)
+ return -ENOMEM;
+
+ dev_priv = vmw_priv(crtc->dev);
+ vmw_svga_enable(dev_priv);
+
+ /* After we have alloced the backing store might not be able to
+ * resume the overlays, this is preferred to failing to alloc.
+ */
+ vmw_overlay_pause_all(dev_priv);
+ ret = vmw_dmabuf_init(dev_priv, vps->dmabuf, size,
+ &vmw_vram_ne_placement,
+ false, &vmw_dmabuf_bo_free);
+ vmw_overlay_resume_all(dev_priv);
+
+ if (ret != 0)
+ vps->dmabuf = NULL; /* vmw_dmabuf_init frees on error */
+ else
+ vps->dmabuf_size = size;
+
+ return ret;
+}
+
+
+static void
+vmw_sou_primary_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+}
+
+
static const struct drm_plane_funcs vmw_sou_plane_funcs = {
.update_plane = drm_primary_helper_update,
.disable_plane = drm_primary_helper_disable,
@@ -633,6 +727,22 @@ static const struct drm_plane_funcs vmw_sou_cursor_funcs = {
/*
* Atomic Helpers
*/
+static const struct
+drm_plane_helper_funcs vmw_sou_cursor_plane_helper_funcs = {
+ .atomic_check = vmw_du_cursor_plane_atomic_check,
+ .atomic_update = vmw_du_cursor_plane_atomic_update,
+ .prepare_fb = vmw_du_cursor_plane_prepare_fb,
+ .cleanup_fb = vmw_du_plane_cleanup_fb,
+};
+
+static const struct
+drm_plane_helper_funcs vmw_sou_primary_plane_helper_funcs = {
+ .atomic_check = vmw_du_primary_plane_atomic_check,
+ .atomic_update = vmw_sou_primary_plane_atomic_update,
+ .prepare_fb = vmw_sou_primary_plane_prepare_fb,
+ .cleanup_fb = vmw_sou_primary_plane_cleanup_fb,
+};
+
static const struct drm_crtc_helper_funcs vmw_sou_crtc_helper_funcs = {
.prepare = vmw_sou_crtc_helper_prepare,
.commit = vmw_sou_crtc_helper_commit,
@@ -691,6 +801,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
goto err_free;
}
+ drm_plane_helper_add(primary, &vmw_sou_primary_plane_helper_funcs);
+
/* Initialize cursor plane */
vmw_du_plane_reset(cursor);
@@ -705,6 +817,9 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
goto err_free;
}
+ drm_plane_helper_add(cursor, &vmw_sou_cursor_plane_helper_funcs);
+
+ vmw_du_connector_reset(connector);
ret = drm_connector_init(dev, connector, &vmw_sou_connector_funcs,
DRM_MODE_CONNECTOR_VIRTUAL);
if (ret) {