Skip to content

Commit 56fa2d1

Browse files
vsyrjalagregkh
authored andcommitted
drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
commit 584cf61 upstream. According to the DP spec TPS4 is mandatory for HBR3. We have however seen some broken eDP sinks that violate this and declare support for HBR3 without TPS4 support. At least in the case of the icl Dell XPS 13 7390 this results in an unstable output. Reject HBR3 when TPS4 supports is unavailable on the sink. v2: Leave breadcrumbs in dmesg to avoid head scratching (Jani) Cc: stable@vger.kernel.org Cc: Jani Nikula <jani.nikula@linux.intel.com> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5969 Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250306210740.11886-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula <jani.nikula@intel.com> (cherry picked from commit 38188a7) Signed-off-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 15f4b8d commit 56fa2d1

1 file changed

Lines changed: 42 additions & 7 deletions

File tree

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

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,28 @@ int intel_dp_link_symbol_clock(int rate)
172172

173173
static int max_dprx_rate(struct intel_dp *intel_dp)
174174
{
175+
struct intel_display *display = to_intel_display(intel_dp);
176+
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
177+
int max_rate;
178+
175179
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
176-
return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
180+
max_rate = drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
181+
else
182+
max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
177183

178-
return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
184+
/*
185+
* Some broken eDP sinks illegally declare support for
186+
* HBR3 without TPS4, and are unable to produce a stable
187+
* output. Reject HBR3 when TPS4 is not available.
188+
*/
189+
if (max_rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) {
190+
drm_dbg_kms(display->drm,
191+
"[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n",
192+
encoder->base.base.id, encoder->base.name);
193+
max_rate = 540000;
194+
}
195+
196+
return max_rate;
179197
}
180198

181199
static int max_dprx_lane_count(struct intel_dp *intel_dp)
@@ -4188,6 +4206,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
41884206
static void
41894207
intel_edp_set_sink_rates(struct intel_dp *intel_dp)
41904208
{
4209+
struct intel_display *display = to_intel_display(intel_dp);
4210+
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
4211+
41914212
intel_dp->num_sink_rates = 0;
41924213

41934214
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
@@ -4198,18 +4219,32 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
41984219
sink_rates, sizeof(sink_rates));
41994220

42004221
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
4201-
int val = le16_to_cpu(sink_rates[i]);
4202-
4203-
if (val == 0)
4204-
break;
4222+
int rate;
42054223

42064224
/* Value read multiplied by 200kHz gives the per-lane
42074225
* link rate in kHz. The source rates are, however,
42084226
* stored in terms of LS_Clk kHz. The full conversion
42094227
* back to symbols is
42104228
* (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte)
42114229
*/
4212-
intel_dp->sink_rates[i] = (val * 200) / 10;
4230+
rate = le16_to_cpu(sink_rates[i]) * 200 / 10;
4231+
4232+
if (rate == 0)
4233+
break;
4234+
4235+
/*
4236+
* Some broken eDP sinks illegally declare support for
4237+
* HBR3 without TPS4, and are unable to produce a stable
4238+
* output. Reject HBR3 when TPS4 is not available.
4239+
*/
4240+
if (rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) {
4241+
drm_dbg_kms(display->drm,
4242+
"[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n",
4243+
encoder->base.base.id, encoder->base.name);
4244+
break;
4245+
}
4246+
4247+
intel_dp->sink_rates[i] = rate;
42134248
}
42144249
intel_dp->num_sink_rates = i;
42154250
}

0 commit comments

Comments
 (0)