Skip to content

Commit 264613b

Browse files
committed
drm/i915: Disable LTTPR support when the DPCD rev < 1.4
By the specification the 0xF0000-0xF02FF range is only valid when the DPCD revision is 1.4 or higher. Disable LTTPR support if this isn't so. Trying to detect LTTPRs returned corrupted values for the above DPCD range at least on a Skylake host with an LG 43UD79-B monitor with a DPCD revision 1.2 connected. v2: Add the actual version check. v3: Fix s/DRPX/DPRX/ typo. Fixes: 7b2a4ab ("drm/i915: Switch to LTTPR transparent mode link training") Cc: <stable@vger.kernel.org> # v5.11 Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210317190149.4032966-1-imre.deak@intel.com
1 parent 984982f commit 264613b

File tree

3 files changed

+39
-15
lines changed

3 files changed

+39
-15
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3709,9 +3709,7 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
37093709
{
37103710
int ret;
37113711

3712-
intel_dp_lttpr_init(intel_dp);
3713-
3714-
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd))
3712+
if (intel_dp_init_lttpr_and_dprx_caps(intel_dp) < 0)
37153713
return false;
37163714

37173715
/*

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

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ intel_dp_dump_link_status(struct drm_device *drm,
3535
link_status[3], link_status[4], link_status[5]);
3636
}
3737

38+
static void intel_dp_reset_lttpr_common_caps(struct intel_dp *intel_dp)
39+
{
40+
memset(&intel_dp->lttpr_common_caps, 0, sizeof(intel_dp->lttpr_common_caps));
41+
}
42+
3843
static void intel_dp_reset_lttpr_count(struct intel_dp *intel_dp)
3944
{
4045
intel_dp->lttpr_common_caps[DP_PHY_REPEATER_CNT -
@@ -96,8 +101,7 @@ static bool intel_dp_read_lttpr_common_caps(struct intel_dp *intel_dp)
96101

97102
if (drm_dp_read_lttpr_common_caps(&intel_dp->aux,
98103
intel_dp->lttpr_common_caps) < 0) {
99-
memset(intel_dp->lttpr_common_caps, 0,
100-
sizeof(intel_dp->lttpr_common_caps));
104+
intel_dp_reset_lttpr_common_caps(intel_dp);
101105
return false;
102106
}
103107

@@ -119,30 +123,49 @@ intel_dp_set_lttpr_transparent_mode(struct intel_dp *intel_dp, bool enable)
119123
}
120124

121125
/**
122-
* intel_dp_lttpr_init - detect LTTPRs and init the LTTPR link training mode
126+
* intel_dp_init_lttpr_and_dprx_caps - detect LTTPR and DPRX caps, init the LTTPR link training mode
123127
* @intel_dp: Intel DP struct
124128
*
125-
* Read the LTTPR common capabilities, switch to non-transparent link training
126-
* mode if any is detected and read the PHY capabilities for all detected
127-
* LTTPRs. In case of an LTTPR detection error or if the number of
129+
* Read the LTTPR common and DPRX capabilities and switch to non-transparent
130+
* link training mode if any is detected and read the PHY capabilities for all
131+
* detected LTTPRs. In case of an LTTPR detection error or if the number of
128132
* LTTPRs is more than is supported (8), fall back to the no-LTTPR,
129133
* transparent mode link training mode.
130134
*
131135
* Returns:
132-
* >0 if LTTPRs were detected and the non-transparent LT mode was set
136+
* >0 if LTTPRs were detected and the non-transparent LT mode was set. The
137+
* DPRX capabilities are read out.
133138
* 0 if no LTTPRs or more than 8 LTTPRs were detected or in case of a
134-
* detection failure and the transparent LT mode was set
139+
* detection failure and the transparent LT mode was set. The DPRX
140+
* capabilities are read out.
141+
* <0 Reading out the DPRX capabilities failed.
135142
*/
136-
int intel_dp_lttpr_init(struct intel_dp *intel_dp)
143+
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
137144
{
138145
int lttpr_count;
139146
bool ret;
140147
int i;
141148

142149
ret = intel_dp_read_lttpr_common_caps(intel_dp);
150+
151+
/* The DPTX shall read the DPRX caps after LTTPR detection. */
152+
if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd)) {
153+
intel_dp_reset_lttpr_common_caps(intel_dp);
154+
return -EIO;
155+
}
156+
143157
if (!ret)
144158
return 0;
145159

160+
/*
161+
* The 0xF0000-0xF02FF range is only valid if the DPCD revision is
162+
* at least 1.4.
163+
*/
164+
if (intel_dp->dpcd[DP_DPCD_REV] < 0x14) {
165+
intel_dp_reset_lttpr_common_caps(intel_dp);
166+
return 0;
167+
}
168+
146169
lttpr_count = drm_dp_lttpr_count(intel_dp->lttpr_common_caps);
147170
/*
148171
* Prevent setting LTTPR transparent mode explicitly if no LTTPRs are
@@ -182,7 +205,7 @@ int intel_dp_lttpr_init(struct intel_dp *intel_dp)
182205

183206
return lttpr_count;
184207
}
185-
EXPORT_SYMBOL(intel_dp_lttpr_init);
208+
EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps);
186209

187210
static u8 dp_voltage_max(u8 preemph)
188211
{
@@ -817,7 +840,10 @@ void intel_dp_start_link_train(struct intel_dp *intel_dp,
817840
* TODO: Reiniting LTTPRs here won't be needed once proper connector
818841
* HW state readout is added.
819842
*/
820-
int lttpr_count = intel_dp_lttpr_init(intel_dp);
843+
int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
844+
845+
if (lttpr_count < 0)
846+
return;
821847

822848
if (!intel_dp_link_train_all_phys(intel_dp, crtc_state, lttpr_count))
823849
intel_dp_schedule_fallback_link_training(intel_dp, crtc_state);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
struct intel_crtc_state;
1212
struct intel_dp;
1313

14-
int intel_dp_lttpr_init(struct intel_dp *intel_dp);
14+
int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp);
1515

1616
void intel_dp_get_adjust_train(struct intel_dp *intel_dp,
1717
const struct intel_crtc_state *crtc_state,

0 commit comments

Comments
 (0)