@@ -159,4 +159,6 @@ MODULE_PARM_DESC(enable_cmd_parser,
"Enable command parsing (1=enabled [default], 0=disabled)");
module_param_named(use_mmio_flip, i915.use_mmio_flip, bool, 0600);
-MODULE_PARM_DESC(use_mmio_flip, "use MMIO flips (default: false)");
+MODULE_PARM_DESC(use_mmio_flip, "use MMIO page flips"
+ "(0 force CS, 1:force mmio, >1: driver selection)"
+ "(default: 0)");
@@ -9185,22 +9185,50 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
static bool intel_use_mmio_flip(struct drm_device *dev)
{
- /* If module parameter is disabled, use CS flips.
- * Otherwise, use MMIO flips starting from Gen5.
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ bool use_mmio_flip = false;
+
+ /* If module parameter is 0, force CS flip.
+ * If module parameter is 1, force MMIO flip starting from Gen5.
* This is not being used for older platforms, because
* non-availability of flip done interrupt forces us to use
* CS flips. Older platforms derive flip done using some clever
* tricks involving the flip_pending status bits and vblank irqs.
* So using MMIO flips there would disrupt this mechanism.
+ * If module parameter is > 1, driver discretion is applied for
+ * selection of CS vs MMIO flip.
*/
if (i915.use_mmio_flip == 0)
- return false;
+ use_mmio_flip = false;
- if (INTEL_INFO(dev)->gen >= 5)
- return true;
- else
- return false;
+ if (i915.use_mmio_flip == 1) {
+ if (INTEL_INFO(dev)->gen >= 5)
+ use_mmio_flip = true;
+ else
+ use_mmio_flip = false;
+ }
+
+ if (i915.use_mmio_flip > 1) {
+ /* For Valleyview, Blitter and Video engines are in the same
+ * power well. So, if both are idle, we can use MMIO flips,
+ * Otherwise, we can use the BCS flips.
+ * We use the parameter 'request_list' to determine the idleness
+ * of the engine.
+ */
+ if (IS_VALLEYVIEW(dev)) {
+ struct intel_engine_cs *bcs_ring = &dev_priv->ring[BCS];
+ struct intel_engine_cs *vcs_ring = &dev_priv->ring[VCS];
+
+ if (list_empty(&bcs_ring->request_list) &&
+ list_empty(&vcs_ring->request_list))
+ use_mmio_flip = true;
+ else
+ use_mmio_flip = false;
+ } else
+ use_mmio_flip = false;
+ }
+ return use_mmio_flip;
}
static void intel_do_mmio_flip(struct intel_crtc *intel_crtc)