diff mbox series

drm/i915: Fix the HDMI hot plug disconnection failure

Message ID 1538543556-31778-1-git-send-email-guang.bai@intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: Fix the HDMI hot plug disconnection failure | expand

Commit Message

Guang Bai Oct. 3, 2018, 5:12 a.m. UTC
On some platforms, slowly unplugging (wiggling) the HDMI cable makes
the kernel to believe the HDMI display still connected. This is because
the HDMI DDC lines are disconnected sometimes later after the hot-plug
interrupt triggered. Use the hot plug live states to honor HDMI hot plug
status in addtion to access the DDC channels.

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Chris Chiu <chiu@endlessm.com>
Signed-off-by: Guang Bai <guang.bai@intel.com>
---
 drivers/gpu/drm/i915/intel_hotplug.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

Comments

Chris Chiu Oct. 3, 2018, 9:22 a.m. UTC | #1
It works on my problematic laptops. Verified on X530UN and X560UD.
On Wed, Oct 3, 2018 at 1:23 PM Guang Bai <guang.bai@intel.com> wrote:
>
> On some platforms, slowly unplugging (wiggling) the HDMI cable makes
> the kernel to believe the HDMI display still connected. This is because
> the HDMI DDC lines are disconnected sometimes later after the hot-plug
> interrupt triggered. Use the hot plug live states to honor HDMI hot plug
> status in addtion to access the DDC channels.
>
> Cc: Jani Nikula <jani.nikula@intel.com>
> Cc: Chris Chiu <chiu@endlessm.com>
> Signed-off-by: Guang Bai <guang.bai@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hotplug.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
> index 648a13c..db6288f 100644
> --- a/drivers/gpu/drm/i915/intel_hotplug.c
> +++ b/drivers/gpu/drm/i915/intel_hotplug.c
> @@ -246,17 +246,42 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
>         intel_runtime_pm_put(dev_priv);
>  }
>
> +#define MAX_SHORT_PULSE_MS     100
> +#define PORT_CHECK_LOOP_COUNT  3
> +
>  bool intel_encoder_hotplug(struct intel_encoder *encoder,
>                            struct intel_connector *connector)
>  {
>         struct drm_device *dev = connector->base.dev;
> -       enum drm_connector_status old_status;
> +       enum drm_connector_status old_status, new_status;
> +       enum hpd_pin pin = encoder->hpd_pin;
> +       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +       u32 count = 0;
>
>         WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
>         old_status = connector->base.status;
>
> -       connector->base.status =
> -               drm_helper_probe_detect(&connector->base, NULL, false);
> +       /*
> +        * Set HDMI connection status based on hot-plug live states and
> +        * display probe results.
> +        */
> +       if ((encoder->type == INTEL_OUTPUT_HDMI ||
> +            encoder->type == INTEL_OUTPUT_DDI) &&
> +           dev_priv->hotplug.stats[pin].state == HPD_ENABLED) {
> +               do {
> +                       new_status = connector_status_disconnected;
> +                       msleep(MAX_SHORT_PULSE_MS);
> +
> +                       if (intel_digital_port_connected(encoder))
> +                               new_status = drm_helper_probe_detect(&connector->base,
> +                                                                    NULL, false);
> +                       if (new_status == connector_status_connected)
> +                               break;
> +               } while (++count <= PORT_CHECK_LOOP_COUNT);
> +               connector->base.status = new_status;
> +       } else
> +               connector->base.status =
> +                       drm_helper_probe_detect(&connector->base, NULL, false);
>
>         if (old_status == connector->base.status)
>                 return false;
> --
> 2.7.4
>
Martin Peres Oct. 3, 2018, 9:52 a.m. UTC | #2
On 03/10/2018 12:34, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915: Fix the HDMI hot plug disconnection failure
> URL   : https://patchwork.freedesktop.org/series/50477/
> State : failure
> 
> == Summary ==
> 
> = CI Bug Log - changes from CI_DRM_4916_full -> Patchwork_10333_full =
> 
> == Summary - FAILURE ==
> 
>   Serious unknown changes coming with Patchwork_10333_full absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_10333_full, please notify your bug team to allow them
>   to document this new failure mode, which will reduce false positives in CI.
> 
>   
> 
> == Possible new issues ==
> 
>   Here are the unknown changes that may have been introduced in Patchwork_10333_full:
> 
>   === IGT changes ===
> 
>     ==== Possible regressions ====
> 
>     igt@kms_color@pipe-c-ctm-max:
>       shard-apl:          PASS -> FAIL

Known issue: https://bugs.freedesktop.org/show_bug.cgi?id=108147

Martin

> 
>     
>     ==== Warnings ====
> 
>     igt@pm_rc6_residency@rc6-accuracy:
>       shard-kbl:          SKIP -> PASS
>       shard-snb:          SKIP -> PASS
> 
>     
> == Known issues ==
> 
>   Here are the changes found in Patchwork_10333_full that come from known issues:
> 
>   === IGT changes ===
> 
>     ==== Issues hit ====
> 
>     igt@gem_exec_schedule@pi-ringfull-bsd:
>       shard-glk:          NOTRUN -> FAIL (fdo#103158)
> 
>     igt@gem_ppgtt@blt-vs-render-ctx0:
>       shard-skl:          NOTRUN -> TIMEOUT (fdo#108039, fdo#108130)
> 
>     igt@kms_busy@extended-modeset-hang-newfb-render-c:
>       shard-glk:          NOTRUN -> DMESG-WARN (fdo#107956) +1
> 
>     igt@kms_busy@extended-modeset-hang-newfb-with-reset-render-b:
>       shard-snb:          NOTRUN -> DMESG-WARN (fdo#107956)
> 
>     igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-c:
>       shard-skl:          NOTRUN -> DMESG-WARN (fdo#107956) +1
> 
>     igt@kms_cursor_crc@cursor-128x42-onscreen:
>       shard-skl:          NOTRUN -> FAIL (fdo#103232)
> 
>     igt@kms_cursor_crc@cursor-128x42-random:
>       shard-glk:          PASS -> FAIL (fdo#103232) +1
> 
>     igt@kms_cursor_crc@cursor-256x256-suspend:
>       shard-glk:          NOTRUN -> FAIL (fdo#103232)
> 
>     igt@kms_cursor_crc@cursor-256x85-onscreen:
>       shard-apl:          PASS -> FAIL (fdo#103232) +1
> 
>     igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-blt:
>       shard-glk:          PASS -> FAIL (fdo#103167)
> 
>     igt@kms_frontbuffer_tracking@fbc-1p-primscrn-spr-indfb-draw-pwrite:
>       shard-skl:          NOTRUN -> FAIL (fdo#103167) +1
>       shard-glk:          NOTRUN -> FAIL (fdo#103167)
> 
>     igt@kms_plane@plane-position-covered-pipe-b-planes:
>       shard-glk:          PASS -> FAIL (fdo#103166)
> 
>     {igt@kms_plane_alpha_blend@pipe-a-alpha-7efc}:
>       shard-skl:          NOTRUN -> FAIL (fdo#108145) +1
> 
>     {igt@kms_plane_alpha_blend@pipe-a-constant-alpha-max}:
>       shard-glk:          NOTRUN -> FAIL (fdo#108145) +2
> 
>     {igt@kms_plane_alpha_blend@pipe-b-constant-alpha-max}:
>       shard-apl:          NOTRUN -> FAIL (fdo#108145)
> 
>     igt@kms_plane_multiple@atomic-pipe-b-tiling-yf:
>       shard-apl:          PASS -> FAIL (fdo#103166)
> 
>     igt@kms_setmode@basic:
>       shard-glk:          NOTRUN -> FAIL (fdo#99912)
>       shard-hsw:          PASS -> FAIL (fdo#99912)
>       shard-snb:          NOTRUN -> FAIL (fdo#99912)
> 
>     igt@kms_sysfs_edid_timing:
>       shard-skl:          NOTRUN -> FAIL (fdo#100047)
> 
>     igt@pm_rpm@modeset-non-lpsp:
>       shard-skl:          NOTRUN -> INCOMPLETE (fdo#107807)
> 
>     igt@pm_rpm@modeset-non-lpsp-stress-no-wait:
>       shard-skl:          SKIP -> INCOMPLETE (fdo#107807)
> 
>     igt@syncobj_basic@illegal-fd-to-handle:
>       shard-glk:          PASS -> DMESG-WARN (fdo#105763, fdo#106538) +1
> 
>     
>     ==== Possible fixes ====
> 
>     igt@gem_exec_await@wide-contexts:
>       shard-apl:          FAIL (fdo#106680) -> PASS
> 
>     igt@kms_cursor_crc@cursor-64x21-random:
>       shard-glk:          FAIL (fdo#103232) -> PASS
> 
>     igt@kms_flip@flip-vs-expired-vblank:
>       shard-skl:          FAIL (fdo#105363) -> PASS
> 
>     igt@kms_plane_multiple@atomic-pipe-b-tiling-x:
>       shard-glk:          FAIL (fdo#103166) -> PASS
> 
>     igt@kms_setmode@basic:
>       shard-kbl:          FAIL (fdo#99912) -> PASS
> 
>     
>   {name}: This element is suppressed. This means it is ignored when computing
>           the status of the difference (SUCCESS, WARNING, or FAILURE).
> 
>   fdo#100047 https://bugs.freedesktop.org/show_bug.cgi?id=100047
>   fdo#103158 https://bugs.freedesktop.org/show_bug.cgi?id=103158
>   fdo#103166 https://bugs.freedesktop.org/show_bug.cgi?id=103166
>   fdo#103167 https://bugs.freedesktop.org/show_bug.cgi?id=103167
>   fdo#103232 https://bugs.freedesktop.org/show_bug.cgi?id=103232
>   fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363
>   fdo#105763 https://bugs.freedesktop.org/show_bug.cgi?id=105763
>   fdo#106538 https://bugs.freedesktop.org/show_bug.cgi?id=106538
>   fdo#106680 https://bugs.freedesktop.org/show_bug.cgi?id=106680
>   fdo#107807 https://bugs.freedesktop.org/show_bug.cgi?id=107807
>   fdo#107956 https://bugs.freedesktop.org/show_bug.cgi?id=107956
>   fdo#108039 https://bugs.freedesktop.org/show_bug.cgi?id=108039
>   fdo#108130 https://bugs.freedesktop.org/show_bug.cgi?id=108130
>   fdo#108145 https://bugs.freedesktop.org/show_bug.cgi?id=108145
>   fdo#99912 https://bugs.freedesktop.org/show_bug.cgi?id=99912
> 
> 
> == Participating hosts (6 -> 6) ==
> 
>   No changes in participating hosts
> 
> 
> == Build changes ==
> 
>     * Linux: CI_DRM_4916 -> Patchwork_10333
> 
>   CI_DRM_4916: c3900869be8592412dc71001c22c7452a7044eab @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_4662: ebf6a1dd1795e2f014ff3c47fe2eb4d5255845bd @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
>   Patchwork_10333: de3c5d5af683585af5574cfd32fe25ed597faf8e @ git://anongit.freedesktop.org/gfx-ci/linux
>   piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
> 
> == Logs ==
> 
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_10333/shards.html
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 648a13c..db6288f 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -246,17 +246,42 @@  static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
 	intel_runtime_pm_put(dev_priv);
 }
 
+#define MAX_SHORT_PULSE_MS	100
+#define PORT_CHECK_LOOP_COUNT	3
+
 bool intel_encoder_hotplug(struct intel_encoder *encoder,
 			   struct intel_connector *connector)
 {
 	struct drm_device *dev = connector->base.dev;
-	enum drm_connector_status old_status;
+	enum drm_connector_status old_status, new_status;
+	enum hpd_pin pin = encoder->hpd_pin;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	u32 count = 0;
 
 	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
 	old_status = connector->base.status;
 
-	connector->base.status =
-		drm_helper_probe_detect(&connector->base, NULL, false);
+	/*
+	 * Set HDMI connection status based on hot-plug live states and
+	 * display probe results.
+	 */
+	if ((encoder->type == INTEL_OUTPUT_HDMI ||
+	     encoder->type == INTEL_OUTPUT_DDI) &&
+	    dev_priv->hotplug.stats[pin].state == HPD_ENABLED) {
+		do {
+			new_status = connector_status_disconnected;
+			msleep(MAX_SHORT_PULSE_MS);
+
+			if (intel_digital_port_connected(encoder))
+				new_status = drm_helper_probe_detect(&connector->base,
+								     NULL, false);
+			if (new_status == connector_status_connected)
+				break;
+		} while (++count <= PORT_CHECK_LOOP_COUNT);
+		connector->base.status = new_status;
+	} else
+		connector->base.status =
+			drm_helper_probe_detect(&connector->base, NULL, false);
 
 	if (old_status == connector->base.status)
 		return false;