Skip to content

Commit c0352d7

Browse files
jnikuladdavenport-chromium
authored andcommitted
UPSTREAM: drm/i915/mst: read link status only when requested by sink in ESI
The link service irq vector in DPCD 0x2005 contains the link status changed bit to indicate the status should be checked. Only read and check the link status when requested by the sink. This also reduces the confusion around the buffer size for the combined ESI and link status. Alas, we still need to take into account that all link status helpers expect a buffer of DP_LINK_STATUS_SIZE (6) while the link status in ESI only has 4 bytes. Signed-off-by: Jani Nikula <[email protected]> Reviewed-by: Uma Shankar <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] (cherry picked from commit 1d50942) Signed-off-by: Drew Davenport <[email protected]> BUG=b:235993998 TEST=build test Backported using forklift.py Change-Id: Ic7e1ad5f956c8b0e2237c113df8990200f1b896c
1 parent 28fbcde commit c0352d7

File tree

1 file changed

+18
-23
lines changed

1 file changed

+18
-23
lines changed

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

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@
7373
#include "intel_vdsc.h"
7474
#include "intel_vrr.h"
7575

76-
#define DP_DPRX_ESI_LEN 14
77-
7876
/* DP DSC throughput values used for slice count calculations KPixels/s */
7977
#define DP_DSC_PEAK_PIXEL_RATE 2720000
8078
#define DP_DSC_MAX_ENC_THROUGHPUT_0 340000
@@ -2814,11 +2812,9 @@ intel_dp_configure_mst(struct intel_dp *intel_dp)
28142812
}
28152813

28162814
static bool
2817-
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
2815+
intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi)
28182816
{
2819-
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI,
2820-
sink_irq_vector, DP_DPRX_ESI_LEN) ==
2821-
DP_DPRX_ESI_LEN;
2817+
return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4;
28222818
}
28232819

28242820
static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4])
@@ -3639,12 +3635,22 @@ intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled)
36393635
}
36403636
}
36413637

3642-
static bool intel_dp_mst_link_status(struct intel_dp *intel_dp, u8 *esi)
3638+
static bool intel_dp_mst_link_status(struct intel_dp *intel_dp)
36433639
{
36443640
struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
36453641
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
3642+
u8 link_status[DP_LINK_STATUS_SIZE] = {};
3643+
const size_t esi_link_status_size = DP_LINK_STATUS_SIZE - 2;
3644+
3645+
if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI, link_status,
3646+
esi_link_status_size) != esi_link_status_size) {
3647+
drm_err(&i915->drm,
3648+
"[ENCODER:%d:%s] Failed to read link status\n",
3649+
encoder->base.base.id, encoder->base.name);
3650+
return false;
3651+
}
36463652

3647-
if (!drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) {
3653+
if (!drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) {
36483654
drm_dbg_kms(&i915->drm,
36493655
"[ENCODER:%d:%s] channel EQ not ok, retraining\n",
36503656
encoder->base.base.id, encoder->base.name);
@@ -3676,18 +3682,7 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
36763682
drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
36773683

36783684
for (;;) {
3679-
/*
3680-
* The +2 is because DP_DPRX_ESI_LEN is 14, but we then
3681-
* pass in "esi+10" to drm_dp_channel_eq_ok(), which
3682-
* takes a 6-byte array. So we actually need 16 bytes
3683-
* here.
3684-
*
3685-
* Somebody who knows what the limits actually are
3686-
* should check this, but for now this is at least
3687-
* harmless and avoids a valid compiler warning about
3688-
* using more of the array than we have allocated.
3689-
*/
3690-
u8 esi[DP_DPRX_ESI_LEN+2] = {};
3685+
u8 esi[4] = {};
36913686
bool handled;
36923687

36933688
if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) {
@@ -3700,9 +3695,9 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp)
37003695

37013696
drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi);
37023697

3703-
/* check link status - esi[10] = 0x200c */
3704-
if (intel_dp->active_mst_links > 0 && link_ok) {
3705-
if (!intel_dp_mst_link_status(intel_dp, esi))
3698+
if (intel_dp->active_mst_links > 0 && link_ok &&
3699+
esi[3] & LINK_STATUS_CHANGED) {
3700+
if (!intel_dp_mst_link_status(intel_dp))
37063701
link_ok = false;
37073702
}
37083703

0 commit comments

Comments
 (0)