This function would call drm_modeset_lock_all, while the suspend/resume functions already have their own locking. Fix this by factoring out __intel_display_resume, and calling the atomic helpers for duplicating atomic state and disabling all crtc's during suspend. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> Fixes: e2c8b8701e2d ("drm/i915: Use atomic helpers for suspend, v2.") Cc: drm-intel-fixes@xxxxxxxxxxxxxxxxxxxxx --- drivers/gpu/drm/i915/intel_display.c | 123 +++++++++++++++++++++++------------ 1 file changed, 83 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index feb7028341b8..2f76efc86417 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3126,8 +3126,44 @@ static void intel_update_primary_planes(struct drm_device *dev) } } +static int +__intel_display_resume(struct drm_device *dev, + struct drm_atomic_state *state, + bool *setup) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + int i; + + if (!setup || !*setup) { + if (setup) + *setup = true; + + intel_modeset_setup_hw_state(dev); + i915_redisable_vga(dev); + } + + if (!state) + return 0; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + /* + * Force recalculation even if we restore + * current state. With fast modeset this may not result + * in a modeset when the state is compatible. + */ + crtc_state->mode_changed = true; + } + + return drm_atomic_commit(state); +} + void intel_prepare_reset(struct drm_device *dev) { + struct drm_atomic_state *state; + struct drm_modeset_acquire_ctx *pctx; + int ret; + /* no reset support for gen2 */ if (IS_GEN2(dev)) return; @@ -3137,16 +3173,39 @@ void intel_prepare_reset(struct drm_device *dev) return; drm_modeset_lock_all(dev); + pctx = dev->mode_config.acquire_ctx; + /* * Disabling the crtcs gracefully seems nicer. Also the * g33 docs say we should at least disable all the planes. */ - intel_display_suspend(dev); + + state = drm_atomic_helper_duplicate_state(dev, pctx); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + state = NULL; + DRM_ERROR("Duplicating state failed with %i\n", ret); + goto err; + } + + ret = drm_atomic_helper_disable_all(dev, pctx); + if (ret) { + DRM_ERROR("Suspending crtc's failed with %i\n", ret); + goto err; + } + + to_i915(dev)->modeset_restore_state = state; + return; + +err: + drm_atomic_state_free(state); } void intel_finish_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); + struct drm_atomic_state *state = dev_priv->modeset_restore_state; + int ret; /* * Flips in the rings will be nuked by the reset, @@ -3172,23 +3231,29 @@ void intel_finish_reset(struct drm_device *dev) */ intel_update_primary_planes(dev); return; - } + } else { + /* + * The display has been reset as well, + * so need a full re-initialization. + */ + intel_runtime_pm_disable_interrupts(dev_priv); + intel_runtime_pm_enable_interrupts(dev_priv); - /* - * The display has been reset as well, - * so need a full re-initialization. - */ - intel_runtime_pm_disable_interrupts(dev_priv); - intel_runtime_pm_enable_interrupts(dev_priv); + intel_modeset_init_hw(dev); - intel_modeset_init_hw(dev); + spin_lock_irq(&dev_priv->irq_lock); + if (dev_priv->display.hpd_irq_setup) + dev_priv->display.hpd_irq_setup(dev); + spin_unlock_irq(&dev_priv->irq_lock); + } - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hpd_irq_setup) - dev_priv->display.hpd_irq_setup(dev); - spin_unlock_irq(&dev_priv->irq_lock); + dev_priv->modeset_restore_state = NULL; + if (state) + state->acquire_ctx = dev->mode_config.acquire_ctx; - intel_display_resume(dev); + ret = __intel_display_resume(dev, state, NULL); + if (ret) + DRM_ERROR("Restoring old state failed with %i\n", ret); intel_hpd_init(dev_priv); @@ -15885,6 +15950,8 @@ void intel_display_resume(struct drm_device *dev) bool setup = false; dev_priv->modeset_restore_state = NULL; + if (state) + state->acquire_ctx = &ctx; /* * This is a cludge because with real atomic modeset mode_config.mutex @@ -15897,32 +15964,8 @@ void intel_display_resume(struct drm_device *dev) retry: ret = drm_modeset_lock_all_ctx(dev, &ctx); - - if (ret == 0 && !setup) { - setup = true; - - intel_modeset_setup_hw_state(dev); - i915_redisable_vga(dev); - } - - if (ret == 0 && state) { - struct drm_crtc_state *crtc_state; - struct drm_crtc *crtc; - int i; - - state->acquire_ctx = &ctx; - - for_each_crtc_in_state(state, crtc, crtc_state, i) { - /* - * Force recalculation even if we restore - * current state. With fast modeset this may not result - * in a modeset when the state is compatible. - */ - crtc_state->mode_changed = true; - } - - ret = drm_atomic_commit(state); - } + if (!ret) + ret = __intel_display_resume(dev, state, &setup); if (ret == -EDEADLK) { drm_modeset_backoff(&ctx); -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx