[RFC 04/30] drm/i915: implement DDI disable function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Paulo Zanoni <paulo.r.zanoni at intel.com>

It follows the "mode unset" sequence recommended by the documentation.
This is necessary so we can make PLLs available for the other mode
sets and it also helps preventing machine hangs.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 31 +++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_drv.h  |  1 +
 drivers/gpu/drm/i915/intel_hdmi.c |  1 +
 3 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 4fd22ae..e3dac45 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -841,6 +841,37 @@ static void intel_ddi_disable_port(struct drm_i915_private *dev_priv,
 	I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
 }
 
+static bool intel_ddi_port_disabled(struct drm_i915_private *dev_priv,
+				    enum port port)
+{
+	return (I915_READ(PORT_CLK_SEL(port)) == PORT_CLK_SEL_NONE);
+}
+
+void intel_ddi_disable(struct drm_encoder *encoder)
+{
+	struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+	struct drm_crtc *crtc = encoder->crtc;
+	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+	int port = intel_hdmi->ddi_port;
+
+	if (intel_ddi_port_disabled(dev_priv, port))
+		return;
+
+	if (!crtc) {
+		WARN(1, "Disabling encoder on port %c without CRTC\n",
+		     port_name(port));
+	} else {
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		int pipe = intel_crtc->pipe;
+		struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+
+		(*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
+		intel_ddi_disable_pipe(dev_priv, pipe);
+	}
+
+	intel_ddi_disable_port(dev_priv, port);
+}
+
 void intel_ddi_pll_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 2578158..b99af38 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -526,5 +526,6 @@ extern void intel_ddi_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode);
 extern void intel_ddi_pll_init(struct drm_device *dev);
+extern void intel_ddi_disable(struct drm_encoder *encoder);
 
 #endif /* __INTEL_DRV_H__ */
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index e4c37bb..c56d213 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -854,6 +854,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = {
 	.prepare = intel_encoder_prepare,
 	.mode_set = intel_ddi_mode_set,
 	.commit = intel_encoder_commit,
+	.disable = intel_ddi_disable,
 };
 
 static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
-- 
1.7.11.2



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux