161 lines
6.7 KiB
Diff
161 lines
6.7 KiB
Diff
From 287a960c316ecae5cb87c9d23dcb25810d67a0d1 Mon Sep 17 00:00:00 2001
|
|
From: Kishore Kadiyala <kishore.kadiyala@intel.com>
|
|
Date: Sat, 19 Sep 2020 01:28:14 +0530
|
|
Subject: [PATCH xserver 2/2] modesetting: keep going if a modeset fails on
|
|
EnterVT
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
There was a time when setting a mode on a CRTC would not depend on the
|
|
associated connector's state. If a mode had been set successfully once,
|
|
it would mean it would work later on.
|
|
|
|
This changed with the introduction of new connectors type that now
|
|
require a link training sequence (DP, HDMI 2.0), and that means that
|
|
some events may have happened while the X server was not master that
|
|
would then prevent the mode from successfully be restored to its
|
|
previous state.
|
|
|
|
This patch relaxes the requirement that all modes should be restored on
|
|
EnterVT, or the entire X-Server would go down by allowing modesets to
|
|
fail (with some warnings). If a modeset fails, the CRTC will be
|
|
disabled, and a RandR event will be sent for the desktop environment to
|
|
fix the situation as well as possible.
|
|
|
|
Additional patches might be needed to make sure that the user would
|
|
never be left with all screens black in some scenarios.
|
|
|
|
v2 (Martin Peres):
|
|
- whitespace fixes
|
|
- remove the uevent handling (it is done in a previous patch)
|
|
- improve the commit message
|
|
- reduce the size of the patch by not changing lines needlessly
|
|
- return FALSE if one modeset fails in ignore mode
|
|
- add comments/todos to explain why we do things
|
|
- disable the CRTCs that failed the modeset
|
|
|
|
Signed-off-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
|
|
Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
|
|
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
|
|
Tested-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
|
|
Closes: #1010
|
|
Signed-off-by: Michel Dänzer <mdaenzer@redhat.com>
|
|
---
|
|
hw/xfree86/drivers/modesetting/driver.c | 23 +++++++++++++++----
|
|
.../drivers/modesetting/drmmode_display.c | 19 +++++++++++----
|
|
.../drivers/modesetting/drmmode_display.h | 3 ++-
|
|
3 files changed, 36 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
|
|
index a4d486a67..ef4a3147d 100644
|
|
--- a/hw/xfree86/drivers/modesetting/driver.c
|
|
+++ b/hw/xfree86/drivers/modesetting/driver.c
|
|
@@ -705,7 +705,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);
|
|
}
|
|
|
|
static void
|
|
@@ -1348,7 +1348,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))
|
|
@@ -1822,8 +1822,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 646bacecb..88992f521 100644
|
|
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
|
|
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
|
|
@@ -3457,9 +3457,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++) {
|
|
@@ -3507,8 +3509,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;
|
|
@@ -3522,7 +3533,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 6ef8ab9e4..59d79e9a0 100644
|
|
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
|
|
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
|
|
@@ -278,7 +278,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);
|
|
--
|
|
2.28.0
|
|
|