Skip to content

Commit 7d4ecf3

Browse files
committed
Merge tag 'drm-intel-next-fixes-2024-07-18' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
- Reset intel_dp->link_trained before retraining the link [dp] (Imre Deak) - Don't switch the LTTPR mode on an active link [dp] (Imre Deak) Signed-off-by: Dave Airlie <[email protected]> From: Tvrtko Ursulin <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/ZpjgtowjpUZoHvrl@linux
2 parents 478a527 + 509580f commit 7d4ecf3

File tree

2 files changed

+50
-7
lines changed

2 files changed

+50
-7
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5314,6 +5314,8 @@ static int intel_dp_retrain_link(struct intel_encoder *encoder,
53145314
const struct intel_crtc_state *crtc_state =
53155315
to_intel_crtc_state(crtc->base.state);
53165316

5317+
intel_dp->link_trained = false;
5318+
53175319
intel_dp_check_frl_training(intel_dp);
53185320
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
53195321
intel_dp_start_link_train(NULL, intel_dp, crtc_state);

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

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,24 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
117117
return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1;
118118
}
119119

120-
static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
120+
static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
121+
{
122+
return intel_dp->lttpr_common_caps[DP_PHY_REPEATER_MODE -
123+
DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] ==
124+
DP_PHY_REPEATER_MODE_TRANSPARENT;
125+
}
126+
127+
/*
128+
* Read the LTTPR common capabilities and switch the LTTPR PHYs to
129+
* non-transparent mode if this is supported. Preserve the
130+
* transparent/non-transparent mode on an active link.
131+
*
132+
* Return the number of detected LTTPRs in non-transparent mode or 0 if the
133+
* LTTPRs are in transparent mode or the detection failed.
134+
*/
135+
static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
121136
{
122137
int lttpr_count;
123-
int i;
124138

125139
if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd))
126140
return 0;
@@ -134,6 +148,19 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
134148
if (lttpr_count == 0)
135149
return 0;
136150

151+
/*
152+
* Don't change the mode on an active link, to prevent a loss of link
153+
* synchronization. See DP Standard v2.0 3.6.7. about the LTTPR
154+
* resetting its internal state when the mode is changed from
155+
* non-transparent to transparent.
156+
*/
157+
if (intel_dp->link_trained) {
158+
if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp))
159+
goto out_reset_lttpr_count;
160+
161+
return lttpr_count;
162+
}
163+
137164
/*
138165
* See DP Standard v2.0 3.6.6.1. about the explicit disabling of
139166
* non-transparent mode and the disable->enable non-transparent mode
@@ -154,11 +181,25 @@ static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEI
154181
"Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n");
155182

156183
intel_dp_set_lttpr_transparent_mode(intel_dp, true);
157-
intel_dp_reset_lttpr_count(intel_dp);
158184

159-
return 0;
185+
goto out_reset_lttpr_count;
160186
}
161187

188+
return lttpr_count;
189+
190+
out_reset_lttpr_count:
191+
intel_dp_reset_lttpr_count(intel_dp);
192+
193+
return 0;
194+
}
195+
196+
static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
197+
{
198+
int lttpr_count;
199+
int i;
200+
201+
lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd);
202+
162203
for (i = 0; i < lttpr_count; i++)
163204
intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i));
164205

@@ -1482,10 +1523,10 @@ void intel_dp_start_link_train(struct intel_atomic_state *state,
14821523
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
14831524
struct intel_encoder *encoder = &dig_port->base;
14841525
bool passed;
1485-
14861526
/*
1487-
* TODO: Reiniting LTTPRs here won't be needed once proper connector
1488-
* HW state readout is added.
1527+
* Reinit the LTTPRs here to ensure that they are switched to
1528+
* non-transparent mode. During an earlier LTTPR detection this
1529+
* could've been prevented by an active link.
14891530
*/
14901531
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
14911532

0 commit comments

Comments
 (0)