diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index cf9d3ca12bb855148342e690280775187b067ccd..6549ef8e167d3b7ee5b5a87e857a2fac11feb754 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -712,7 +712,7 @@ msBlockHandler_oneshot(ScreenPtr pScreen, void *pTimeout) msBlockHandler(pScreen, pTimeout); - drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE); + drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE, FALSE); } Bool @@ -1530,7 +1530,7 @@ CreateScreenResources(ScreenPtr pScreen) ret = pScreen->CreateScreenResources(pScreen); pScreen->CreateScreenResources = CreateScreenResources; - if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, pScrn->is_gpu)) + if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, pScrn->is_gpu, FALSE)) return FALSE; if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode)) @@ -2016,8 +2016,23 @@ EnterVT(ScrnInfoPtr pScrn) drmmode_update_kms_state(&ms->drmmode); - if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE)) - return FALSE; + /* allow not all modes to be set successfully since some events might have + * happened while not being master that could prevent the previous + * configuration from being re-applied. + */ + if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE, TRUE)) { + xf86DisableUnusedFunctions(pScrn); + + /* TODO: check that at least one screen is on, to allow the user to fix + * their setup if all modeset failed... + */ + + /* Tell the desktop environment that something changed, so that they + * can hopefully correct the situation + */ + RRSetChanged(xf86ScrnToScreen(pScrn)); + RRTellChanged(xf86ScrnToScreen(pScrn)); + } return TRUE; } diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index f4a174e76d4dcae16c335239fb8145c9bc338ef5..d74f62ab68959fcdaa00204d95a74b8536cd1806 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -3571,9 +3571,11 @@ drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y) } Bool -drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw) +drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw, + Bool ign_err) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + Bool success = TRUE; int c; for (c = 0; c < config->num_crtc; c++) { @@ -3621,8 +3623,17 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw) if (set_hw) { if (!crtc->funcs-> set_mode_major(crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) - return FALSE; + crtc->desiredX, crtc->desiredY)) { + if (!ign_err) + return FALSE; + else { + success = FALSE; + crtc->enabled = FALSE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Failed to set the desired mode on connector %s\n", + output->name); + } + } } else { crtc->mode = crtc->desiredMode; crtc->rotation = crtc->desiredRotation; @@ -3636,7 +3647,7 @@ drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw) /* Validate leases on VT re-entry */ drmmode_validate_leases(pScrn); - return TRUE; + return success; } static void diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 205d1011f07cba100e7d335d65065737db56e7c6..ce85546bf1fbe8164c6193c20553de1b21573702 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -280,7 +280,8 @@ void drmmode_DisableSharedPixmapFlipping(xf86CrtcPtr crtc, drmmode_ptr drmmode); extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp); extern Bool drmmode_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode); void drmmode_adjust_frame(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int x, int y); -extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw); +extern Bool drmmode_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, + Bool set_hw, Bool ign_err); extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); extern void drmmode_update_kms_state(drmmode_ptr drmmode);