]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/i915/dp: Read DPRX for all long HPD pulses
authorImre Deak <imre.deak@intel.com>
Tue, 20 Feb 2024 21:18:40 +0000 (23:18 +0200)
committerImre Deak <imre.deak@intel.com>
Tue, 27 Feb 2024 15:35:12 +0000 (17:35 +0200)
The TBT DP tunnel BW request logic in the Thunderbolt Connection Manager
depends on the GFX driver reading out the sink's DPRX capabilities in
response to a long HPD pulse. Since in i915 this read-out can be blocked
by another connector's/encoder's hotplug event handling (which is
serialized by drm_mode_config::connection_mutex), do a dummy DPRX read-out
in the encoder's HPD pulse handler (which is not blocked by other
encoders).

Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240220211841.448846-21-imre.deak@intel.com
drivers/gpu/drm/i915/display/intel_dp.c

index 0b9c33a000f95fe67edb731c33ade1dd175fa915..a0e826a740b13303b0622c6d8bbd899e40a721ac 100644 (file)
@@ -6165,6 +6165,7 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
 {
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
        struct intel_dp *intel_dp = &dig_port->dp;
+       u8 dpcd[DP_RECEIVER_CAP_SIZE];
 
        if (dig_port->base.type == INTEL_OUTPUT_EDP &&
            (long_hpd || !intel_pps_have_panel_power_or_vdd(intel_dp))) {
@@ -6187,6 +6188,17 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
                    dig_port->base.base.name,
                    long_hpd ? "long" : "short");
 
+       /*
+        * TBT DP tunnels require the GFX driver to read out the DPRX caps in
+        * response to long HPD pulses. The DP hotplug handler does that,
+        * however the hotplug handler may be blocked by another
+        * connector's/encoder's hotplug handler. Since the TBT CM may not
+        * complete the DP tunnel BW request for the latter connector/encoder
+        * waiting for this encoder's DPRX read, perform a dummy read here.
+        */
+       if (long_hpd)
+               intel_dp_read_dprx_caps(intel_dp, dpcd);
+
        if (long_hpd) {
                intel_dp->reset_link_params = true;
                return IRQ_NONE;