]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/i915: Enable/disable TMDS output buffers in DP++ adaptor as needed
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 2 May 2016 19:08:24 +0000 (22:08 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 8 Jun 2016 01:23:41 +0000 (18:23 -0700)
commit 0c2fb7c6c8fef2092051192095a7788231ba9a42 upstream.

To save a bit of power, let's try to turn off the TMDS output buffers
in DP++ adaptors when we're not driving the port.

v2: Let's not forget DDI, toss in a debug message while at it
v3: Just do the TMDS output control based on adaptor type. With the
    helper getting passed the type, we wouldn't actually have to
    check at all in the driver, but the check eliminates the debug
    output more honest

Cc: Tore Anderson <tore@fud.no>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Shashank Sharma <shashank.sharma@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1462216105-20881-4-git-send-email-ville.syrjala@linux.intel.com
Reviewed-by: Shashank Sharma <shashank.sharma@intel.com>
(cherry picked from commit b2ccb822d376d1bbbe5d1f9118d1488b25e6bc6d)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c

index 96ffcc541e17697b69bad69fb24fe5bec3866aab..50f5b0c975e33f64beb1560f5e33d30f630c5493 100644 (file)
@@ -2309,6 +2309,12 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
        enum port port = intel_ddi_get_encoder_port(intel_encoder);
        int type = intel_encoder->type;
 
+       if (type == INTEL_OUTPUT_HDMI) {
+               struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+               intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+       }
+
        intel_prepare_ddi_buffer(intel_encoder);
 
        if (type == INTEL_OUTPUT_EDP) {
@@ -2375,6 +2381,12 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
                                        DPLL_CTRL2_DDI_CLK_OFF(port)));
        else if (INTEL_INFO(dev)->gen < 9)
                I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
+
+       if (type == INTEL_OUTPUT_HDMI) {
+               struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
+
+               intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+       }
 }
 
 static void intel_enable_ddi(struct intel_encoder *intel_encoder)
index 23c73e8e5f6da848372dfc126cf645220b83d6f0..8db4d4409cf3d5f972f9820d7644bae56a91c9c2 100644 (file)
@@ -1356,6 +1356,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
 bool intel_hdmi_compute_config(struct intel_encoder *encoder,
                               struct intel_crtc_state *pipe_config);
+void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
 
 
 /* intel_lvds.c */
index 5bcbfea8995491f78be6ac3bb47418a959b8db73..3ddb4fac53fa5bbc163e2277947006ff45e8b7a1 100644 (file)
@@ -836,6 +836,22 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
        intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
 }
 
+void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
+{
+       struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
+       struct i2c_adapter *adapter =
+               intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
+
+       if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
+               return;
+
+       DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
+                     enable ? "Enabling" : "Disabling");
+
+       drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
+                                        adapter, enable);
+}
+
 static void intel_hdmi_prepare(struct intel_encoder *encoder)
 {
        struct drm_device *dev = encoder->base.dev;
@@ -845,6 +861,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
        const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
        u32 hdmi_val;
 
+       intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
+
        hdmi_val = SDVO_ENCODING_HDMI;
        if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
                hdmi_val |= HDMI_COLOR_RANGE_16_235;
@@ -1143,6 +1161,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
        }
 
        intel_hdmi->set_infoframes(&encoder->base, false, NULL);
+
+       intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
 }
 
 static void g4x_disable_hdmi(struct intel_encoder *encoder)