Commit 0f9976dd authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/kms/nv04-nv4x: move resume code to dispnv04 init hook

It has no relevance to the atomic path used by newer GPUs.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f04a4186
...@@ -73,11 +73,13 @@ nv04_display_fini(struct drm_device *dev, bool suspend) ...@@ -73,11 +73,13 @@ nv04_display_fini(struct drm_device *dev, bool suspend)
} }
static int static int
nv04_display_init(struct drm_device *dev) nv04_display_init(struct drm_device *dev, bool resume, bool runtime)
{ {
struct nv04_display *disp = nv04_display(dev); struct nv04_display *disp = nv04_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *encoder; struct nouveau_encoder *encoder;
struct nouveau_crtc *crtc; struct drm_crtc *crtc;
int ret;
/* meh.. modeset apparently doesn't setup all the regs and depends /* meh.. modeset apparently doesn't setup all the regs and depends
* on pre-existing state, for now load the state of the card *before* * on pre-existing state, for now load the state of the card *before*
...@@ -87,14 +89,74 @@ nv04_display_init(struct drm_device *dev) ...@@ -87,14 +89,74 @@ nv04_display_init(struct drm_device *dev)
* save/restore "pre-load" state, but more general so we can save * save/restore "pre-load" state, but more general so we can save
* on suspend too. * on suspend too.
*/ */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
crtc->save(&crtc->base); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->save(&nv_crtc->base);
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head) list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
encoder->enc_save(&encoder->base.base); encoder->enc_save(&encoder->base.base);
/* Enable flip completion events. */ /* Enable flip completion events. */
nvif_notify_get(&disp->flip); nvif_notify_get(&disp->flip);
if (!resume)
return 0;
/* Re-pin FB/cursors. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true);
if (ret)
NV_ERROR(drm, "Could not pin framebuffer\n");
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
if (!ret && nv_crtc->cursor.set_offset)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
NV_ERROR(drm, "Could not pin/map cursor.\n");
}
/* Force CLUT to get re-loaded during modeset. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->lut.depth = 0;
}
/* This should ensure we don't hit a locking problem when someone
* wakes us up via a connector. We should never go into suspend
* while the display is on anyways.
*/
if (runtime)
return 0;
/* Restore mode. */
drm_helper_resume_force_mode(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
if (nv_crtc->cursor.set_offset)
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y);
}
return 0; return 0;
} }
......
...@@ -2244,7 +2244,7 @@ nv50_display_fini(struct drm_device *dev, bool suspend) ...@@ -2244,7 +2244,7 @@ nv50_display_fini(struct drm_device *dev, bool suspend)
} }
static int static int
nv50_display_init(struct drm_device *dev) nv50_display_init(struct drm_device *dev, bool resume, bool runtime)
{ {
struct nv50_core *core = nv50_disp(dev)->core; struct nv50_core *core = nv50_disp(dev)->core;
struct drm_encoder *encoder; struct drm_encoder *encoder;
......
...@@ -407,14 +407,14 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, ...@@ -407,14 +407,14 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val,
#endif #endif
int int
nouveau_display_init(struct drm_device *dev) nouveau_display_init(struct drm_device *dev, bool resume, bool runtime)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter; struct drm_connector_list_iter conn_iter;
int ret; int ret;
ret = disp->init(dev); ret = disp->init(dev, resume, runtime);
if (ret) if (ret)
return ret; return ret;
...@@ -634,73 +634,16 @@ void ...@@ -634,73 +634,16 @@ void
nouveau_display_resume(struct drm_device *dev, bool runtime) nouveau_display_resume(struct drm_device *dev, bool runtime)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_crtc *crtc; nouveau_display_init(dev, true, runtime);
int ret;
if (drm_drv_uses_atomic_modeset(dev)) { if (drm_drv_uses_atomic_modeset(dev)) {
nouveau_display_init(dev);
if (disp->suspend) { if (disp->suspend) {
drm_atomic_helper_resume(dev, disp->suspend); drm_atomic_helper_resume(dev, disp->suspend);
disp->suspend = NULL; disp->suspend = NULL;
} }
return; return;
} }
/* re-pin fb/cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true);
if (ret)
NV_ERROR(drm, "Could not pin framebuffer\n");
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
if (!ret && nv_crtc->cursor.set_offset)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
NV_ERROR(drm, "Could not pin/map cursor.\n");
}
nouveau_display_init(dev);
/* Force CLUT to get re-loaded during modeset */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->lut.depth = 0;
}
/* This should ensure we don't hit a locking problem when someone
* wakes us up via a connector. We should never go into suspend
* while the display is on anyways.
*/
if (runtime)
return;
drm_helper_resume_force_mode(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
if (nv_crtc->cursor.set_offset)
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y);
}
} }
int int
......
...@@ -28,7 +28,7 @@ int nouveau_framebuffer_new(struct drm_device *, ...@@ -28,7 +28,7 @@ int nouveau_framebuffer_new(struct drm_device *,
struct nouveau_display { struct nouveau_display {
void *priv; void *priv;
void (*dtor)(struct drm_device *); void (*dtor)(struct drm_device *);
int (*init)(struct drm_device *); int (*init)(struct drm_device *, bool resume, bool runtime);
void (*fini)(struct drm_device *, bool suspend); void (*fini)(struct drm_device *, bool suspend);
struct nvif_disp disp; struct nvif_disp disp;
...@@ -53,7 +53,7 @@ nouveau_display(struct drm_device *dev) ...@@ -53,7 +53,7 @@ nouveau_display(struct drm_device *dev)
int nouveau_display_create(struct drm_device *dev); int nouveau_display_create(struct drm_device *dev);
void nouveau_display_destroy(struct drm_device *dev); void nouveau_display_destroy(struct drm_device *dev);
int nouveau_display_init(struct drm_device *dev); int nouveau_display_init(struct drm_device *dev, bool resume, bool runtime);
void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime); void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime);
int nouveau_display_suspend(struct drm_device *dev, bool runtime); int nouveau_display_suspend(struct drm_device *dev, bool runtime);
void nouveau_display_resume(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime);
......
...@@ -498,7 +498,7 @@ nouveau_drm_device_init(struct drm_device *dev) ...@@ -498,7 +498,7 @@ nouveau_drm_device_init(struct drm_device *dev)
goto fail_dispctor; goto fail_dispctor;
if (dev->mode_config.num_crtc) { if (dev->mode_config.num_crtc) {
ret = nouveau_display_init(dev); ret = nouveau_display_init(dev, false, false);
if (ret) if (ret)
goto fail_dispinit; goto fail_dispinit;
} }
......
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