[Intel-gfx] drm/i915: Postpone plane readout until after encoder readout, v2.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Wed Aug 5 03:45:48 PDT 2015


From: Patrik Jakobsson <patrik.jakobsson at linux.intel.com>

When reading out hw state for planes we disable inactive planes which in
turn triggers an update of the watermarks. The update depends on the
crtc_clock being set which is done when reading out encoders. Thus
postpone the plane readout until after encoder readout.

This prevents a warning in skl_compute_linetime_wm() where pixel_rate
becomes 0 when crtc_clock is 0.

Changes since v1:
- Set all modes after all state is read out. (Maarten)

References: https://bugs.freedesktop.org/show_bug.cgi?id=91428
Signed-off-by: Patrik Jakobsson <patrik.jakobsson at linux.intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index df237ad4a780..85d52158d476 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -15042,27 +15042,25 @@ static bool primary_get_hw_state(struct intel_crtc *crtc)
 	return !!(I915_READ(DSPCNTR(crtc->plane)) & DISPLAY_PLANE_ENABLE);
 }
 
-static void readout_plane_state(struct intel_crtc *crtc,
-				struct intel_crtc_state *crtc_state)
+static void intel_sanitize_plane(struct intel_plane *plane)
 {
-	struct intel_plane *p;
 	struct intel_plane_state *plane_state;
-	bool active = crtc_state->base.active;
+	struct intel_crtc *crtc;
 
-	for_each_intel_plane(crtc->base.dev, p) {
-		if (crtc->pipe != p->pipe)
-			continue;
+	plane_state = to_intel_plane_state(plane->base.state);
 
-		plane_state = to_intel_plane_state(p->base.state);
+	if (!plane_state->base.crtc)
+		return;
 
-		if (p->base.type == DRM_PLANE_TYPE_PRIMARY)
-			plane_state->visible = primary_get_hw_state(crtc);
-		else {
-			if (active)
-				p->disable_plane(&p->base, &crtc->base);
+	crtc = to_intel_crtc(plane_state->base.crtc);
 
-			plane_state->visible = false;
-		}
+	if (plane->base.type == DRM_PLANE_TYPE_PRIMARY) {
+		plane_state->visible = primary_get_hw_state(crtc);
+	} else {
+		if (crtc->base.state->active)
+			plane->disable_plane(&plane->base, &crtc->base);
+
+		plane_state->visible = false;
 	}
 }
 
@@ -15086,35 +15084,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		crtc->base.state->active = crtc->active;
 		crtc->base.enabled = crtc->active;
 
-		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
-		if (crtc->base.state->active) {
-			intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
-			intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
-			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
-
-			/*
-			 * The initial mode needs to be set in order to keep
-			 * the atomic core happy. It wants a valid mode if the
-			 * crtc's enabled, so we do the above call.
-			 *
-			 * At this point some state updated by the connectors
-			 * in their ->detect() callback has not run yet, so
-			 * no recalculation can be done yet.
-			 *
-			 * Even if we could do a recalculation and modeset
-			 * right now it would cause a double modeset if
-			 * fbdev or userspace chooses a different initial mode.
-			 *
-			 * If that happens, someone indicated they wanted a
-			 * mode change, which means it's safe to do a full
-			 * recalculation.
-			 */
-			crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
-		}
-
-		crtc->base.hwmode = crtc->config->base.adjusted_mode;
-		readout_plane_state(crtc, to_intel_crtc_state(crtc->base.state));
-
 		DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n",
 			      crtc->base.base.id,
 			      crtc->active ? "enabled" : "disabled");
@@ -15184,6 +15153,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
 	enum pipe pipe;
 	struct intel_crtc *crtc;
 	struct intel_encoder *encoder;
+	struct intel_plane *plane;
 	int i;
 
 	intel_modeset_readout_hw_state(dev);
@@ -15195,6 +15165,40 @@ intel_modeset_setup_hw_state(struct drm_device *dev)
 
 	for_each_pipe(dev_priv, pipe) {
 		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+		crtc->base.hwmode = crtc->config->base.adjusted_mode;
+		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
+		if (crtc->base.state->active) {
+			intel_mode_from_pipe_config(&crtc->base.mode, crtc->config);
+			intel_mode_from_pipe_config(&crtc->base.state->adjusted_mode, crtc->config);
+			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+
+			/*
+			 * The initial mode needs to be set in order to keep
+			 * the atomic core happy. It wants a valid mode if the
+			 * crtc's enabled, so we do the above call.
+			 *
+			 * At this point some state updated by the connectors
+			 * in their ->detect() callback has not run yet, so
+			 * no recalculation can be done yet.
+			 *
+			 * Even if we could do a recalculation and modeset
+			 * right now it would cause a double modeset if
+			 * fbdev or userspace chooses a different initial mode.
+			 *
+			 * If that happens, someone indicated they wanted a
+			 * mode change, which means it's safe to do a full
+			 * recalculation.
+			 */
+			crtc->base.state->mode.private_flags = I915_MODE_FLAG_INHERITED;
+		}
+
+		for_each_intel_plane(crtc->base.dev, plane) {
+			if (crtc->pipe != plane->pipe)
+				continue;
+
+			intel_sanitize_plane(plane);
+		}
+
 		intel_sanitize_crtc(crtc);
 		intel_dump_pipe_config(crtc, crtc->config,
 				       "[setup_hw_state]");



More information about the Intel-gfx mailing list