From 41f85557a939d8037dc5e509e39316bf624fd186 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 24 Apr 2020 18:06:16 +0300 Subject: [PATCH xserver 1/2] modesetting: check the kms state on EnterVT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Normally, we would receive a uevent coming from Linux's DRM subsystem, which would trigger the check for disappearing/appearing resources. However, this event is not received when X is not master (another VT is selected), and so the userspace / desktop environment would not be notified about the changes that happened while X wasn't master. To fix the issue, this patch forces a refresh on EnterVT by splitting the kms-checking code from the uevent handling into its own (exported) function called drmmode_update_kms_state. This function is then called from both the uevent-handling function, and on EnterVT right before restoring the modes. Signed-off-by: Martin Peres Reviewed-by: Daniel Vetter Acked-by: Kishore Kadiyala Tested-by: Kishore Kadiyala Signed-off-by: Michel Dänzer --- hw/xfree86/drivers/modesetting/driver.c | 2 ++ .../drivers/modesetting/drmmode_display.c | 34 ++++++++++++------- .../drivers/modesetting/drmmode_display.h | 1 + 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 2aaea5f7d..a4d486a67 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1820,6 +1820,8 @@ EnterVT(ScrnInfoPtr pScrn) SetMaster(pScrn); + drmmode_update_kms_state(&ms->drmmode); + if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE)) return FALSE; diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 9dd8c5573..646bacecb 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -3607,30 +3607,19 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn) return TRUE; } -#ifdef CONFIG_UDEV_KMS - #define DRM_MODE_LINK_STATUS_GOOD 0 #define DRM_MODE_LINK_STATUS_BAD 1 -static void -drmmode_handle_uevents(int fd, void *closure) +void +drmmode_update_kms_state(drmmode_ptr drmmode) { - drmmode_ptr drmmode = closure; ScrnInfoPtr scrn = drmmode->scrn; - struct udev_device *dev; drmModeResPtr mode_res; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int i, j; Bool found = FALSE; Bool changed = FALSE; - while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) { - udev_device_unref(dev); - found = TRUE; - } - if (!found) - return; - /* Try to re-set the mode on all the connectors with a BAD link-state: * This may happen if a link degrades and a new modeset is necessary, using * different link-training parameters. If the kernel found that the current @@ -3745,6 +3734,25 @@ out: #undef DRM_MODE_LINK_STATUS_BAD #undef DRM_MODE_LINK_STATUS_GOOD +#ifdef CONFIG_UDEV_KMS + +static void +drmmode_handle_uevents(int fd, void *closure) +{ + drmmode_ptr drmmode = closure; + struct udev_device *dev; + Bool found = FALSE; + + while ((dev = udev_monitor_receive_device(drmmode->uevent_monitor))) { + udev_device_unref(dev); + found = TRUE; + } + if (!found) + return; + + drmmode_update_kms_state(drmmode); +} + #endif void diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 4142607fb..6ef8ab9e4 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -281,6 +281,7 @@ 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_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); +extern void drmmode_update_kms_state(drmmode_ptr drmmode); extern void drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); -- 2.28.0