|
|
2ae2ca |
From 924083938c8f209d8f6ff472caf8692a644f7e78 Mon Sep 17 00:00:00 2001
|
|
|
2ae2ca |
From: Lyude <lyude@redhat.com>
|
|
|
2ae2ca |
Date: Fri, 3 Mar 2017 18:27:42 -0500
|
|
|
2ae2ca |
Subject: [PATCH] Consider CRTCs disabled when DPMS is off
|
|
|
2ae2ca |
|
|
|
2ae2ca |
It turns out there's a difference in X between a CRTC being "disabled"
|
|
|
2ae2ca |
and simply having it's DPMS turned off. This is problematic though,
|
|
|
2ae2ca |
because if DPMS is turned off you can't really use the CRTC as a normal
|
|
|
2ae2ca |
CRTC anyway since page flipping and vblanks will be non-functional. As a
|
|
|
2ae2ca |
result, we've been considering DPMS-on CRTCs as enabled and attempt to
|
|
|
2ae2ca |
perform pageflips, vblank waits, etc. on them which inevitably fails. and
|
|
|
2ae2ca |
usually breaks the display the first time any of the CRTCs have their
|
|
|
2ae2ca |
DPMS turned on.
|
|
|
2ae2ca |
|
|
|
2ae2ca |
This was a problem that didn't really show itself until kernel 4.10 when
|
|
|
2ae2ca |
atomic modesetting was added which caused nouveau to stop trying to
|
|
|
2ae2ca |
fulfill pageflips and vblank waits on disabled CRTCs. I'm not sure how
|
|
|
2ae2ca |
pageflipping disabled CRTCs ever worked in the first place, but since
|
|
|
2ae2ca |
not doing so is the proper behavior anyway I haven't investigated any
|
|
|
2ae2ca |
further.
|
|
|
2ae2ca |
|
|
|
2ae2ca |
So, copy the ms_crtc_on() function from the modesetting driver and add
|
|
|
2ae2ca |
it here as drmmode_crtc_on(), then use that in all of the places where
|
|
|
2ae2ca |
we should be checking for both DPMS off and disabled CRTCs.
|
|
|
2ae2ca |
|
|
|
2ae2ca |
This fixes issues with the X ceasing to function (usually) after the
|
|
|
2ae2ca |
first time a CRTC has it's DPMS turned on. Reproduction recipe:
|
|
|
2ae2ca |
|
|
|
2ae2ca |
- Load up gnome-shell on a machine
|
|
|
2ae2ca |
- Wait for the display to timeout from inactivity and turn itself off
|
|
|
2ae2ca |
- Shake the cursor or press something on the keyboard. Chances are the
|
|
|
2ae2ca |
monitor will come back on, but the display remains black until the
|
|
|
2ae2ca |
next time the X server is restarted.
|
|
|
2ae2ca |
|
|
|
2ae2ca |
Signed-off-by: Lyude <lyude@redhat.com>
|
|
|
2ae2ca |
Reviewed-by: Adam Jackson <ajax@redhat.com>
|
|
|
2ae2ca |
---
|
|
|
2ae2ca |
src/drmmode_display.c | 14 ++++++++++++--
|
|
|
2ae2ca |
src/nouveau_dri2.c | 14 +++++++++-----
|
|
|
2ae2ca |
src/nouveau_present.c | 6 +++---
|
|
|
2ae2ca |
src/nouveau_xv.c | 2 +-
|
|
|
2ae2ca |
src/nv_proto.h | 1 +
|
|
|
2ae2ca |
5 files changed, 26 insertions(+), 11 deletions(-)
|
|
|
2ae2ca |
|
|
|
2ae2ca |
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
|
|
|
2ae2ca |
index b6c9bb9..dd9fa27 100644
|
|
|
2ae2ca |
--- a/src/drmmode_display.c
|
|
|
2ae2ca |
+++ b/src/drmmode_display.c
|
|
|
2ae2ca |
@@ -65,6 +65,7 @@ typedef struct {
|
|
|
2ae2ca |
uint32_t rotate_fb_id;
|
|
|
2ae2ca |
Bool cursor_visible;
|
|
|
2ae2ca |
int scanout_pixmap_x;
|
|
|
2ae2ca |
+ int dpms_mode;
|
|
|
2ae2ca |
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
typedef struct {
|
|
|
2ae2ca |
@@ -114,6 +115,14 @@ drmmode_crtc(xf86CrtcPtr crtc)
|
|
|
2ae2ca |
return drmmode_crtc->mode_crtc->crtc_id;
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
+Bool
|
|
|
2ae2ca |
+drmmode_crtc_on(xf86CrtcPtr crtc)
|
|
|
2ae2ca |
+{
|
|
|
2ae2ca |
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
|
|
2ae2ca |
+
|
|
|
2ae2ca |
+ return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
|
|
|
2ae2ca |
+}
|
|
|
2ae2ca |
+
|
|
|
2ae2ca |
int
|
|
|
2ae2ca |
drmmode_head(xf86CrtcPtr crtc)
|
|
|
2ae2ca |
{
|
|
|
2ae2ca |
@@ -313,9 +322,10 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn, drmModeModeInfo *kmode,
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
static void
|
|
|
2ae2ca |
-drmmode_crtc_dpms(xf86CrtcPtr drmmode_crtc, int mode)
|
|
|
2ae2ca |
+drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
|
|
|
2ae2ca |
{
|
|
|
2ae2ca |
-
|
|
|
2ae2ca |
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
|
|
2ae2ca |
+ drmmode_crtc->dpms_mode = mode;
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
void
|
|
|
2ae2ca |
diff --git a/src/nouveau_dri2.c b/src/nouveau_dri2.c
|
|
|
2ae2ca |
index 81ee9be..cbb7b2a 100644
|
|
|
2ae2ca |
--- a/src/nouveau_dri2.c
|
|
|
2ae2ca |
+++ b/src/nouveau_dri2.c
|
|
|
2ae2ca |
@@ -279,23 +279,27 @@ can_exchange(DrawablePtr draw, PixmapPtr dst_pix, PixmapPtr src_pix)
|
|
|
2ae2ca |
ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
|
|
|
2ae2ca |
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
|
|
|
2ae2ca |
NVPtr pNv = NVPTR(scrn);
|
|
|
2ae2ca |
- int i;
|
|
|
2ae2ca |
+ int i, active_crtc_count = 0;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
if (!xf86_config->num_crtc)
|
|
|
2ae2ca |
return FALSE;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
for (i = 0; i < xf86_config->num_crtc; i++) {
|
|
|
2ae2ca |
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
|
|
2ae2ca |
- if (crtc->enabled && crtc->rotatedData)
|
|
|
2ae2ca |
- return FALSE;
|
|
|
2ae2ca |
+ if (drmmode_crtc_on(crtc)) {
|
|
|
2ae2ca |
+ if (crtc->rotatedData)
|
|
|
2ae2ca |
+ return FALSE;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
+ active_crtc_count++;
|
|
|
2ae2ca |
+ }
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
return ((DRI2CanFlip(draw) && pNv->has_pageflip)) &&
|
|
|
2ae2ca |
dst_pix->drawable.width == src_pix->drawable.width &&
|
|
|
2ae2ca |
dst_pix->drawable.height == src_pix->drawable.height &&
|
|
|
2ae2ca |
dst_pix->drawable.bitsPerPixel == src_pix->drawable.bitsPerPixel &&
|
|
|
2ae2ca |
- dst_pix->devKind == src_pix->devKind;
|
|
|
2ae2ca |
+ dst_pix->devKind == src_pix->devKind &&
|
|
|
2ae2ca |
+ active_crtc_count;
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
static Bool
|
|
|
2ae2ca |
@@ -475,7 +479,7 @@ dri2_page_flip(DrawablePtr draw, PixmapPtr back, void *priv,
|
|
|
2ae2ca |
int head = drmmode_crtc(config->crtc[i]);
|
|
|
2ae2ca |
void *token;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
- if (!config->crtc[i]->enabled)
|
|
|
2ae2ca |
+ if (!drmmode_crtc_on(config->crtc[i]))
|
|
|
2ae2ca |
continue;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
flipdata->flip_count++;
|
|
|
2ae2ca |
diff --git a/src/nouveau_present.c b/src/nouveau_present.c
|
|
|
2ae2ca |
index 482ac6e..ebd5fcf 100644
|
|
|
2ae2ca |
--- a/src/nouveau_present.c
|
|
|
2ae2ca |
+++ b/src/nouveau_present.c
|
|
|
2ae2ca |
@@ -152,7 +152,7 @@ nouveau_present_flip_check(RRCrtcPtr rrcrtc, WindowPtr window,
|
|
|
2ae2ca |
ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
|
|
|
2ae2ca |
xf86CrtcPtr crtc = rrcrtc->devPrivate;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
- if (!scrn->vtSema || !crtc->enabled)
|
|
|
2ae2ca |
+ if (!scrn->vtSema || !drmmode_crtc_on(crtc))
|
|
|
2ae2ca |
return FALSE;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
return TRUE;
|
|
|
2ae2ca |
@@ -199,7 +199,7 @@ nouveau_present_flip_exec(ScrnInfoPtr scrn, uint64_t event_id, int sync,
|
|
|
2ae2ca |
flip->msc = target_msc;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
for (i = 0; i < config->num_crtc; i++) {
|
|
|
2ae2ca |
- if (config->crtc[i]->enabled)
|
|
|
2ae2ca |
+ if (drmmode_crtc_on(config->crtc[i]))
|
|
|
2ae2ca |
last = i;
|
|
|
2ae2ca |
}
|
|
|
2ae2ca |
|
|
|
2ae2ca |
@@ -208,7 +208,7 @@ nouveau_present_flip_exec(ScrnInfoPtr scrn, uint64_t event_id, int sync,
|
|
|
2ae2ca |
int crtc = drmmode_crtc(config->crtc[i]);
|
|
|
2ae2ca |
void *user = NULL;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
- if (!config->crtc[i]->enabled)
|
|
|
2ae2ca |
+ if (!drmmode_crtc_on(config->crtc[i]))
|
|
|
2ae2ca |
continue;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
if (token && ((crtc == sync) || (i == last))) {
|
|
|
2ae2ca |
diff --git a/src/nouveau_xv.c b/src/nouveau_xv.c
|
|
|
2ae2ca |
index 716b18d..4b939f7 100644
|
|
|
2ae2ca |
--- a/src/nouveau_xv.c
|
|
|
2ae2ca |
+++ b/src/nouveau_xv.c
|
|
|
2ae2ca |
@@ -299,7 +299,7 @@ nv_window_belongs_to_crtc(ScrnInfoPtr pScrn, int x, int y, int w, int h)
|
|
|
2ae2ca |
for (i = 0; i < xf86_config->num_crtc; i++) {
|
|
|
2ae2ca |
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
|
|
2ae2ca |
|
|
|
2ae2ca |
- if (!crtc->enabled)
|
|
|
2ae2ca |
+ if (!drmmode_crtc_on(crtc))
|
|
|
2ae2ca |
continue;
|
|
|
2ae2ca |
|
|
|
2ae2ca |
if ((x < (crtc->x + crtc->mode.HDisplay)) &&
|
|
|
2ae2ca |
diff --git a/src/nv_proto.h b/src/nv_proto.h
|
|
|
2ae2ca |
index 122ede5..4a57406 100644
|
|
|
2ae2ca |
--- a/src/nv_proto.h
|
|
|
2ae2ca |
+++ b/src/nv_proto.h
|
|
|
2ae2ca |
@@ -13,6 +13,7 @@ void drmmode_screen_init(ScreenPtr pScreen);
|
|
|
2ae2ca |
void drmmode_screen_fini(ScreenPtr pScreen);
|
|
|
2ae2ca |
|
|
|
2ae2ca |
int drmmode_crtc(xf86CrtcPtr crtc);
|
|
|
2ae2ca |
+Bool drmmode_crtc_on(xf86CrtcPtr crtc);
|
|
|
2ae2ca |
int drmmode_head(xf86CrtcPtr crtc);
|
|
|
2ae2ca |
void drmmode_swap(ScrnInfoPtr, uint32_t, uint32_t *);
|
|
|
2ae2ca |
|
|
|
2ae2ca |
--
|
|
|
2ae2ca |
2.9.3
|
|
|
2ae2ca |
|