diff mbox

[1/2] drm/i915: Creating a new workqueue to handle MMIO flip work items

Message ID 1389266799-13317-2-git-send-email-akash.goel@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

akash.goel@intel.com Jan. 9, 2014, 11:26 a.m. UTC
From: Akash Goel <akash.goel@intel.com>

MMIO flips will replace the blitter command streamer based flips on VLV.
Created our own private workqueue for handling the MMIO based flips,
so as to avoid the block of the display thread (who issued the flip ioctl),
due to the synchronization needed between the Rendering & flip stages.
Now with MMIO based flips, the synchronization will require a wait in sw
for the ongoing rendering operation, if any, to complete before issuing
the flip. Because of this work queue, the wait on rendering to complete
would be done by the worker thread.

Signed-off-by: Akash Goel <akash.goel@intel.com>
---
 drivers/gpu/drm/i915/i915_dma.c | 25 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_drv.h |  1 +
 2 files changed, 26 insertions(+)
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index ee9502b..ee4b445 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1609,6 +1609,29 @@  int i915_driver_load(struct drm_device *dev, unsigned long flags)
 		goto out_mtrrfree;
 	}
 
+	/*
+	 * Creating our own private workqueue for handling the
+	 * MMIO based flips. This is to avoid the block of the
+	 * display thread (who issued the flip ioctl), due to the
+	 * synchronization needed between the Rendering & flip stages.
+	 * Now with MMIO based flips, the synchronization will require a
+	 * wait in sw for the ongoing rendering operation, if any, to
+	 * complete before issuing the flip. Because of this work queue,
+	 * the wait on rendering would be done by the worker thread.
+	 *
+	 * Also since the flip work has to be processed at earliest,
+	 * HIGHPRI flag is used here. We also use an ordered one, as
+	 * we need serialized execution but anyways we support one
+	 * outstanding flip call only, so probably doesn't really matter.
+	 */
+	dev_priv->flipwq = alloc_ordered_workqueue("i915_flip", WQ_HIGHPRI);
+	if (dev_priv->flipwq == NULL) {
+		DRM_ERROR("Failed to create flip workqueue.\n");
+		ret = -ENOMEM;
+		destroy_workqueue(dev_priv->wq);
+		goto out_mtrrfree;
+	}
+
 	intel_irq_init(dev);
 	intel_uncore_sanitize(dev);
 
@@ -1685,6 +1708,7 @@  out_gem_unload:
 
 	intel_teardown_gmbus(dev);
 	intel_teardown_mchbar(dev);
+	destroy_workqueue(dev_priv->flipwq);
 	destroy_workqueue(dev_priv->wq);
 out_mtrrfree:
 	arch_phys_wc_del(dev_priv->gtt.mtrr);
@@ -1792,6 +1816,7 @@  int i915_driver_unload(struct drm_device *dev)
 	intel_teardown_mchbar(dev);
 
 	destroy_workqueue(dev_priv->wq);
+	destroy_workqueue(dev_priv->flipwq);
 	pm_qos_remove_request(&dev_priv->pm_qos);
 
 	dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index cc8afff..2e22430 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1451,6 +1451,7 @@  typedef struct drm_i915_private {
 	 * result in deadlocks.
 	 */
 	struct workqueue_struct *wq;
+	struct workqueue_struct *flipwq;
 
 	/* Display functions */
 	struct drm_i915_display_funcs display;