[Intel-gfx] [PATCH] drm: Propagate failure from setting crtc base.

Chris Wilson chris at chris-wilson.co.uk
Wed Feb 11 15:26:29 CET 2009


Check the error paths within intel_pipe_set_base() to first cleanup and
then report back the error.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/drm_crtc_helper.c    |   13 ++++--
 drivers/gpu/drm/i915/intel_display.c |   75 ++++++++++++++++++++++------------
 include/drm/drm_crtc_helper.h        |   10 ++--
 3 files changed, 63 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 964c5eb..7203fb2 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -512,8 +512,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 	if (drm_mode_equal(&saved_mode, &crtc->mode)) {
 		if (saved_x != crtc->x || saved_y != crtc->y ||
 		    depth_changed || bpp_changed) {
-			crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
-						  old_fb);
+			ret = crtc_funcs->mode_set_base(crtc, crtc->x, crtc->y,
+							old_fb);
 			goto done;
 		}
 	}
@@ -552,7 +552,9 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
 	/* Set up the DPLL and any encoders state that needs to adjust or depend
 	 * on the DPLL.
 	 */
-	crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+	ret = crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
+	if (ret != 0)
+	    goto done;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 
@@ -765,7 +767,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
 		old_fb = set->crtc->fb;
 		if (set->crtc->fb != set->fb)
 			set->crtc->fb = set->fb;
-		crtc_funcs->mode_set_base(set->crtc, set->x, set->y, old_fb);
+		ret = crtc_funcs->mode_set_base(set->crtc,
+						set->x, set->y, old_fb);
+		if (ret != 0)
+		    goto fail_set_mode;
 	}
 
 	kfree(save_encoders);
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bbdd729..53ce69c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -343,7 +343,7 @@ intel_wait_for_vblank(struct drm_device *dev)
 	udelay(20000);
 }
 
-static void
+static int
 intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		    struct drm_framebuffer *old_fb)
 {
@@ -361,11 +361,21 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
 	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 	u32 dspcntr, alignment;
+	int ret;
 
 	/* no fb bound */
 	if (!crtc->fb) {
 		DRM_DEBUG("No FB bound\n");
-		return;
+		return 0;
+	}
+
+	switch (pipe) {
+	case 0:
+	case 1:
+		break;
+	default:
+		DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
+		return -EINVAL;
 	}
 
 	intel_fb = to_intel_framebuffer(crtc->fb);
@@ -385,15 +395,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 	case I915_TILING_Y:
 		/* FIXME: Is this true? */
 		DRM_ERROR("Y tiled not allowed for scan out buffers\n");
-		return;
+		return -EINVAL;
 	default:
 		BUG();
 	}
 
-	if (i915_gem_object_pin(intel_fb->obj, alignment))
-		return;
+	mutex_lock(&dev->struct_mutex);
+	ret = i915_gem_object_pin(intel_fb->obj, alignment);
+	if (ret != 0) {
+		mutex_unlock(&dev->struct_mutex);
+		return ret;
+	}
 
-	i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+	ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1);
+	if (ret != 0) {
+		i915_gem_object_unpin(intel_fb->obj);
+		mutex_unlock(&dev->struct_mutex);
+		return ret;
+	}
 
 	Start = obj_priv->gtt_offset;
 	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
@@ -419,7 +438,9 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		break;
 	default:
 		DRM_ERROR("Unknown color depth\n");
-		return;
+		i915_gem_object_unpin(intel_fb->obj);
+		mutex_unlock(&dev->struct_mutex);
+		return -EINVAL;
 	}
 	I915_WRITE(dspcntr_reg, dspcntr);
 
@@ -440,27 +461,24 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
 		intel_fb = to_intel_framebuffer(old_fb);
 		i915_gem_object_unpin(intel_fb->obj);
 	}
+	mutex_unlock(&dev->struct_mutex);
 
 	if (!dev->primary->master)
-		return;
+		return 0;
 
 	master_priv = dev->primary->master->driver_priv;
 	if (!master_priv->sarea_priv)
-		return;
+		return 0;
 
-	switch (pipe) {
-	case 0:
-		master_priv->sarea_priv->pipeA_x = x;
-		master_priv->sarea_priv->pipeA_y = y;
-		break;
-	case 1:
+	if (pipe) {
 		master_priv->sarea_priv->pipeB_x = x;
 		master_priv->sarea_priv->pipeB_y = y;
-		break;
-	default:
-		DRM_ERROR("Can't update pipe %d in SAREA\n", pipe);
-		break;
+	} else {
+		master_priv->sarea_priv->pipeA_x = x;
+		master_priv->sarea_priv->pipeA_y = y;
 	}
+
+	return 0;
 }
 
 
@@ -708,11 +726,11 @@ static int intel_panel_fitter_pipe (struct drm_device *dev)
 	return 1;
 }
 
-static void intel_crtc_mode_set(struct drm_crtc *crtc,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode,
-				int x, int y,
-				struct drm_framebuffer *old_fb)
+static int intel_crtc_mode_set(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode,
+			       int x, int y,
+			       struct drm_framebuffer *old_fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -739,6 +757,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 	bool is_crt = false, is_lvds = false, is_tv = false;
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
+	int ret;
 
 	drm_vblank_pre_modeset(dev, pipe);
 
@@ -779,7 +798,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 	ok = intel_find_best_PLL(crtc, adjusted_mode->clock, refclk, &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
-		return;
+		return -EINVAL;
 	}
 
 	fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
@@ -950,9 +969,13 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 	I915_WRITE(dspcntr_reg, dspcntr);
 
 	/* Flush the plane changes */
-	intel_pipe_set_base(crtc, x, y, old_fb);
+	ret = intel_pipe_set_base(crtc, x, y, old_fb);
+	if (ret != 0)
+	    return ret;
 
 	drm_vblank_post_modeset(dev, pipe);
+
+	return 0;
 }
 
 /** Loads the palette/gamma unit for the CRTC with the prepared values */
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 0c6f0e1..0b0d236 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -54,13 +54,13 @@ struct drm_crtc_helper_funcs {
 			   struct drm_display_mode *mode,
 			   struct drm_display_mode *adjusted_mode);
 	/* Actually set the mode */
-	void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
-			 struct drm_display_mode *adjusted_mode, int x, int y,
-			 struct drm_framebuffer *old_fb);
+	int (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
+			struct drm_display_mode *adjusted_mode, int x, int y,
+			struct drm_framebuffer *old_fb);
 
 	/* Move the crtc on the current fb to the given position *optional* */
-	void (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
-			      struct drm_framebuffer *old_fb);
+	int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
+			     struct drm_framebuffer *old_fb);
 };
 
 struct drm_encoder_helper_funcs {
-- 
1.6.0.4




More information about the Intel-gfx mailing list