Commit 028791bb authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/kms: restore fbcon after display has been resumed

Under some complicated circumstances (boot, suspend, resume, attach
second display, suspend, resume, suspend, detach second display,
resume, suspend, attach second display, resume), the fb_set_suspend()
call can somehow result in a modeset being attempted before we're
ready for it and things blow up in fun ways.

Running display init first fixes the issue.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 276e526c
...@@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev) ...@@ -652,12 +652,12 @@ int nouveau_pmops_resume(struct device *dev)
ret = nouveau_do_resume(drm_dev); ret = nouveau_do_resume(drm_dev);
if (ret) if (ret)
return ret; return ret;
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 0);
nouveau_fbcon_zfill_all(drm_dev); if (drm_dev->mode_config.num_crtc) {
if (drm_dev->mode_config.num_crtc)
nouveau_display_resume(drm_dev); nouveau_display_resume(drm_dev);
nouveau_fbcon_set_suspend(drm_dev, 0);
}
return 0; return 0;
} }
...@@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev) ...@@ -683,11 +683,12 @@ static int nouveau_pmops_thaw(struct device *dev)
ret = nouveau_do_resume(drm_dev); ret = nouveau_do_resume(drm_dev);
if (ret) if (ret)
return ret; return ret;
if (drm_dev->mode_config.num_crtc)
nouveau_fbcon_set_suspend(drm_dev, 0); if (drm_dev->mode_config.num_crtc) {
nouveau_fbcon_zfill_all(drm_dev);
if (drm_dev->mode_config.num_crtc)
nouveau_display_resume(drm_dev); nouveau_display_resume(drm_dev);
nouveau_fbcon_set_suspend(drm_dev, 0);
}
return 0; return 0;
} }
......
...@@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state) ...@@ -531,17 +531,10 @@ nouveau_fbcon_set_suspend(struct drm_device *dev, int state)
if (state == 1) if (state == 1)
nouveau_fbcon_save_disable_accel(dev); nouveau_fbcon_save_disable_accel(dev);
fb_set_suspend(drm->fbcon->helper.fbdev, state); fb_set_suspend(drm->fbcon->helper.fbdev, state);
if (state == 0) if (state == 0) {
nouveau_fbcon_restore_accel(dev); nouveau_fbcon_restore_accel(dev);
console_unlock();
}
}
void
nouveau_fbcon_zfill_all(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
if (drm->fbcon) {
nouveau_fbcon_zfill(dev, drm->fbcon); nouveau_fbcon_zfill(dev, drm->fbcon);
} }
console_unlock();
}
} }
...@@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info); ...@@ -61,7 +61,6 @@ void nouveau_fbcon_gpu_lockup(struct fb_info *info);
int nouveau_fbcon_init(struct drm_device *dev); int nouveau_fbcon_init(struct drm_device *dev);
void nouveau_fbcon_fini(struct drm_device *dev); void nouveau_fbcon_fini(struct drm_device *dev);
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state); void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
void nouveau_fbcon_zfill_all(struct drm_device *dev);
void nouveau_fbcon_save_disable_accel(struct drm_device *dev); void nouveau_fbcon_save_disable_accel(struct drm_device *dev);
void nouveau_fbcon_restore_accel(struct drm_device *dev); void nouveau_fbcon_restore_accel(struct drm_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment