@@ -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;
@@ -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__ */
@@ -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 = {