On 09/15/2014 08:45 AM, Robert Hooker wrote:
> From: Todd Previte <tprevite at 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 at gmail.com>
> Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
>
> (Backported to 3.13.x)
> Signed-off-by: Robert Hooker <robert.hooker at 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;
> };
>
>
--
Brad Figg brad.figg at canonical.com http://www.canonical.com