drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
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 38188a7f57)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
pull/1199/head
parent
2e43ae7dd7
commit
584cf613c2
|
|
@ -172,10 +172,28 @@ int intel_dp_link_symbol_clock(int rate)
|
||||||
|
|
||||||
static int max_dprx_rate(struct intel_dp *intel_dp)
|
static int max_dprx_rate(struct intel_dp *intel_dp)
|
||||||
{
|
{
|
||||||
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
|
struct intel_display *display = to_intel_display(intel_dp);
|
||||||
return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
|
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||||
|
int max_rate;
|
||||||
|
|
||||||
return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
|
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
|
||||||
|
max_rate = drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
|
||||||
|
else
|
||||||
|
max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some broken eDP sinks illegally declare support for
|
||||||
|
* HBR3 without TPS4, and are unable to produce a stable
|
||||||
|
* output. Reject HBR3 when TPS4 is not available.
|
||||||
|
*/
|
||||||
|
if (max_rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) {
|
||||||
|
drm_dbg_kms(display->drm,
|
||||||
|
"[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n",
|
||||||
|
encoder->base.base.id, encoder->base.name);
|
||||||
|
max_rate = 540000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int max_dprx_lane_count(struct intel_dp *intel_dp)
|
static int max_dprx_lane_count(struct intel_dp *intel_dp)
|
||||||
|
|
@ -4170,6 +4188,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
|
||||||
static void
|
static void
|
||||||
intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
||||||
{
|
{
|
||||||
|
struct intel_display *display = to_intel_display(intel_dp);
|
||||||
|
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
|
||||||
|
|
||||||
intel_dp->num_sink_rates = 0;
|
intel_dp->num_sink_rates = 0;
|
||||||
|
|
||||||
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
|
if (intel_dp->edp_dpcd[0] >= DP_EDP_14) {
|
||||||
|
|
@ -4180,10 +4201,7 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
||||||
sink_rates, sizeof(sink_rates));
|
sink_rates, sizeof(sink_rates));
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
|
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
|
||||||
int val = le16_to_cpu(sink_rates[i]);
|
int rate;
|
||||||
|
|
||||||
if (val == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Value read multiplied by 200kHz gives the per-lane
|
/* Value read multiplied by 200kHz gives the per-lane
|
||||||
* link rate in kHz. The source rates are, however,
|
* link rate in kHz. The source rates are, however,
|
||||||
|
|
@ -4191,7 +4209,24 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
|
||||||
* back to symbols is
|
* back to symbols is
|
||||||
* (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte)
|
* (val * 200kHz)*(8/10 ch. encoding)*(1/8 bit to Byte)
|
||||||
*/
|
*/
|
||||||
intel_dp->sink_rates[i] = (val * 200) / 10;
|
rate = le16_to_cpu(sink_rates[i]) * 200 / 10;
|
||||||
|
|
||||||
|
if (rate == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some broken eDP sinks illegally declare support for
|
||||||
|
* HBR3 without TPS4, and are unable to produce a stable
|
||||||
|
* output. Reject HBR3 when TPS4 is not available.
|
||||||
|
*/
|
||||||
|
if (rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) {
|
||||||
|
drm_dbg_kms(display->drm,
|
||||||
|
"[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n",
|
||||||
|
encoder->base.base.id, encoder->base.name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_dp->sink_rates[i] = rate;
|
||||||
}
|
}
|
||||||
intel_dp->num_sink_rates = i;
|
intel_dp->num_sink_rates = i;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue