drm/i915/overlay: Use non-atomic mappings for the common case.

The only time where an atomic mapping is required is during
error-capture and there we cannot use the default slot, but need to
specifically use one of the IRQ slots. So separate out the two
conditions and use the atomic mapping only when appropriate.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index df5277a..0c13e1b 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -173,7 +173,9 @@
 /* overlay flip addr flag */
 #define OFC_UPDATE		0x1
 
-static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
+static struct overlay_registers *
+intel_overlay_map_regs_atomic(struct intel_overlay *overlay,
+			      int slot)
 {
         drm_i915_private_t *dev_priv = overlay->dev->dev_private;
 	struct overlay_registers *regs;
@@ -186,7 +188,7 @@
 	} else {
 		regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
 						overlay->reg_bo->gtt_offset,
-						KM_USER0);
+						slot);
 
 		if (!regs) {
 			DRM_ERROR("failed to map overlay regs in GTT\n");
@@ -197,10 +199,45 @@
 	return overlay->virt_addr = regs;
 }
 
-static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay)
+static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
+				     int slot)
 {
 	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
-		io_mapping_unmap_atomic(overlay->virt_addr, KM_USER0);
+		io_mapping_unmap_atomic(overlay->virt_addr, slot);
+
+	overlay->virt_addr = NULL;
+
+	return;
+}
+
+static struct overlay_registers *
+intel_overlay_map_regs(struct intel_overlay *overlay)
+{
+        drm_i915_private_t *dev_priv = overlay->dev->dev_private;
+	struct overlay_registers *regs;
+
+	/* no recursive mappings */
+	BUG_ON(overlay->virt_addr);
+
+	if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) {
+		regs = overlay->reg_bo->phys_obj->handle->vaddr;
+	} else {
+		regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
+					 overlay->reg_bo->gtt_offset);
+
+		if (!regs) {
+			DRM_ERROR("failed to map overlay regs in GTT\n");
+			return NULL;
+		}
+	}
+
+	return overlay->virt_addr = regs;
+}
+
+static void intel_overlay_unmap_regs(struct intel_overlay *overlay)
+{
+	if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
+		io_mapping_unmap(overlay->virt_addr);
 
 	overlay->virt_addr = NULL;
 
@@ -467,7 +504,8 @@
 
 /* Wait for pending overlay flip and release old frame.
  * Needs to be called before the overlay register are changed
- * via intel_overlay_(un)map_regs_atomic */
+ * via intel_overlay_(un)map_regs
+ */
 static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
 {
 	int ret;
@@ -770,7 +808,7 @@
 		goto out_unpin;
 
 	if (!overlay->active) {
-		regs = intel_overlay_map_regs_atomic(overlay);
+		regs = intel_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unpin;
@@ -780,14 +818,14 @@
 			regs->OCONFIG |= OCONF_CSC_MODE_BT709;
 		regs->OCONFIG |= overlay->crtc->pipe == 0 ?
 			OCONF_PIPE_A : OCONF_PIPE_B;
-		intel_overlay_unmap_regs_atomic(overlay);
+		intel_overlay_unmap_regs(overlay);
 
 		ret = intel_overlay_on(overlay);
 		if (ret != 0)
 			goto out_unpin;
 	}
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_overlay_map_regs(overlay);
 	if (!regs) {
 		ret = -ENOMEM;
 		goto out_unpin;
@@ -830,7 +868,7 @@
 
 	regs->OCMD = overlay_cmd_reg(params);
 
-	intel_overlay_unmap_regs_atomic(overlay);
+	intel_overlay_unmap_regs(overlay);
 
 	intel_overlay_continue(overlay, scale_changed);
 
@@ -866,9 +904,9 @@
 	if (ret != 0)
 		return ret;
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_overlay_map_regs(overlay);
 	regs->OCMD = 0;
-	intel_overlay_unmap_regs_atomic(overlay);
+	intel_overlay_unmap_regs(overlay);
 
 	ret = intel_overlay_off(overlay);
 	if (ret != 0)
@@ -1314,7 +1352,7 @@
 			goto out_unlock;
 		}
 
-		regs = intel_overlay_map_regs_atomic(overlay);
+		regs = intel_overlay_map_regs(overlay);
 		if (!regs) {
 			ret = -ENOMEM;
 			goto out_unlock;
@@ -1322,7 +1360,7 @@
 
 		update_reg_attrs(overlay, regs);
 
-		intel_overlay_unmap_regs_atomic(overlay);
+		intel_overlay_unmap_regs(overlay);
 
 		if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
 			if (!IS_I9XX(dev)) {
@@ -1407,7 +1445,7 @@
 	overlay->contrast = 75;
 	overlay->saturation = 146;
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_overlay_map_regs(overlay);
 	if (!regs)
 		goto out_free_bo;
 
@@ -1416,7 +1454,7 @@
 
 	update_reg_attrs(overlay, regs);
 
-	intel_overlay_unmap_regs_atomic(overlay);
+	intel_overlay_unmap_regs(overlay);
 
 	dev_priv->overlay = overlay;
 	DRM_INFO("initialized overlay support\n");
@@ -1474,12 +1512,12 @@
 	else
 		error->base = (long) overlay->reg_bo->gtt_offset;
 
-	regs = intel_overlay_map_regs_atomic(overlay);
+	regs = intel_overlay_map_regs_atomic(overlay, KM_IRQ0);
 	if (!regs)
 		goto err;
 
 	memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
-	intel_overlay_unmap_regs_atomic(overlay);
+	intel_overlay_unmap_regs_atomic(overlay, KM_IRQ0);
 
 	return error;