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

Signed-off-by: Gil Dekel <gilde...@chromium.org>
---
 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 db3c26e013e3..2ec75aa0b4ee 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7962,20 +7962,28 @@ void i830_disable_pipe(struct drm_i915_private 
*dev_priv, enum pipe pipe)

 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);
+               }
+       }
 }

 bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 731f2ec04d5c..b92bb69a3fe4 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -620,9 +620,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;
 };

@@ -1779,6 +1776,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 01b180c8d9bd..42353b1ac487 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -5992,12 +5992,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);

@@ -6027,7 +6024,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 31d0d7854003..87d13cd03ef5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1063,7 +1063,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 drm_i915_private *i915 = dp_to_i915(intel_dp);

        if (!intel_digital_port_connected(&dp_to_dig_port(intel_dp)->base)) {
@@ -1082,7 +1081,7 @@ static void 
intel_dp_schedule_fallback_link_training(struct intel_dp *intel_dp,
        }

        /* Schedule a Hotplug Uevent to userspace to start modeset */
-       queue_work(i915->unordered_wq, &intel_connector->modeset_retry_work);
+       queue_work(i915->unordered_wq, &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

Reply via email to