drm/i915: Add a retry counter for hotplug detect retries
authorImre Deak <imre.deak@intel.com>
Mon, 30 Mar 2020 09:54:24 +0000 (12:54 +0300)
committerImre Deak <imre.deak@intel.com>
Mon, 6 Apr 2020 14:53:51 +0000 (17:53 +0300)
On TypeC connectors we need to retry the detection after hotplug events
for a longer time, so add a retry counter to support this. The next
patch will add detection retries on TypeC ports needing this.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: José Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200330095425.29113-1-imre.deak@intel.com
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_dp.c
drivers/gpu/drm/i915/display/intel_hdmi.c
drivers/gpu/drm/i915/display/intel_hotplug.c
drivers/gpu/drm/i915/display/intel_hotplug.h
drivers/gpu/drm/i915/display/intel_sdvo.c

index 7184f3b8f0915d95d955affb794d147ea07a66c4..1bc6bfb2511e303affe1d9dee9f5fdbe8e0ae4dd 100644 (file)
@@ -4518,15 +4518,14 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
 
 static enum intel_hotplug_state
 intel_ddi_hotplug(struct intel_encoder *encoder,
-                 struct intel_connector *connector,
-                 bool irq_received)
+                 struct intel_connector *connector)
 {
        struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
        struct drm_modeset_acquire_ctx ctx;
        enum intel_hotplug_state state;
        int ret;
 
-       state = intel_encoder_hotplug(encoder, connector, irq_received);
+       state = intel_encoder_hotplug(encoder, connector);
 
        drm_modeset_acquire_init(&ctx, 0);
 
@@ -4565,7 +4564,7 @@ intel_ddi_hotplug(struct intel_encoder *encoder,
         * time around we didn't detect any change in the sink's connection
         * status.
         */
-       if (state == INTEL_HOTPLUG_UNCHANGED && irq_received &&
+       if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries &&
            !dig_port->dp.is_mst)
                state = INTEL_HOTPLUG_RETRY;
 
index 2bedd626c686d877af812419b12acd430be1d17e..5a0adf14ebefe58c68d9315711c15a40c9fbe99f 100644 (file)
@@ -132,8 +132,7 @@ struct intel_encoder {
        u16 cloneable;
        u8 pipe_mask;
        enum intel_hotplug_state (*hotplug)(struct intel_encoder *encoder,
-                                           struct intel_connector *connector,
-                                           bool irq_received);
+                                           struct intel_connector *connector);
        enum intel_output_type (*compute_output_type)(struct intel_encoder *,
                                                      struct intel_crtc_state *,
                                                      struct drm_connector_state *);
@@ -432,6 +431,9 @@ struct intel_connector {
        struct edid *edid;
        struct edid *detect_edid;
 
+       /* Number of times hotplug detection was tried after an HPD interrupt */
+       int hotplug_retries;
+
        /* since POLL and HPD connectors may use the same HPD line keep the native
           state of connector->polled in case hotplug storm detection changes it */
        u8 polled;
index db6ae8e9af6e91bff62ea4b3317777a6d2f17d72..25f0baafd6d04e5ded8cc7222c14fb8df25c4756 100644 (file)
@@ -5571,14 +5571,13 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
  */
 static enum intel_hotplug_state
 intel_dp_hotplug(struct intel_encoder *encoder,
-                struct intel_connector *connector,
-                bool irq_received)
+                struct intel_connector *connector)
 {
        struct drm_modeset_acquire_ctx ctx;
        enum intel_hotplug_state state;
        int ret;
 
-       state = intel_encoder_hotplug(encoder, connector, irq_received);
+       state = intel_encoder_hotplug(encoder, connector);
 
        drm_modeset_acquire_init(&ctx, 0);
 
@@ -5602,7 +5601,7 @@ intel_dp_hotplug(struct intel_encoder *encoder,
         * Keeping it consistent with intel_ddi_hotplug() and
         * intel_hdmi_hotplug().
         */
-       if (state == INTEL_HOTPLUG_UNCHANGED && irq_received)
+       if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
                state = INTEL_HOTPLUG_RETRY;
 
        return state;
index 7e37b7fdefe6da4800c572ba3a4b35f547975a7e..011d83c2a1e31435cec1c7401ada2599d7c7a0cf 100644 (file)
@@ -3279,11 +3279,11 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
 
 static enum intel_hotplug_state
 intel_hdmi_hotplug(struct intel_encoder *encoder,
-                  struct intel_connector *connector, bool irq_received)
+                  struct intel_connector *connector)
 {
        enum intel_hotplug_state state;
 
-       state = intel_encoder_hotplug(encoder, connector, irq_received);
+       state = intel_encoder_hotplug(encoder, connector);
 
        /*
         * On many platforms the HDMI live state signal is known to be
@@ -3297,7 +3297,7 @@ intel_hdmi_hotplug(struct intel_encoder *encoder,
         * time around we didn't detect any change in the sink's connection
         * status.
         */
-       if (state == INTEL_HOTPLUG_UNCHANGED && irq_received)
+       if (state == INTEL_HOTPLUG_UNCHANGED && !connector->hotplug_retries)
                state = INTEL_HOTPLUG_RETRY;
 
        return state;
index a091442efba4d46668d38499a42f47400bc121c3..4f6f560e093e9224f80f90e58901b7c1c140af75 100644 (file)
@@ -270,8 +270,7 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 
 enum intel_hotplug_state
 intel_encoder_hotplug(struct intel_encoder *encoder,
-                     struct intel_connector *connector,
-                     bool irq_received)
+                     struct intel_connector *connector)
 {
        struct drm_device *dev = connector->base.dev;
        enum drm_connector_status old_status;
@@ -392,12 +391,17 @@ static void i915_hotplug_work_func(struct work_struct *work)
                        struct intel_encoder *encoder =
                                intel_attached_encoder(connector);
 
+                       if (hpd_event_bits & hpd_bit)
+                               connector->hotplug_retries = 0;
+                       else
+                               connector->hotplug_retries++;
+
                        drm_dbg_kms(&dev_priv->drm,
-                                   "Connector %s (pin %i) received hotplug event.\n",
-                                   connector->base.name, pin);
+                                   "Connector %s (pin %i) received hotplug event. (retry %d)\n",
+                                   connector->base.name, pin,
+                                   connector->hotplug_retries);
 
-                       switch (encoder->hotplug(encoder, connector,
-                                                hpd_event_bits & hpd_bit)) {
+                       switch (encoder->hotplug(encoder, connector)) {
                        case INTEL_HOTPLUG_UNCHANGED:
                                break;
                        case INTEL_HOTPLUG_CHANGED:
index 1e6b4fda2900ae8cdcfc5b083b2da4b4e4f29950..777b0743257e5487c1a4159320d6eb248cea7548 100644 (file)
@@ -15,8 +15,7 @@ enum port;
 
 void intel_hpd_poll_init(struct drm_i915_private *dev_priv);
 enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder,
-                                              struct intel_connector *connector,
-                                              bool irq_received);
+                                              struct intel_connector *connector);
 void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
                           u32 pin_mask, u32 long_mask);
 void intel_hpd_init(struct drm_i915_private *dev_priv);
index e6306cbb7a3ae47b9e552659136f71c7b595aa55..bc6c26818e152ba651e6f5ab91e7b9bac55cfed6 100644 (file)
@@ -1939,12 +1939,11 @@ static void intel_sdvo_enable_hotplug(struct intel_encoder *encoder)
 
 static enum intel_hotplug_state
 intel_sdvo_hotplug(struct intel_encoder *encoder,
-                  struct intel_connector *connector,
-                  bool irq_received)
+                  struct intel_connector *connector)
 {
        intel_sdvo_enable_hotplug(encoder);
 
-       return intel_encoder_hotplug(encoder, connector, irq_received);
+       return intel_encoder_hotplug(encoder, connector);
 }
 
 static bool