* [PATCH 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
@ 2025-03-03 12:39 Ville Syrjala
2025-03-04 9:05 ` Jani Nikula
2025-03-06 21:07 ` [PATCH v2 " Ville Syrjala
0 siblings, 2 replies; 4+ messages in thread
From: Ville Syrjala @ 2025-03-03 12:39 UTC (permalink / raw)
To: intel-gfx; +Cc: stable
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
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.
Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5969
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_dp.c | 36 ++++++++++++++++++++-----
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 205ec315b413..61a58ff801a5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -172,10 +172,22 @@ int intel_dp_link_symbol_clock(int rate)
static int max_dprx_rate(struct intel_dp *intel_dp)
{
+ int max_rate;
+
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
- return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
+ 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 (!drm_dp_tps4_supported(intel_dp->dpcd))
+ max_rate = min(max_rate, 540000);
- return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
+ return max_rate;
}
static int max_dprx_lane_count(struct intel_dp *intel_dp)
@@ -4180,10 +4192,7 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
sink_rates, sizeof(sink_rates));
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
- int val = le16_to_cpu(sink_rates[i]);
-
- if (val == 0)
- break;
+ int rate;
/* Value read multiplied by 200kHz gives the per-lane
* link rate in kHz. The source rates are, however,
@@ -4191,7 +4200,20 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
* back to symbols is
* (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))
+ break;
+
+ intel_dp->sink_rates[i] = rate;
}
intel_dp->num_sink_rates = i;
}
--
2.45.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
2025-03-03 12:39 [PATCH 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4 Ville Syrjala
@ 2025-03-04 9:05 ` Jani Nikula
2025-03-06 21:07 ` [PATCH v2 " Ville Syrjala
1 sibling, 0 replies; 4+ messages in thread
From: Jani Nikula @ 2025-03-04 9:05 UTC (permalink / raw)
To: Ville Syrjala, intel-gfx; +Cc: stable
On Mon, 03 Mar 2025, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> 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.
Based on the logs this drops bpp from 30 to 24 on the device. In case
anyone notices, they might wonder about the degration.
As we'll no longer hit the "8.1 Gbps link rate without sink TPS4
support" warning in intel_dp_training_pattern(), as the sink rates are
filtered earlier, I'm thinking it would be a good idea to debug log
this. Otherwise it might take a while to find out why we're rejecting
HBR3.
BR,
Jani.
>
> Cc: stable@vger.kernel.org
> Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/5969
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_dp.c | 36 ++++++++++++++++++++-----
> 1 file changed, 29 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 205ec315b413..61a58ff801a5 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -172,10 +172,22 @@ int intel_dp_link_symbol_clock(int rate)
>
> static int max_dprx_rate(struct intel_dp *intel_dp)
> {
> + int max_rate;
> +
> if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> - return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
> + 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 (!drm_dp_tps4_supported(intel_dp->dpcd))
> + max_rate = min(max_rate, 540000);
>
> - return drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
> + return max_rate;
> }
>
> static int max_dprx_lane_count(struct intel_dp *intel_dp)
> @@ -4180,10 +4192,7 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
> sink_rates, sizeof(sink_rates));
>
> for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
> - int val = le16_to_cpu(sink_rates[i]);
> -
> - if (val == 0)
> - break;
> + int rate;
>
> /* Value read multiplied by 200kHz gives the per-lane
> * link rate in kHz. The source rates are, however,
> @@ -4191,7 +4200,20 @@ intel_edp_set_sink_rates(struct intel_dp *intel_dp)
> * back to symbols is
> * (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))
> + break;
> +
> + intel_dp->sink_rates[i] = rate;
> }
> intel_dp->num_sink_rates = i;
> }
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v2 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
2025-03-03 12:39 [PATCH 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4 Ville Syrjala
2025-03-04 9:05 ` Jani Nikula
@ 2025-03-06 21:07 ` Ville Syrjala
2025-03-27 7:35 ` Jani Nikula
1 sibling, 1 reply; 4+ messages in thread
From: Ville Syrjala @ 2025-03-06 21:07 UTC (permalink / raw)
To: intel-gfx; +Cc: stable, Jani Nikula
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
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>
---
drivers/gpu/drm/i915/display/intel_dp.c | 49 +++++++++++++++++++++----
1 file changed, 42 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 205ec315b413..70f5d1465f81 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -172,10 +172,28 @@ int intel_dp_link_symbol_clock(int rate)
static int max_dprx_rate(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;
+ int max_rate;
+
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
- return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
+ 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]);
- return 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)
@@ -4170,6 +4188,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
static void
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;
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));
for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
- int val = le16_to_cpu(sink_rates[i]);
-
- if (val == 0)
- break;
+ int rate;
/* Value read multiplied by 200kHz gives the per-lane
* 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
* (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;
}
--
2.45.3
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v2 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4
2025-03-06 21:07 ` [PATCH v2 " Ville Syrjala
@ 2025-03-27 7:35 ` Jani Nikula
0 siblings, 0 replies; 4+ messages in thread
From: Jani Nikula @ 2025-03-27 7:35 UTC (permalink / raw)
To: Ville Syrjala, intel-gfx; +Cc: stable
On Thu, 06 Mar 2025, Ville Syrjala <ville.syrjala@linux.intel.com> wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
>
> 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>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_dp.c | 49 +++++++++++++++++++++----
> 1 file changed, 42 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 205ec315b413..70f5d1465f81 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -172,10 +172,28 @@ int intel_dp_link_symbol_clock(int rate)
>
> static int max_dprx_rate(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;
> + int max_rate;
> +
> if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
> - return drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel);
> + 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]);
>
> - return 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)
> @@ -4170,6 +4188,9 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
> static void
> 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;
>
> 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));
>
> for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
> - int val = le16_to_cpu(sink_rates[i]);
> -
> - if (val == 0)
> - break;
> + int rate;
>
> /* Value read multiplied by 200kHz gives the per-lane
> * 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
> * (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;
> }
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-03-27 7:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-03 12:39 [PATCH 1/2] drm/i915/dp: Reject HBR3 when sink doesn't support TPS4 Ville Syrjala
2025-03-04 9:05 ` Jani Nikula
2025-03-06 21:07 ` [PATCH v2 " Ville Syrjala
2025-03-27 7:35 ` Jani Nikula
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox