Currently, link-training fallback is only implemented for SST, so having modeset_retry_work in intel_connector makes sense. However, we hope to implement link training fallback for MST in a follow-up patchset, so moving modeset_retry_work to indel_dp will make handling both SST and MST connectors simpler. This patch does exactly that, and updates all modeset_retry_work dependencies to use an intel_dp instead. Credit: this patch is a rebase of Lyude Pual's original patch: https://patchwork.freedesktop.org/patch/216627/?series=41576&rev=3 Change-Id: I3d80d58b05efe7b07450fb800c438c6e2a34f30c Signed-off-by: Gil Dekel <gildekel@xxxxxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_display.c | 14 +++++++++++--- drivers/gpu/drm/i915/display/intel_display_types.h | 6 +++--- drivers/gpu/drm/i915/display/intel_dp.c | 11 ++++------- .../gpu/drm/i915/display/intel_dp_link_training.c | 3 +-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index f387215f713af..8e3c7abda3193 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8937,20 +8937,28 @@ void intel_display_resume(struct drm_device *dev) static void intel_hpd_poll_fini(struct drm_i915_private *i915) { - struct intel_connector *connector; struct drm_connector_list_iter conn_iter; + struct intel_connector *connector; + struct intel_dp *intel_dp; + struct intel_encoder *encoder; /* Kill all the work that may have been queued by hpd. */ drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { - if (connector->modeset_retry_work.func) - cancel_work_sync(&connector->modeset_retry_work); if (connector->hdcp.shim) { cancel_delayed_work_sync(&connector->hdcp.check_work); cancel_work_sync(&connector->hdcp.prop_work); } } drm_connector_list_iter_end(&conn_iter); + + for_each_intel_dp(&i915->drm, encoder) { + if (encoder->type == DRM_MODE_CONNECTOR_eDP || + encoder->type == DRM_MODE_CONNECTOR_DisplayPort) { + intel_dp = enc_to_intel_dp(encoder); + cancel_work_sync(&intel_dp->modeset_retry_work); + } + } } /* part #1: call before irq uninstall */ diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 4b88f4d60a81f..9181a2fef81e0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -608,9 +608,6 @@ struct intel_connector { struct intel_dp *mst_port; - /* Work struct to schedule a uevent on link train failure */ - struct work_struct modeset_retry_work; - struct intel_hdcp hdcp; }; @@ -1724,6 +1721,9 @@ struct intel_dp { /* Displayport compliance testing */ struct intel_dp_compliance compliance; + /* Work struct to schedule a uevent on link train failure */ + struct work_struct modeset_retry_work; + /* Downstream facing port caps */ struct { int min_tmds_clock, max_tmds_clock; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 9a5bcd630068e..2e562e09c704e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5323,12 +5323,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, static void intel_dp_modeset_retry_work_fn(struct work_struct *work) { - struct intel_connector *intel_connector; - struct drm_connector *connector; - - intel_connector = container_of(work, typeof(*intel_connector), - modeset_retry_work); - connector = &intel_connector->base; + struct intel_dp *intel_dp = + container_of(work, typeof(*intel_dp), modeset_retry_work); + struct drm_connector *connector = &intel_dp->attached_connector->base; drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id, connector->name); @@ -5358,7 +5355,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port, int type; /* Initialize the work for modeset in case of link train failure */ - INIT_WORK(&intel_connector->modeset_retry_work, + INIT_WORK(&intel_dp->modeset_retry_work, intel_dp_modeset_retry_work_fn); if (drm_WARN(dev, dig_port->max_lanes < 1, diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 720af16a654c9..6f16609a0820b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1107,7 +1107,6 @@ intel_dp_link_train_phy(struct intel_dp *intel_dp, static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { - struct intel_connector *intel_connector = intel_dp->attached_connector; struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; if (intel_dp->hobl_active) { @@ -1123,7 +1122,7 @@ static void intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp, } /* Schedule a Hotplug Uevent to userspace to start modeset */ - schedule_work(&intel_connector->modeset_retry_work); + schedule_work(&intel_dp->modeset_retry_work); } /* Perform the link training on all LTTPRs and the DPRX on a link. */ -- Gil Dekel, Software Engineer, Google / ChromeOS Display and Graphics