Skip to content

Commit ed3648b

Browse files
committed
drm/i915/dp: Disable the AUX DPCD probe quirk if it's not required
Reading DPCD registers has side-effects and some of these can cause a problem for instance during link training. Based on this it's better to avoid the probing quirk done before each DPCD register read, limiting this to the monitor which requires it. The only known problematic monitor is an external SST sink, so keep the quirk disabled always for eDP and MST sinks. Reenable the quirk after a hotplug event and after resuming from a power state without hotplug support, until the subsequent EDID based detection. v2: Add a helper for determining the need/setting the probing. (Jani) Cc: Ville Syrjälä <[email protected]> Cc: Jani Nikula <[email protected]> Reviewed-by: Mika Kahola <[email protected]> Acked-by: Jani Nikula <[email protected]> Signed-off-by: Imre Deak <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b87ed52 commit ed3648b

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5790,6 +5790,28 @@ intel_dp_detect_sdp_caps(struct intel_dp *intel_dp)
57905790
drm_dp_as_sdp_supported(&intel_dp->aux, intel_dp->dpcd);
57915791
}
57925792

5793+
static bool intel_dp_needs_dpcd_probe(struct intel_dp *intel_dp, bool force_on_external)
5794+
{
5795+
struct intel_connector *connector = intel_dp->attached_connector;
5796+
5797+
if (intel_dp_is_edp(intel_dp))
5798+
return false;
5799+
5800+
if (force_on_external)
5801+
return true;
5802+
5803+
if (intel_dp->is_mst)
5804+
return false;
5805+
5806+
return drm_edid_has_quirk(&connector->base, DRM_EDID_QUIRK_DP_DPCD_PROBE);
5807+
}
5808+
5809+
void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external)
5810+
{
5811+
drm_dp_dpcd_set_probe(&intel_dp->aux,
5812+
intel_dp_needs_dpcd_probe(intel_dp, force_on_external));
5813+
}
5814+
57935815
static int
57945816
intel_dp_detect(struct drm_connector *_connector,
57955817
struct drm_modeset_acquire_ctx *ctx,
@@ -5918,6 +5940,8 @@ intel_dp_detect(struct drm_connector *_connector,
59185940
if (status != connector_status_connected && !intel_dp->is_mst)
59195941
intel_dp_unset_edid(intel_dp);
59205942

5943+
intel_dp_dpcd_set_probe(intel_dp, false);
5944+
59215945
if (!intel_dp_is_edp(intel_dp))
59225946
drm_dp_set_subconnector_property(&connector->base,
59235947
status,
@@ -5948,6 +5972,8 @@ intel_dp_force(struct drm_connector *_connector)
59485972
return;
59495973

59505974
intel_dp_set_edid(intel_dp);
5975+
5976+
intel_dp_dpcd_set_probe(intel_dp, false);
59515977
}
59525978

59535979
static int intel_dp_get_modes(struct drm_connector *_connector)
@@ -6320,10 +6346,11 @@ intel_dp_hpd_pulse(struct intel_digital_port *dig_port, bool long_hpd)
63206346
* complete the DP tunnel BW request for the latter connector/encoder
63216347
* waiting for this encoder's DPRX read, perform a dummy read here.
63226348
*/
6323-
if (long_hpd)
6349+
if (long_hpd) {
6350+
intel_dp_dpcd_set_probe(intel_dp, true);
6351+
63246352
intel_dp_read_dprx_caps(intel_dp, dpcd);
63256353

6326-
if (long_hpd) {
63276354
intel_dp->reset_link_params = true;
63286355
intel_dp_invalidate_source_oui(intel_dp);
63296356

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,5 +213,6 @@ int intel_dp_compute_min_hblank(struct intel_crtc_state *crtc_state,
213213
const struct drm_connector_state *conn_state);
214214

215215
int intel_dp_dsc_bpp_step_x16(const struct intel_connector *connector);
216+
void intel_dp_dpcd_set_probe(struct intel_dp *intel_dp, bool force_on_external);
216217

217218
#endif /* __INTEL_DP_H__ */

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,8 @@ void intel_dp_aux_init(struct intel_dp *intel_dp)
834834

835835
intel_dp->aux.transfer = intel_dp_aux_transfer;
836836
cpu_latency_qos_add_request(&intel_dp->pm_qos, PM_QOS_DEFAULT_VALUE);
837+
838+
intel_dp_dpcd_set_probe(intel_dp, true);
837839
}
838840

839841
static enum aux_ch default_aux_ch(struct intel_encoder *encoder)

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "intel_display_core.h"
3434
#include "intel_display_rpm.h"
3535
#include "intel_display_types.h"
36+
#include "intel_dp.h"
3637
#include "intel_hdcp.h"
3738
#include "intel_hotplug.h"
3839
#include "intel_hotplug_irq.h"
@@ -906,9 +907,14 @@ void intel_hpd_poll_enable(struct intel_display *display)
906907
*/
907908
void intel_hpd_poll_disable(struct intel_display *display)
908909
{
910+
struct intel_encoder *encoder;
911+
909912
if (!HAS_DISPLAY(display))
910913
return;
911914

915+
for_each_intel_dp(display->drm, encoder)
916+
intel_dp_dpcd_set_probe(enc_to_intel_dp(encoder), true);
917+
912918
WRITE_ONCE(display->hotplug.poll_enabled, false);
913919

914920
spin_lock_irq(&display->irq.lock);

0 commit comments

Comments
 (0)