]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_dp.c
Merge remote-tracking branch 'airlied/drm-prime-vmap' into drm-intel-next-queued
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_dp.c
index 9b2effcc90e5c635ba971917808811f18904543a..c71e7890e6f6127fdd10554ea30618b0105ab3cb 100644 (file)
@@ -266,6 +266,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
        if (mode->clock < 10000)
                return MODE_CLOCK_LOW;
 
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               return MODE_H_ILLEGAL;
+
        return MODE_OK;
 }
 
@@ -702,6 +705,9 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
                mode->clock = intel_dp->panel_fixed_mode->clock;
        }
 
+       if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+               return false;
+
        DRM_DEBUG_KMS("DP link computation with max lane count %i "
                      "max bw %02x pixel clock %iKHz\n",
                      max_lane_count, bws[max_clock], mode->clock);
@@ -1154,11 +1160,10 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
        DRM_DEBUG_KMS("Turn eDP power off\n");
 
-       WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n");
-       ironlake_panel_vdd_off_sync(intel_dp); /* finish any pending work */
+       WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
 
        pp = ironlake_get_pp_control(dev_priv);
-       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
        I915_WRITE(PCH_PP_CONTROL, pp);
        POSTING_READ(PCH_PP_CONTROL);
 
@@ -1266,18 +1271,16 @@ static void intel_dp_prepare(struct drm_encoder *encoder)
 {
        struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
+
+       /* Make sure the panel is off before trying to change the mode. But also
+        * ensure that we have vdd while we switch off the panel. */
+       ironlake_edp_panel_vdd_on(intel_dp);
        ironlake_edp_backlight_off(intel_dp);
        ironlake_edp_panel_off(intel_dp);
 
-       /* Wake up the sink first */
-       ironlake_edp_panel_vdd_on(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
        intel_dp_link_down(intel_dp);
        ironlake_edp_panel_vdd_off(intel_dp, false);
-
-       /* Make sure the panel is off before trying to
-        * change the mode
-        */
 }
 
 static void intel_dp_commit(struct drm_encoder *encoder)
@@ -1309,10 +1312,11 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
 
        if (mode != DRM_MODE_DPMS_ON) {
+               /* Switching the panel off requires vdd. */
+               ironlake_edp_panel_vdd_on(intel_dp);
                ironlake_edp_backlight_off(intel_dp);
                ironlake_edp_panel_off(intel_dp);
 
-               ironlake_edp_panel_vdd_on(intel_dp);
                intel_dp_sink_dpms(intel_dp, mode);
                intel_dp_link_down(intel_dp);
                ironlake_edp_panel_vdd_off(intel_dp, false);
@@ -1961,6 +1965,23 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
        return false;
 }
 
+static void
+intel_dp_probe_oui(struct intel_dp *intel_dp)
+{
+       u8 buf[3];
+
+       if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
+               return;
+
+       if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3))
+               DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
+                             buf[0], buf[1], buf[2]);
+
+       if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3))
+               DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
+                             buf[0], buf[1], buf[2]);
+}
+
 static bool
 intel_dp_get_sink_irq(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 {
@@ -2142,6 +2163,8 @@ intel_dp_detect(struct drm_connector *connector, bool force)
        if (status != connector_status_connected)
                return status;
 
+       intel_dp_probe_oui(intel_dp);
+
        if (intel_dp->force_audio != HDMI_AUDIO_AUTO) {
                intel_dp->has_audio = (intel_dp->force_audio == HDMI_AUDIO_ON);
        } else {