Skip to content

Commit

Permalink
drm/i915/gen9+: Set same power state before hibernation image save/re…
Browse files Browse the repository at this point in the history
…store

Atm, on GEN9 big core platforms before saving the hibernation image we
uninitialize the display, disabling power wells manually, while before
restoring the image we keep things powered (letting HW/DMC power down
things as needed). The state mismatch will trigger the following error:

DC state mismatch (0x0 -> 0x2)

While the restore handler knows how to initialize the display from an
unknown state (due to a different loader kernel or not having i915
loaded in the loader kernel) we should still use the same state for
consistency before image saving and restoring. Do this by uniniting the
display before restoring the image too.

Bugzilla: https://bugs.freedesktop.org/attachment.cgi?id=133376
Reported-and-tested-by: Wang Wendy <[email protected]>
Reported-and-tested-by: Joonas Lahtinen <[email protected]>
Cc: Wang Wendy <[email protected]>
Cc: Joonas Lahtinen <[email protected]>
Cc: Rodrigo Vivi <[email protected]>
Cc: Ville Syrjala <[email protected]>
Signed-off-by: Imre Deak <[email protected]>
Reviewed-by: Ville Syrjälä <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
  • Loading branch information
ideak committed Oct 2, 2017
1 parent 097a948 commit dd9f31c
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1580,7 +1580,7 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation)

intel_display_set_init_power(dev_priv, false);

fw_csr = !IS_GEN9_LP(dev_priv) &&
fw_csr = !IS_GEN9_LP(dev_priv) && !hibernation &&
suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
/*
* In case of firmware assisted context save/restore don't manually
Expand Down Expand Up @@ -2070,11 +2070,14 @@ static int i915_pm_resume(struct device *kdev)
/* freeze: before creating the hibernation_image */
static int i915_pm_freeze(struct device *kdev)
{
struct drm_device *dev = &kdev_to_i915(kdev)->drm;
int ret;

ret = i915_pm_suspend(kdev);
if (ret)
return ret;
if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) {
ret = i915_drm_suspend(dev);
if (ret)
return ret;
}

ret = i915_gem_freeze(kdev_to_i915(kdev));
if (ret)
Expand All @@ -2085,11 +2088,14 @@ static int i915_pm_freeze(struct device *kdev)

static int i915_pm_freeze_late(struct device *kdev)
{
struct drm_device *dev = &kdev_to_i915(kdev)->drm;
int ret;

ret = i915_pm_suspend_late(kdev);
if (ret)
return ret;
if (dev->switch_power_state != DRM_SWITCH_POWER_OFF) {
ret = i915_drm_suspend_late(dev, true);
if (ret)
return ret;
}

ret = i915_gem_freeze_late(kdev_to_i915(kdev));
if (ret)
Expand Down

0 comments on commit dd9f31c

Please sign in to comment.