浏览代码

drm/i915: push DDI CRT underrun reporting on enable to encoder

CRT being the only PCH encoder, we can simplify the crtc enable by
pushing the PCH encoder specific parts to CRT encoder.

v2: add separate hsw_enable_crt (Daniel), rebase

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/b117fb524fc571837c83292194fc2ad35e588ec9.1507200657.git.jani.nikula@intel.com
Jani Nikula 8 年之前
父节点
当前提交
51c4fa6903
共有 2 个文件被更改,包括 51 次插入14 次删除
  1. 50 1
      drivers/gpu/drm/i915/intel_crt.c
  2. 1 13
      drivers/gpu/drm/i915/intel_display.c

+ 50 - 1
drivers/gpu/drm/i915/intel_crt.c

@@ -227,6 +227,52 @@ static void hsw_post_disable_crt(struct intel_encoder *encoder,
 	intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state);
 	intel_ddi_fdi_post_disable(encoder, old_crtc_state, old_conn_state);
 }
 }
 
 
+static void hsw_pre_pll_enable_crt(struct intel_encoder *encoder,
+				   const struct intel_crtc_state *pipe_config,
+				   const struct drm_connector_state *conn_state)
+{
+	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	WARN_ON(!intel_crtc->config->has_pch_encoder);
+
+	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
+}
+
+static void hsw_pre_enable_crt(struct intel_encoder *encoder,
+			       const struct intel_crtc_state *pipe_config,
+			       const struct drm_connector_state *conn_state)
+{
+	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	WARN_ON(!intel_crtc->config->has_pch_encoder);
+
+	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
+}
+
+static void hsw_enable_crt(struct intel_encoder *encoder,
+			   const struct intel_crtc_state *pipe_config,
+			   const struct drm_connector_state *conn_state)
+{
+	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+
+	WARN_ON(!intel_crtc->config->has_pch_encoder);
+
+	intel_crt_set_dpms(encoder, pipe_config, DRM_MODE_DPMS_ON);
+
+	intel_wait_for_vblank(dev_priv, pipe);
+	intel_wait_for_vblank(dev_priv, pipe);
+	intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
+	intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
+}
+
 static void intel_enable_crt(struct intel_encoder *encoder,
 static void intel_enable_crt(struct intel_encoder *encoder,
 			     const struct intel_crtc_state *pipe_config,
 			     const struct intel_crtc_state *pipe_config,
 			     const struct drm_connector_state *conn_state)
 			     const struct drm_connector_state *conn_state)
@@ -897,7 +943,6 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
 	} else {
 	} else {
 		crt->base.disable = intel_disable_crt;
 		crt->base.disable = intel_disable_crt;
 	}
 	}
-	crt->base.enable = intel_enable_crt;
 	if (I915_HAS_HOTPLUG(dev_priv) &&
 	if (I915_HAS_HOTPLUG(dev_priv) &&
 	    !dmi_check_system(intel_spurious_crt_detect))
 	    !dmi_check_system(intel_spurious_crt_detect))
 		crt->base.hpd_pin = HPD_CRT;
 		crt->base.hpd_pin = HPD_CRT;
@@ -905,11 +950,15 @@ void intel_crt_init(struct drm_i915_private *dev_priv)
 		crt->base.port = PORT_E;
 		crt->base.port = PORT_E;
 		crt->base.get_config = hsw_crt_get_config;
 		crt->base.get_config = hsw_crt_get_config;
 		crt->base.get_hw_state = intel_ddi_get_hw_state;
 		crt->base.get_hw_state = intel_ddi_get_hw_state;
+		crt->base.pre_pll_enable = hsw_pre_pll_enable_crt;
+		crt->base.pre_enable = hsw_pre_enable_crt;
+		crt->base.enable = hsw_enable_crt;
 		crt->base.post_disable = hsw_post_disable_crt;
 		crt->base.post_disable = hsw_post_disable_crt;
 	} else {
 	} else {
 		crt->base.port = PORT_NONE;
 		crt->base.port = PORT_NONE;
 		crt->base.get_config = intel_crt_get_config;
 		crt->base.get_config = intel_crt_get_config;
 		crt->base.get_hw_state = intel_crt_get_hw_state;
 		crt->base.get_hw_state = intel_crt_get_hw_state;
+		crt->base.enable = intel_enable_crt;
 	}
 	}
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
 	intel_connector->get_hw_state = intel_connector_get_hw_state;
 
 

+ 1 - 13
drivers/gpu/drm/i915/intel_display.c

@@ -5488,9 +5488,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (WARN_ON(intel_crtc->active))
 	if (WARN_ON(intel_crtc->active))
 		return;
 		return;
 
 
-	if (intel_crtc->config->has_pch_encoder)
-		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
-
 	intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
 	intel_encoders_pre_pll_enable(crtc, pipe_config, old_state);
 
 
 	if (intel_crtc->config->shared_dpll)
 	if (intel_crtc->config->shared_dpll)
@@ -5524,9 +5521,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 
 
 	intel_crtc->active = true;
 	intel_crtc->active = true;
 
 
-	if (intel_crtc->config->has_pch_encoder)
-		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false);
-	else
+	if (!intel_crtc->config->has_pch_encoder)
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
 
 
 	intel_encoders_pre_enable(crtc, pipe_config, old_state);
 	intel_encoders_pre_enable(crtc, pipe_config, old_state);
@@ -5581,13 +5576,6 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 		glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
 		glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
 	}
 	}
 
 
-	if (intel_crtc->config->has_pch_encoder) {
-		intel_wait_for_vblank(dev_priv, pipe);
-		intel_wait_for_vblank(dev_priv, pipe);
-		intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true);
-		intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, true);
-	}
-
 	/* If we change the relative order between pipe/planes enabling, we need
 	/* If we change the relative order between pipe/planes enabling, we need
 	 * to change the workaround. */
 	 * to change the workaround. */
 	hsw_workaround_pipe = pipe_config->hsw_workaround_pipe;
 	hsw_workaround_pipe = pipe_config->hsw_workaround_pipe;