Skip to content

Commit b30edfd

Browse files
committed
drm/i915: Switch to LTTPR non-transparent mode link training
The DP Standard's recommendation is to use the LTTPR non-transparent mode link training if LTTPRs are detected, so let's do this. Besides power-saving, the advantages of this are that the maximum number of LTTPRs can only be used in non-transparent mode (the limit is 5-8 in transparent mode), and it provides a way to narrow down the reason for a link training failure to a given link segment. Non-transparent mode is probably also the mode that was tested the most by the industry. The changes in this patchset: - Pass the DP PHY that is currently link trained to all LT helpers, so that these can access the correct LTTPR/DPRX DPCD registers. - During LT take into account the LTTPR common lane rate/count and the per LTTPR-PHY vswing/pre-emph limits. - Switch to LTTPR non-transparent LT mode and train each link segment according to the sequence in DP Standard v2.0 (complete CR/EQ for each segment before continuing with the next segment). v2: - Switch to non-transparent mode during connector detection, which is required before reading the per-PHY LTTPR capabilities. - Move the DP_PHY_LTTPR() macro to drm_dp_helper.h (Ville) - Use the new drm_dp_dpcd_read_phy_link_status() instead of adding the same logic to intel_dp_get_link_status(). (Ville) - Make intel_dp_lttpr_phy_caps() return a pointer to the whole array instead of a pointer to its first element. (Ville) - Add the intel_dp_phy_is_downstream_of_source() helper. (Ville) - Add a code comment about the disable->enable quirk of non-transparent mode. - Add the intel_dp_training_pattern_set_reg() helper. - Fix checkpatch/sparse warns. Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20201007170917.1764556-7-imre.deak@intel.com
1 parent 7b2a4ab commit b30edfd

File tree

5 files changed

+321
-73
lines changed

5 files changed

+321
-73
lines changed

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,7 @@ struct intel_dp {
13031303
u8 edp_dpcd[EDP_DISPLAY_CTL_CAP_SIZE];
13041304
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE];
13051305
u8 lttpr_common_caps[DP_LTTPR_COMMON_CAP_SIZE];
1306+
u8 lttpr_phy_caps[DP_MAX_LTTPR_COUNT][DP_LTTPR_PHY_CAP_SIZE];
13061307
u8 fec_capable;
13071308
/* source rates */
13081309
int num_source_rates;

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
160160
162000, 270000, 540000, 810000
161161
};
162162
int i, max_rate;
163+
int max_lttpr_rate;
163164

164165
if (drm_dp_has_quirk(&intel_dp->desc, 0,
165166
DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS)) {
@@ -173,6 +174,9 @@ static void intel_dp_set_sink_rates(struct intel_dp *intel_dp)
173174
}
174175

175176
max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
177+
max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps);
178+
if (max_lttpr_rate)
179+
max_rate = min(max_rate, max_lttpr_rate);
176180

177181
for (i = 0; i < ARRAY_SIZE(dp_rates); i++) {
178182
if (dp_rates[i] > max_rate)
@@ -218,6 +222,10 @@ static int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
218222
int source_max = dig_port->max_lanes;
219223
int sink_max = drm_dp_max_lane_count(intel_dp->dpcd);
220224
int fia_max = intel_tc_port_fia_max_lane_count(dig_port);
225+
int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
226+
227+
if (lttpr_max)
228+
sink_max = min(sink_max, lttpr_max);
221229

222230
return min3(source_max, sink_max, fia_max);
223231
}
@@ -4179,17 +4187,6 @@ static void chv_dp_post_pll_disable(struct intel_atomic_state *state,
41794187
chv_phy_post_pll_disable(encoder, old_crtc_state);
41804188
}
41814189

4182-
/*
4183-
* Fetch AUX CH registers 0x202 - 0x207 which contain
4184-
* link status information
4185-
*/
4186-
bool
4187-
intel_dp_get_link_status(struct intel_dp *intel_dp, u8 link_status[DP_LINK_STATUS_SIZE])
4188-
{
4189-
return drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS, link_status,
4190-
DP_LINK_STATUS_SIZE) == DP_LINK_STATUS_SIZE;
4191-
}
4192-
41934190
static u8 intel_dp_voltage_max_2(struct intel_dp *intel_dp,
41944191
const struct intel_crtc_state *crtc_state)
41954192
{
@@ -5592,13 +5589,15 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp,
55925589
&intel_dp->compliance.test_data.phytest;
55935590
u8 link_status[DP_LINK_STATUS_SIZE];
55945591

5595-
if (!intel_dp_get_link_status(intel_dp, link_status)) {
5592+
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
5593+
link_status) < 0) {
55965594
DRM_DEBUG_KMS("failed to get link status\n");
55975595
return;
55985596
}
55995597

56005598
/* retrieve vswing & pre-emphasis setting */
5601-
intel_dp_get_adjust_train(intel_dp, crtc_state, link_status);
5599+
intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX,
5600+
link_status);
56025601

56035602
intel_dp_autotest_phy_ddi_disable(intel_dp, crtc_state);
56045603

@@ -5756,7 +5755,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
57565755
if (intel_psr_enabled(intel_dp))
57575756
return false;
57585757

5759-
if (!intel_dp_get_link_status(intel_dp, link_status))
5758+
if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX,
5759+
link_status) < 0)
57605760
return false;
57615761

57625762
/*

drivers/gpu/drm/i915/display/intel_dp.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock,
102102
u8 *link_bw, u8 *rate_select);
103103
bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
104104
bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
105-
bool
106-
intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
107105

108106
bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
109107
int intel_dp_link_required(int pixel_clock, int bpp);

0 commit comments

Comments
 (0)