Home Home > GIT Browse > SLE15-SP1
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2019-01-10 16:17:04 +0100
committerThomas Zimmermann <tzimmermann@suse.de>2019-01-17 15:28:26 +0100
commitbfb4810c4c5a30363c4517c5501cab6c9eff51e7 (patch)
tree208e6d689ab4b6be3201cf73060b6b6787d544ca
parent294d3ec6c587b5245846b9eb5ad38b9cdd0f4c87 (diff)
drm/i915: Fix hpd handling for pins with two encoders (bsc#1113956)
-rw-r--r--patches.drm/0071-drm-i915-Fix-hpd-handling-for-pins-with-two-encoders.patch141
-rw-r--r--series.conf1
2 files changed, 142 insertions, 0 deletions
diff --git a/patches.drm/0071-drm-i915-Fix-hpd-handling-for-pins-with-two-encoders.patch b/patches.drm/0071-drm-i915-Fix-hpd-handling-for-pins-with-two-encoders.patch
new file mode 100644
index 0000000000..e6f4bfb6fe
--- /dev/null
+++ b/patches.drm/0071-drm-i915-Fix-hpd-handling-for-pins-with-two-encoders.patch
@@ -0,0 +1,141 @@
+From 5a3aeca97af1b6b3498d59a7fd4e8bb95814c108 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Thu, 8 Nov 2018 22:04:24 +0200
+Subject: drm/i915: Fix hpd handling for pins with two encoders
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Git-commit: 5a3aeca97af1b6b3498d59a7fd4e8bb95814c108
+Patch-mainline: v5.0-rc1
+References: bsc#1113956
+
+In my haste to remove irq_port[] I accidentally changed the
+way we deal with hpd pins that are shared by multiple encoders
+(DP and HDMI for pre-DDI platforms). Previously we would only
+handle such pins via ->hpd_pulse(), but now we queue up the
+hotplug work for the HDMI encoder directly. Worse yet, we now
+count each hpd twice and this increment the hpd storm count
+twice as fast. This can lead to spurious storms being detected.
+
+Go back to the old way of doing things, ie. delegate to
+->hpd_pulse() for any pin which has an encoder with that hook
+implemented. I don't really like the idea of adding irq_port[]
+back so let's loop through the encoders first to check if we
+have an encoder with ->hpd_pulse() for the pin, and then go
+through all the pins and decided on the correct course of action
+based on the earlier findings.
+
+I have occasionally toyed with the idea of unifying the pre-DDI
+HDMI and DP encoders into a single encoder as well. Besides the
+hotplug processing it would have the other benefit of preventing
+userspace from trying to enable both encoders at the same time.
+That is simply illegal as they share the same clock/data pins.
+We have some testcases that will attempt that and thus fail on
+many older machines. But for now let's stick to fixing just the
+hotplug code.
+
+Cc: stable@vger.kernel.org # 4.19+
+Cc: Lyude Paul <lyude@redhat.com>
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Fixes: b6ca3eee18ba ("drm/i915: Nuke dev_priv->irq_port[]")
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20181108200424.28371-1-ville.syrjala@linux.intel.com
+Reviewed-by: Lyude Paul <lyude@redhat.com>
+Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+---
+ drivers/gpu/drm/i915/intel_hotplug.c | 63 ++++++++++++++++++++++++-----------
+ 1 file changed, 44 insertions(+), 19 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_hotplug.c
++++ b/drivers/gpu/drm/i915/intel_hotplug.c
+@@ -395,37 +395,54 @@ void intel_hpd_irq_handler(struct drm_i9
+ struct intel_encoder *encoder;
+ bool storm_detected = false;
+ bool queue_dig = false, queue_hp = false;
++ u32 long_hpd_pulse_mask = 0;
++ u32 short_hpd_pulse_mask = 0;
++ enum hpd_pin pin;
+
+ if (!pin_mask)
+ return;
+
+ spin_lock(&dev_priv->irq_lock);
++
++ /*
++ * Determine whether ->hpd_pulse() exists for each pin, and
++ * whether we have a short or a long pulse. This is needed
++ * as each pin may have up to two encoders (HDMI and DP) and
++ * only the one of them (DP) will have ->hpd_pulse().
++ */
+ for_each_intel_encoder(&dev_priv->drm, encoder) {
+- enum hpd_pin pin = encoder->hpd_pin;
+ bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
++ enum port port = encoder->port;
++ bool long_hpd;
+
++ pin = encoder->hpd_pin;
+ if (!(BIT(pin) & pin_mask))
+ continue;
+
+- if (has_hpd_pulse) {
+- bool long_hpd = long_mask & BIT(pin);
+- enum port port = encoder->port;
++ if (!has_hpd_pulse)
++ continue;
+
+- DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
+- long_hpd ? "long" : "short");
+- /*
+- * For long HPD pulses we want to have the digital queue happen,
+- * but we still want HPD storm detection to function.
+- */
+- queue_dig = true;
+- if (long_hpd) {
+- dev_priv->hotplug.long_port_mask |= (1 << port);
+- } else {
+- /* for short HPD just trigger the digital queue */
+- dev_priv->hotplug.short_port_mask |= (1 << port);
+- continue;
+- }
++ long_hpd = long_mask & BIT(pin);
++
++ DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
++ long_hpd ? "long" : "short");
++ queue_dig = true;
++
++ if (long_hpd) {
++ long_hpd_pulse_mask |= BIT(pin);
++ dev_priv->hotplug.long_port_mask |= BIT(port);
++ } else {
++ short_hpd_pulse_mask |= BIT(pin);
++ dev_priv->hotplug.short_port_mask |= BIT(port);
+ }
++ }
++
++ /* Now process each pin just once */
++ for_each_hpd_pin(pin) {
++ bool long_hpd;
++
++ if (!(BIT(pin) & pin_mask))
++ continue;
+
+ if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
+ /*
+@@ -442,8 +459,16 @@ void intel_hpd_irq_handler(struct drm_i9
+ if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
+ continue;
+
+- if (!has_hpd_pulse) {
++ /*
++ * Delegate to ->hpd_pulse() if one of the encoders for this
++ * pin has it, otherwise let the hotplug_work deal with this
++ * pin directly.
++ */
++ if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) {
++ long_hpd = long_hpd_pulse_mask & BIT(pin);
++ } else {
+ dev_priv->hotplug.event_bits |= BIT(pin);
++ long_hpd = true;
+ queue_hp = true;
+ }
+
diff --git a/series.conf b/series.conf
index 86930ff634..8aca53ff9d 100644
--- a/series.conf
+++ b/series.conf
@@ -42098,6 +42098,7 @@
patches.drm/0062-drm-i915-Fix-error-handling-for-the-NV12-fb-dimensio.patch
patches.drm/0063-drm-i915-icl-Fix-the-macros-for-DFLEXDPMLE-register-.patch
patches.drivers/ALSA-x86-Fix-runtime-PM-for-hdmi-lpe-audio.patch
+ patches.drm/0071-drm-i915-Fix-hpd-handling-for-pins-with-two-encoders.patch
patches.drm/0001-drm-rcar-du-Fix-vblank-initialization.patch
patches.drm/0001-drm-rcar-du-Fix-external-clock-error-checks.patch
patches.drivers/ALSA-usb-audio-Define-registers-for-CM6206.patch