modesetting: check the kms state on EnterVT

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 <martin.peres@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
Tested-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
This commit is contained in:
Martin Peres 2020-04-24 18:06:16 +03:00
parent 4c00369024
commit 293cf660c9
3 changed files with 24 additions and 13 deletions

View File

@ -2014,6 +2014,8 @@ EnterVT(ScrnInfoPtr pScrn)
SetMaster(pScrn); SetMaster(pScrn);
drmmode_update_kms_state(&ms->drmmode);
if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE)) if (!drmmode_set_desired_modes(pScrn, &ms->drmmode, TRUE))
return FALSE; return FALSE;

View File

@ -3721,30 +3721,19 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return TRUE; return TRUE;
} }
#ifdef CONFIG_UDEV_KMS
#define DRM_MODE_LINK_STATUS_GOOD 0 #define DRM_MODE_LINK_STATUS_GOOD 0
#define DRM_MODE_LINK_STATUS_BAD 1 #define DRM_MODE_LINK_STATUS_BAD 1
static void void
drmmode_handle_uevents(int fd, void *closure) drmmode_update_kms_state(drmmode_ptr drmmode)
{ {
drmmode_ptr drmmode = closure;
ScrnInfoPtr scrn = drmmode->scrn; ScrnInfoPtr scrn = drmmode->scrn;
struct udev_device *dev;
drmModeResPtr mode_res; drmModeResPtr mode_res;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i, j; int i, j;
Bool found = FALSE; Bool found = FALSE;
Bool changed = 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: /* 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 * 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 * different link-training parameters. If the kernel found that the current
@ -3859,6 +3848,25 @@ out:
#undef DRM_MODE_LINK_STATUS_BAD #undef DRM_MODE_LINK_STATUS_BAD
#undef DRM_MODE_LINK_STATUS_GOOD #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 #endif
void void

View File

@ -283,6 +283,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_set_desired_modes(ScrnInfoPtr pScrn, drmmode_ptr drmmode, Bool set_hw);
extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn); 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_init(ScrnInfoPtr scrn, drmmode_ptr drmmode);
extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode); extern void drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode);