diff --git a/src/sna/sna.h b/src/sna/sna.h index 2f14fad5..17cae7e2 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -321,7 +321,6 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); bool sna_mode_fake_init(struct sna *sna); void sna_mode_adjust_frame(struct sna *sna, int x, int y); extern void sna_mode_update(struct sna *sna); -extern void sna_mode_disable_unused(struct sna *sna); extern void sna_mode_wakeup(struct sna *sna); extern void sna_mode_redisplay(struct sna *sna); extern void sna_mode_close(struct sna *sna); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 39d7db58..eaf54e98 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -726,24 +726,6 @@ mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode) kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0; } -static bool sna_crtc_is_bound(struct sna *sna, xf86CrtcPtr crtc) -{ - struct sna_crtc *sna_crtc = to_sna_crtc(crtc); - struct drm_mode_crtc mode; - - if (!sna_crtc->bo) - return false; - - VG_CLEAR(mode); - mode.crtc_id = sna_crtc->id; - if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) - return false; - - DBG(("%s: crtc=%d, mode valid?=%d, fb attached?=%d\n", __FUNCTION__, - mode.crtc_id, mode.mode_valid, fb_id(sna_crtc->bo) == mode.fb_id)); - return mode.mode_valid && fb_id(sna_crtc->bo) == mode.fb_id; -} - static void sna_crtc_force_outputs_on(xf86CrtcPtr crtc) { @@ -973,22 +955,6 @@ static void update_flush_interval(struct sna *sna) max_vrefresh, sna->vblank_interval)); } -void sna_mode_disable_unused(struct sna *sna) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); - int i; - - DBG(("%s\n", __FUNCTION__)); - - /* Force consistency between kernel and ourselves */ - for (i = 0; i < xf86_config->num_crtc; i++) { - if (!xf86_config->crtc[i]->enabled) - sna_crtc_disable(xf86_config->crtc[i]); - } - - sna_mode_update(sna); -} - static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna, const struct drm_mode_fb_cmd *fbcon) { @@ -1507,6 +1473,9 @@ sna_crtc_dpms(xf86CrtcPtr crtc, int mode) DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n", __FUNCTION__, priv->pipe, mode, mode == DPMSModeOn)); + if (priv->dpms_mode == mode) + return; + if (mode == DPMSModeOn) { if (priv->bo == NULL && !sna_crtc_set_mode_major(crtc, @@ -3157,7 +3126,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) mode->kmode = drmModeGetResources(sna->kgem.fd); if (mode->kmode) { xf86CrtcConfigInit(scrn, &sna_mode_funcs); - XF86_CRTC_CONFIG_PTR(sna->scrn)->xf86_crtc_notify = sna_crtc_config_notify; + XF86_CRTC_CONFIG_PTR(scrn)->xf86_crtc_notify = sna_crtc_config_notify; for (i = 0; i < mode->kmode->count_crtcs; i++) if (!sna_crtc_init(scrn, mode, i)) @@ -3570,13 +3539,30 @@ void sna_mode_update(struct sna *sna) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(sna->scrn); int i; - /* Validate CRTC attachments */ + /* Validate CRTC attachments and force consistency upon the kernel */ for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; - if (to_sna_crtc(crtc) == NULL) + struct sna_crtc *sna_crtc = to_sna_crtc(crtc); + struct drm_mode_crtc mode; + uint32_t expected; + + if (sna_crtc == NULL) continue; - if (!crtc->active || !sna_crtc_is_bound(sna, crtc)) + assert(sna_crtc->bo == NULL || crtc->active); + expected = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0; + + VG_CLEAR(mode); + mode.crtc_id = sna_crtc->id; + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode)) + continue; + + DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n", + __FUNCTION__, + mode.crtc_id, mode.mode_valid, + mode.fb_id, fb_id, expected)); + + if (mode.fb_id != expected) sna_crtc_disable(crtc); } diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index ca41e7e7..503d1e51 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -206,7 +206,7 @@ static Bool sna_become_master(struct sna *sna) sna_set_fallback_mode(scrn); } - sna_mode_disable_unused(sna); + sna_mode_update(sna); return TRUE; } @@ -998,7 +998,6 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL) return FALSE; if (sna->flags & SNA_REPROBE) { - sna_mode_update(sna); RRGetInfo(xf86ScrnToScreen(scrn), TRUE); sna->flags &= ~SNA_REPROBE; }