diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 146e54ef672e..f1dbc7852414 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1826,8 +1826,11 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, asyh->clr.mask, asyh->set.mask); - if (old_crtc_state->active && !new_crtc_state->active) + + if (old_crtc_state->active && !new_crtc_state->active) { + pm_runtime_put_noidle(dev->dev); drm_crtc_vblank_off(crtc); + } if (asyh->clr.mask) { nv50_head_flush_clr(head, asyh, atom->flush_disable); @@ -1913,8 +1916,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) } if (new_crtc_state->active) { - if (!old_crtc_state->active) + if (!old_crtc_state->active) { drm_crtc_vblank_on(crtc); + pm_runtime_get_noresume(dev->dev); + } if (new_crtc_state->event) drm_crtc_vblank_get(crtc); } @@ -1979,6 +1984,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_helper_commit_cleanup_done(state); drm_atomic_state_put(state); + + /* Drop the RPM ref we got from nv50_disp_atomic_commit() */ + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); } static void @@ -1993,11 +2002,8 @@ static int nv50_disp_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock) { - struct nouveau_drm *drm = nouveau_drm(dev); struct drm_plane_state *new_plane_state; struct drm_plane *plane; - struct drm_crtc *crtc; - bool active = false; int ret, i; ret = pm_runtime_get_sync(dev->dev); @@ -2034,27 +2040,17 @@ nv50_disp_atomic_commit(struct drm_device *dev, drm_atomic_state_get(state); + /* + * Grab another RPM ref for the commit tail, which will release the + * ref when it's finished + */ + pm_runtime_get_noresume(dev->dev); + if (nonblock) queue_work(system_unbound_wq, &state->commit_work); else nv50_disp_atomic_commit_tail(state); - drm_for_each_crtc(crtc, dev) { - if (crtc->state->active) { - if (!drm->have_disp_power_ref) { - drm->have_disp_power_ref = true; - return 0; - } - active = true; - break; - } - } - - if (!active && drm->have_disp_power_ref) { - pm_runtime_put_autosuspend(dev->dev); - drm->have_disp_power_ref = false; - } - err_cleanup: if (ret) drm_atomic_helper_cleanup_planes(dev, state); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index cf0d0a416af6..70f34cacc552 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -206,9 +206,6 @@ struct nouveau_drm { /* led management */ struct nouveau_led *led; - /* display power reference */ - bool have_disp_power_ref; - struct dev_pm_domain vga_pm_domain; struct nouveau_svm *svm;