diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display_power.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_hotplug.c | 42 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_hotplug.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 23 |
5 files changed, 46 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 5a07763e71bc..a8a39c0fe7cc 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -5041,18 +5041,14 @@ void intel_finish_reset(struct drm_i915_private *dev_priv) intel_pps_unlock_regs_wa(dev_priv); intel_modeset_init_hw(dev_priv); intel_init_clock_gating(dev_priv); - - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); + intel_hpd_init(dev_priv); ret = __intel_display_resume(dev, state, ctx); if (ret) drm_err(&dev_priv->drm, "Restoring old state failed with %i\n", ret); - intel_hpd_init(dev_priv); + intel_hpd_poll_disable(dev_priv); } drm_atomic_state_put(state); @@ -18262,6 +18258,7 @@ int intel_modeset_init(struct drm_i915_private *i915) /* Only enable hotplug handling once the fbdev is fully set up. */ intel_hpd_init(i915); + intel_hpd_poll_disable(i915); intel_init_ipc(i915); diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index b64b7767f467..689922480661 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1424,6 +1424,7 @@ static void vlv_display_power_well_init(struct drm_i915_private *dev_priv) return; intel_hpd_init(dev_priv); + intel_hpd_poll_disable(dev_priv); /* Re-enable the ADPA, if we have one */ for_each_intel_encoder(&dev_priv->drm, encoder) { @@ -1449,7 +1450,7 @@ static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv) /* Prevent us from re-enabling polling on accident in late suspend */ if (!dev_priv->drm.dev->power.is_suspended) - intel_hpd_poll_init(dev_priv); + intel_hpd_poll_enable(dev_priv); } static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 5c58c1ed6493..30bd4c86d146 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -584,7 +584,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, * This is a separate step from interrupt enabling to simplify the locking rules * in the driver load and resume code. * - * Also see: intel_hpd_poll_init(), which enables connector polling + * Also see: intel_hpd_poll_enable() and intel_hpd_poll_disable(). */ void intel_hpd_init(struct drm_i915_private *dev_priv) { @@ -595,9 +595,6 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) dev_priv->hotplug.stats[i].state = HPD_ENABLED; } - WRITE_ONCE(dev_priv->hotplug.poll_enabled, false); - schedule_work(&dev_priv->hotplug.poll_init_work); - /* * Interrupt setup is already guaranteed to be single-threaded, this is * just to make the assert_spin_locked checks happy. @@ -654,12 +651,12 @@ static void i915_hpd_poll_init_work(struct work_struct *work) } /** - * intel_hpd_poll_init - enables/disables polling for connectors with hpd + * intel_hpd_poll_enable - enable polling for connectors with hpd * @dev_priv: i915 device instance * - * This function enables polling for all connectors, regardless of whether or - * not they support hotplug detection. Under certain conditions HPD may not be - * functional. On most Intel GPUs, this happens when we enter runtime suspend. + * This function enables polling for all connectors which support HPD. + * Under certain conditions HPD may not be functional. On most Intel GPUs, + * this happens when we enter runtime suspend. * On Valleyview and Cherryview systems, this also happens when we shut off all * of the powerwells. * @@ -667,9 +664,9 @@ static void i915_hpd_poll_init_work(struct work_struct *work) * dev->mode_config.mutex, we do the actual hotplug enabling in a seperate * worker. * - * Also see: intel_hpd_init(), which restores hpd handling. + * Also see: intel_hpd_init() and intel_hpd_poll_disable(). */ -void intel_hpd_poll_init(struct drm_i915_private *dev_priv) +void intel_hpd_poll_enable(struct drm_i915_private *dev_priv) { WRITE_ONCE(dev_priv->hotplug.poll_enabled, true); @@ -682,6 +679,31 @@ void intel_hpd_poll_init(struct drm_i915_private *dev_priv) schedule_work(&dev_priv->hotplug.poll_init_work); } +/** + * intel_hpd_poll_disable - disable polling for connectors with hpd + * @dev_priv: i915 device instance + * + * This function disables polling for all connectors which support HPD. + * Under certain conditions HPD may not be functional. On most Intel GPUs, + * this happens when we enter runtime suspend. + * On Valleyview and Cherryview systems, this also happens when we shut off all + * of the powerwells. + * + * Since this function can get called in contexts where we're already holding + * dev->mode_config.mutex, we do the actual hotplug enabling in a seperate + * worker. + * + * Also used during driver init to initialize connector->polled + * appropriately for all connectors. + * + * Also see: intel_hpd_init() and intel_hpd_poll_enable(). + */ +void intel_hpd_poll_disable(struct drm_i915_private *dev_priv) +{ + WRITE_ONCE(dev_priv->hotplug.poll_enabled, false); + schedule_work(&dev_priv->hotplug.poll_init_work); +} + void intel_hpd_init_work(struct drm_i915_private *dev_priv) { INIT_DELAYED_WORK(&dev_priv->hotplug.hotplug_work, diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index a704d7c94d16..b87e95d606e6 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -14,7 +14,8 @@ struct intel_digital_port; struct intel_encoder; enum port; -void intel_hpd_poll_init(struct drm_i915_private *dev_priv); +void intel_hpd_poll_enable(struct drm_i915_private *dev_priv); +void intel_hpd_poll_disable(struct drm_i915_private *dev_priv); enum intel_hotplug_state intel_encoder_hotplug(struct intel_encoder *encoder, struct intel_connector *connector); void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2641d7e16b5b..ad0dcaacc1a2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1255,26 +1255,15 @@ static int i915_drm_resume(struct drm_device *dev) intel_modeset_init_hw(dev_priv); intel_init_clock_gating(dev_priv); + intel_hpd_init(dev_priv); - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev_priv); - spin_unlock_irq(&dev_priv->irq_lock); - + /* MST sideband requires HPD interrupts enabled */ intel_dp_mst_resume(dev_priv); - intel_display_resume(dev); + intel_hpd_poll_disable(dev_priv); drm_kms_helper_poll_enable(dev); - /* - * ... but also need to make sure that hotplug processing - * doesn't cause havoc. Like in the driver load code we don't - * bother with the tiny race here where we might lose hotplug - * notifications. - * */ - intel_hpd_init(dev_priv); - intel_opregion_resume(dev_priv); intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false); @@ -1586,7 +1575,7 @@ static int intel_runtime_suspend(struct device *kdev) assert_forcewakes_inactive(&dev_priv->uncore); if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) - intel_hpd_poll_init(dev_priv); + intel_hpd_poll_enable(dev_priv); drm_dbg_kms(&dev_priv->drm, "Device suspended\n"); return 0; @@ -1631,8 +1620,10 @@ static int intel_runtime_resume(struct device *kdev) * power well, so hpd is reinitialized from there. For * everyone else do it here. */ - if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) + if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) { intel_hpd_init(dev_priv); + intel_hpd_poll_disable(dev_priv); + } intel_enable_ipc(dev_priv); |