aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hotplug.c')
-rw-r--r--drivers/gpu/drm/i915/intel_hotplug.c131
1 files changed, 90 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c
index 648a13c6043c..e24174d08fed 100644
--- a/drivers/gpu/drm/i915/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/intel_hotplug.c
@@ -114,51 +114,68 @@ enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
114#define HPD_STORM_REENABLE_DELAY (2 * 60 * 1000) 114#define HPD_STORM_REENABLE_DELAY (2 * 60 * 1000)
115 115
116/** 116/**
117 * intel_hpd_irq_storm_detect - gather stats and detect HPD irq storm on a pin 117 * intel_hpd_irq_storm_detect - gather stats and detect HPD IRQ storm on a pin
118 * @dev_priv: private driver data pointer 118 * @dev_priv: private driver data pointer
119 * @pin: the pin to gather stats on 119 * @pin: the pin to gather stats on
120 * @long_hpd: whether the HPD IRQ was long or short
120 * 121 *
121 * Gather stats about HPD irqs from the specified @pin, and detect irq 122 * Gather stats about HPD IRQs from the specified @pin, and detect IRQ
122 * storms. Only the pin specific stats and state are changed, the caller is 123 * storms. Only the pin specific stats and state are changed, the caller is
123 * responsible for further action. 124 * responsible for further action.
124 * 125 *
125 * The number of irqs that are allowed within @HPD_STORM_DETECT_PERIOD is 126 * The number of IRQs that are allowed within @HPD_STORM_DETECT_PERIOD is
126 * stored in @dev_priv->hotplug.hpd_storm_threshold which defaults to 127 * stored in @dev_priv->hotplug.hpd_storm_threshold which defaults to
127 * @HPD_STORM_DEFAULT_THRESHOLD. If this threshold is exceeded, it's 128 * @HPD_STORM_DEFAULT_THRESHOLD. Long IRQs count as +10 to this threshold, and
128 * considered an irq storm and the irq state is set to @HPD_MARK_DISABLED. 129 * short IRQs count as +1. If this threshold is exceeded, it's considered an
130 * IRQ storm and the IRQ state is set to @HPD_MARK_DISABLED.
131 *
132 * By default, most systems will only count long IRQs towards
133 * &dev_priv->hotplug.hpd_storm_threshold. However, some older systems also
134 * suffer from short IRQ storms and must also track these. Because short IRQ
135 * storms are naturally caused by sideband interactions with DP MST devices,
136 * short IRQ detection is only enabled for systems without DP MST support.
137 * Systems which are new enough to support DP MST are far less likely to
138 * suffer from IRQ storms at all, so this is fine.
129 * 139 *
130 * The HPD threshold can be controlled through i915_hpd_storm_ctl in debugfs, 140 * The HPD threshold can be controlled through i915_hpd_storm_ctl in debugfs,
131 * and should only be adjusted for automated hotplug testing. 141 * and should only be adjusted for automated hotplug testing.
132 * 142 *
133 * Return true if an irq storm was detected on @pin. 143 * Return true if an IRQ storm was detected on @pin.
134 */ 144 */
135static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv, 145static bool intel_hpd_irq_storm_detect(struct drm_i915_private *dev_priv,
136 enum hpd_pin pin) 146 enum hpd_pin pin, bool long_hpd)
137{ 147{
138 unsigned long start = dev_priv->hotplug.stats[pin].last_jiffies; 148 struct i915_hotplug *hpd = &dev_priv->hotplug;
149 unsigned long start = hpd->stats[pin].last_jiffies;
139 unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD); 150 unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD);
140 const int threshold = dev_priv->hotplug.hpd_storm_threshold; 151 const int increment = long_hpd ? 10 : 1;
152 const int threshold = hpd->hpd_storm_threshold;
141 bool storm = false; 153 bool storm = false;
142 154
155 if (!threshold ||
156 (!long_hpd && !dev_priv->hotplug.hpd_short_storm_enabled))
157 return false;
158
143 if (!time_in_range(jiffies, start, end)) { 159 if (!time_in_range(jiffies, start, end)) {
144 dev_priv->hotplug.stats[pin].last_jiffies = jiffies; 160 hpd->stats[pin].last_jiffies = jiffies;
145 dev_priv->hotplug.stats[pin].count = 0; 161 hpd->stats[pin].count = 0;
146 DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", pin); 162 }
147 } else if (dev_priv->hotplug.stats[pin].count > threshold && 163
148 threshold) { 164 hpd->stats[pin].count += increment;
149 dev_priv->hotplug.stats[pin].state = HPD_MARK_DISABLED; 165 if (hpd->stats[pin].count > threshold) {
166 hpd->stats[pin].state = HPD_MARK_DISABLED;
150 DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", pin); 167 DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", pin);
151 storm = true; 168 storm = true;
152 } else { 169 } else {
153 dev_priv->hotplug.stats[pin].count++;
154 DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", pin, 170 DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", pin,
155 dev_priv->hotplug.stats[pin].count); 171 hpd->stats[pin].count);
156 } 172 }
157 173
158 return storm; 174 return storm;
159} 175}
160 176
161static void intel_hpd_irq_storm_disable(struct drm_i915_private *dev_priv) 177static void
178intel_hpd_irq_storm_switch_to_polling(struct drm_i915_private *dev_priv)
162{ 179{
163 struct drm_device *dev = &dev_priv->drm; 180 struct drm_device *dev = &dev_priv->drm;
164 struct intel_connector *intel_connector; 181 struct intel_connector *intel_connector;
@@ -228,7 +245,9 @@ static void intel_hpd_irq_storm_reenable_work(struct work_struct *work)
228 drm_for_each_connector_iter(connector, &conn_iter) { 245 drm_for_each_connector_iter(connector, &conn_iter) {
229 struct intel_connector *intel_connector = to_intel_connector(connector); 246 struct intel_connector *intel_connector = to_intel_connector(connector);
230 247
231 if (intel_connector->encoder->hpd_pin == pin) { 248 /* Don't check MST ports, they don't have pins */
249 if (!intel_connector->mst_port &&
250 intel_connector->encoder->hpd_pin == pin) {
232 if (connector->polled != intel_connector->polled) 251 if (connector->polled != intel_connector->polled)
233 DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n", 252 DRM_DEBUG_DRIVER("Reenabling HPD on connector %s\n",
234 connector->name); 253 connector->name);
@@ -346,8 +365,8 @@ static void i915_hotplug_work_func(struct work_struct *work)
346 hpd_event_bits = dev_priv->hotplug.event_bits; 365 hpd_event_bits = dev_priv->hotplug.event_bits;
347 dev_priv->hotplug.event_bits = 0; 366 dev_priv->hotplug.event_bits = 0;
348 367
349 /* Disable hotplug on connectors that hit an irq storm. */ 368 /* Enable polling for connectors which had HPD IRQ storms */
350 intel_hpd_irq_storm_disable(dev_priv); 369 intel_hpd_irq_storm_switch_to_polling(dev_priv);
351 370
352 spin_unlock_irq(&dev_priv->irq_lock); 371 spin_unlock_irq(&dev_priv->irq_lock);
353 372
@@ -395,37 +414,54 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
395 struct intel_encoder *encoder; 414 struct intel_encoder *encoder;
396 bool storm_detected = false; 415 bool storm_detected = false;
397 bool queue_dig = false, queue_hp = false; 416 bool queue_dig = false, queue_hp = false;
417 u32 long_hpd_pulse_mask = 0;
418 u32 short_hpd_pulse_mask = 0;
419 enum hpd_pin pin;
398 420
399 if (!pin_mask) 421 if (!pin_mask)
400 return; 422 return;
401 423
402 spin_lock(&dev_priv->irq_lock); 424 spin_lock(&dev_priv->irq_lock);
425
426 /*
427 * Determine whether ->hpd_pulse() exists for each pin, and
428 * whether we have a short or a long pulse. This is needed
429 * as each pin may have up to two encoders (HDMI and DP) and
430 * only the one of them (DP) will have ->hpd_pulse().
431 */
403 for_each_intel_encoder(&dev_priv->drm, encoder) { 432 for_each_intel_encoder(&dev_priv->drm, encoder) {
404 enum hpd_pin pin = encoder->hpd_pin;
405 bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder); 433 bool has_hpd_pulse = intel_encoder_has_hpd_pulse(encoder);
434 enum port port = encoder->port;
435 bool long_hpd;
406 436
437 pin = encoder->hpd_pin;
407 if (!(BIT(pin) & pin_mask)) 438 if (!(BIT(pin) & pin_mask))
408 continue; 439 continue;
409 440
410 if (has_hpd_pulse) { 441 if (!has_hpd_pulse)
411 bool long_hpd = long_mask & BIT(pin); 442 continue;
412 enum port port = encoder->port;
413 443
414 DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port), 444 long_hpd = long_mask & BIT(pin);
415 long_hpd ? "long" : "short"); 445
416 /* 446 DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", port_name(port),
417 * For long HPD pulses we want to have the digital queue happen, 447 long_hpd ? "long" : "short");
418 * but we still want HPD storm detection to function. 448 queue_dig = true;
419 */ 449
420 queue_dig = true; 450 if (long_hpd) {
421 if (long_hpd) { 451 long_hpd_pulse_mask |= BIT(pin);
422 dev_priv->hotplug.long_port_mask |= (1 << port); 452 dev_priv->hotplug.long_port_mask |= BIT(port);
423 } else { 453 } else {
424 /* for short HPD just trigger the digital queue */ 454 short_hpd_pulse_mask |= BIT(pin);
425 dev_priv->hotplug.short_port_mask |= (1 << port); 455 dev_priv->hotplug.short_port_mask |= BIT(port);
426 continue;
427 }
428 } 456 }
457 }
458
459 /* Now process each pin just once */
460 for_each_hpd_pin(pin) {
461 bool long_hpd;
462
463 if (!(BIT(pin) & pin_mask))
464 continue;
429 465
430 if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) { 466 if (dev_priv->hotplug.stats[pin].state == HPD_DISABLED) {
431 /* 467 /*
@@ -442,17 +478,30 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
442 if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED) 478 if (dev_priv->hotplug.stats[pin].state != HPD_ENABLED)
443 continue; 479 continue;
444 480
445 if (!has_hpd_pulse) { 481 /*
482 * Delegate to ->hpd_pulse() if one of the encoders for this
483 * pin has it, otherwise let the hotplug_work deal with this
484 * pin directly.
485 */
486 if (((short_hpd_pulse_mask | long_hpd_pulse_mask) & BIT(pin))) {
487 long_hpd = long_hpd_pulse_mask & BIT(pin);
488 } else {
446 dev_priv->hotplug.event_bits |= BIT(pin); 489 dev_priv->hotplug.event_bits |= BIT(pin);
490 long_hpd = true;
447 queue_hp = true; 491 queue_hp = true;
448 } 492 }
449 493
450 if (intel_hpd_irq_storm_detect(dev_priv, pin)) { 494 if (intel_hpd_irq_storm_detect(dev_priv, pin, long_hpd)) {
451 dev_priv->hotplug.event_bits &= ~BIT(pin); 495 dev_priv->hotplug.event_bits &= ~BIT(pin);
452 storm_detected = true; 496 storm_detected = true;
497 queue_hp = true;
453 } 498 }
454 } 499 }
455 500
501 /*
502 * Disable any IRQs that storms were detected on. Polling enablement
503 * happens later in our hotplug work.
504 */
456 if (storm_detected && dev_priv->display_irqs_enabled) 505 if (storm_detected && dev_priv->display_irqs_enabled)
457 dev_priv->display.hpd_irq_setup(dev_priv); 506 dev_priv->display.hpd_irq_setup(dev_priv);
458 spin_unlock(&dev_priv->irq_lock); 507 spin_unlock(&dev_priv->irq_lock);