Message ID | 1410795943-17809-1-git-send-email-sarvatt@ubuntu.com |
---|---|
State | New |
Headers | show |
On 09/15/2014 08:45 AM, Robert Hooker wrote: > From: Todd Previte <tprevite@gmail.com> > > commit 06ea66b6bb445043dc25a9626254d5c130093199 upstream. > > BugLink: http://bugs.launchpad.net/bugs/1369633 > > For HSW+ platforms, enable the 5.4Ghz (HBR2) link rate for devices that support it. The > sink device must report that is supports Displayport 1.2 and the HBR2 bit rate in the > DPCD in order to use HBR2. > > Signed-off-by: Todd Previte <tprevite@gmail.com> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> > > (Backported to 3.13.x) > Signed-off-by: Robert Hooker <robert.hooker@canonical.com> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 6b50a14..2d1e1a1d 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -96,13 +96,18 @@ static int > intel_dp_max_link_bw(struct intel_dp *intel_dp) > { > int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; > + struct drm_device *dev = intel_dp->attached_connector->base.dev; > > switch (max_link_bw) { > case DP_LINK_BW_1_62: > case DP_LINK_BW_2_7: > break; > case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ > - max_link_bw = DP_LINK_BW_2_7; > + if ((IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) && > + intel_dp->dpcd[DP_DPCD_REV] >= 0x12) > + max_link_bw = DP_LINK_BW_5_4; > + else > + max_link_bw = DP_LINK_BW_2_7; > break; > default: > WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n", > @@ -811,9 +816,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, > struct intel_connector *intel_connector = intel_dp->attached_connector; > int lane_count, clock; > int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); > - int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; > + /* Conveniently, the link BW constants become indices with a shift...*/ > + int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; > int bpp, mode_rate; > - static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; > + static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; > int link_avail, link_clock; > > if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) > @@ -2638,10 +2644,15 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) > bool channel_eq = false; > int tries, cr_tries; > uint32_t DP = intel_dp->DP; > + uint32_t training_pattern = DP_TRAINING_PATTERN_2; > + > + /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/ > + if (intel_dp->link_bw == DP_LINK_BW_5_4 || intel_dp->use_tps3) > + training_pattern = DP_TRAINING_PATTERN_3; > > /* channel equalization */ > if (!intel_dp_set_link_train(intel_dp, &DP, > - DP_TRAINING_PATTERN_2 | > + training_pattern | > DP_LINK_SCRAMBLING_DISABLE)) { > DRM_ERROR("failed to start channel equalization\n"); > return; > @@ -2669,7 +2680,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) > if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { > intel_dp_start_link_train(intel_dp); > intel_dp_set_link_train(intel_dp, &DP, > - DP_TRAINING_PATTERN_2 | > + training_pattern | > DP_LINK_SCRAMBLING_DISABLE); > cr_tries++; > continue; > @@ -2685,7 +2696,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) > intel_dp_link_down(intel_dp); > intel_dp_start_link_train(intel_dp); > intel_dp_set_link_train(intel_dp, &DP, > - DP_TRAINING_PATTERN_2 | > + training_pattern | > DP_LINK_SCRAMBLING_DISABLE); > tries = 0; > cr_tries++; > @@ -2827,6 +2838,14 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) > } > } > > + /* Training Pattern 3 support */ > + if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && > + intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { > + intel_dp->use_tps3 = true; > + DRM_DEBUG_KMS("Displayport TPS3 supported"); > + } else > + intel_dp->use_tps3 = false; > + > if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & > DP_DWN_STRM_PORT_PRESENT)) > return true; /* native DP sink */ > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index d6e5653..bc1eb7d 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -475,6 +475,7 @@ struct intel_dp { > struct delayed_work panel_vdd_work; > bool want_panel_vdd; > bool psr_setup_done; > + bool use_tps3; > struct intel_connector *attached_connector; > }; > >
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6b50a14..2d1e1a1d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -96,13 +96,18 @@ static int intel_dp_max_link_bw(struct intel_dp *intel_dp) { int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; + struct drm_device *dev = intel_dp->attached_connector->base.dev; switch (max_link_bw) { case DP_LINK_BW_1_62: case DP_LINK_BW_2_7: break; case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ - max_link_bw = DP_LINK_BW_2_7; + if ((IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) && + intel_dp->dpcd[DP_DPCD_REV] >= 0x12) + max_link_bw = DP_LINK_BW_5_4; + else + max_link_bw = DP_LINK_BW_2_7; break; default: WARN(1, "invalid max DP link bw val %x, using 1.62Gbps\n", @@ -811,9 +816,10 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct intel_connector *intel_connector = intel_dp->attached_connector; int lane_count, clock; int max_lane_count = drm_dp_max_lane_count(intel_dp->dpcd); - int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; + /* Conveniently, the link BW constants become indices with a shift...*/ + int max_clock = intel_dp_max_link_bw(intel_dp) >> 3; int bpp, mode_rate; - static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; + static int bws[] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7, DP_LINK_BW_5_4 }; int link_avail, link_clock; if (HAS_PCH_SPLIT(dev) && !HAS_DDI(dev) && port != PORT_A) @@ -2638,10 +2644,15 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) bool channel_eq = false; int tries, cr_tries; uint32_t DP = intel_dp->DP; + uint32_t training_pattern = DP_TRAINING_PATTERN_2; + + /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/ + if (intel_dp->link_bw == DP_LINK_BW_5_4 || intel_dp->use_tps3) + training_pattern = DP_TRAINING_PATTERN_3; /* channel equalization */ if (!intel_dp_set_link_train(intel_dp, &DP, - DP_TRAINING_PATTERN_2 | + training_pattern | DP_LINK_SCRAMBLING_DISABLE)) { DRM_ERROR("failed to start channel equalization\n"); return; @@ -2669,7 +2680,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { intel_dp_start_link_train(intel_dp); intel_dp_set_link_train(intel_dp, &DP, - DP_TRAINING_PATTERN_2 | + training_pattern | DP_LINK_SCRAMBLING_DISABLE); cr_tries++; continue; @@ -2685,7 +2696,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) intel_dp_link_down(intel_dp); intel_dp_start_link_train(intel_dp); intel_dp_set_link_train(intel_dp, &DP, - DP_TRAINING_PATTERN_2 | + training_pattern | DP_LINK_SCRAMBLING_DISABLE); tries = 0; cr_tries++; @@ -2827,6 +2838,14 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) } } + /* Training Pattern 3 support */ + if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && + intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED) { + intel_dp->use_tps3 = true; + DRM_DEBUG_KMS("Displayport TPS3 supported"); + } else + intel_dp->use_tps3 = false; + if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT)) return true; /* native DP sink */ diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index d6e5653..bc1eb7d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -475,6 +475,7 @@ struct intel_dp { struct delayed_work panel_vdd_work; bool want_panel_vdd; bool psr_setup_done; + bool use_tps3; struct intel_connector *attached_connector; };