summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-06-14 15:35:24 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2012-06-14 16:34:23 +0100
commitd5b273b20b7d917d08af120815c28b1618d3342c (patch)
treeda25cc5ca69e460c26091eb1e14724d9ac869032 /src
parent221534abe2dc04fae8b8fc332104bca275d4863b (diff)
sna: Explicitly disable the CRTC so that xserver/kernel agree after VT switch
References: https://bugs.freedesktop.org/show_bug.cgi?id=50772 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna.h2
-rw-r--r--src/sna/sna_display.c157
2 files changed, 55 insertions, 104 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 9453c200..634692ca 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -316,8 +316,6 @@ extern int sna_page_flip(struct sna *sna,
int ref_crtc_hw_id,
uint32_t *old_fb);
-extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap);
-
constant static inline struct sna *
to_sna(ScrnInfoPtr scrn)
{
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index a51abb50..a198b5cf 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -95,8 +95,10 @@ struct sna_output {
struct list link;
};
-static void
-sna_output_dpms(xf86OutputPtr output, int mode);
+static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
+{
+ return crtc->driver_private;
+}
#define BACKLIGHT_CLASS "/sys/class/backlight"
@@ -132,24 +134,23 @@ crtc_id(struct sna_crtc *crtc)
int sna_crtc_id(xf86CrtcPtr crtc)
{
- return crtc_id(crtc->driver_private);
+ return to_sna_crtc(crtc)->id;
}
int sna_crtc_on(xf86CrtcPtr crtc)
{
- struct sna_crtc *sna_crtc = crtc->driver_private;
- return sna_crtc->active;
+ return to_sna_crtc(crtc)->active;
}
int sna_crtc_to_pipe(xf86CrtcPtr crtc)
{
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
return sna_crtc->pipe;
}
int sna_crtc_to_plane(xf86CrtcPtr crtc)
{
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
return sna_crtc->plane;
}
@@ -399,7 +400,7 @@ bool sna_crtc_is_bound(struct sna *sna, xf86CrtcPtr crtc)
struct drm_mode_crtc mode;
VG_CLEAR(mode);
- mode.crtc_id = crtc_id(crtc->driver_private);
+ mode.crtc_id = to_sna_crtc(crtc)->id;
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
return false;
@@ -412,7 +413,7 @@ static Bool
sna_crtc_apply(xf86CrtcPtr crtc)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
struct sna_mode *mode = &sna->mode;
struct drm_mode_crtc arg;
@@ -459,10 +460,10 @@ sna_crtc_apply(xf86CrtcPtr crtc)
"switch to mode %dx%d on crtc %d (pipe %d)\n",
sna_crtc->kmode.hdisplay,
sna_crtc->kmode.vdisplay,
- crtc_id(sna_crtc), sna_crtc->pipe);
+ sna_crtc->id, sna_crtc->pipe);
DBG(("%s: applying crtc [%d] mode=%dx%d@%d, fb=%d%s update to %d outputs\n",
- __FUNCTION__, crtc_id(sna_crtc),
+ __FUNCTION__, sna_crtc->id,
sna_crtc->kmode.hdisplay,
sna_crtc->kmode.vdisplay,
sna_crtc->kmode.clock,
@@ -493,65 +494,30 @@ sna_crtc_apply(xf86CrtcPtr crtc)
}
static void
-sna_crtc_restore(ScrnInfoPtr scrn)
+sna_crtc_disable(xf86CrtcPtr crtc)
{
- struct sna *sna = to_sna(scrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- struct kgem_bo *bo;
- int i;
-
- DBG(("%s (fb_pixmap=%ld, front=%ld)\n", __FUNCTION__,
- (long)sna->mode.fb_pixmap,
- (long)sna->front->drawable.serialNumber));
-
- if (sna->mode.fb_pixmap == sna->front->drawable.serialNumber)
- return;
-
- bo = sna_pixmap_pin(sna->front);
- if (!bo)
- return;
-
- DBG(("%s: create fb %dx%d@%d/%d\n",
- __FUNCTION__,
- sna->front->drawable.width,
- sna->front->drawable.height,
- sna->front->drawable.depth,
- sna->front->drawable.bitsPerPixel));
-
- sna_mode_remove_fb(sna);
- sna->mode.fb_id = get_fb(sna, bo,
- sna->front->drawable.width,
- sna->front->drawable.height);
- if (sna->mode.fb_id == 0)
- return;
+ struct sna *sna = to_sna(crtc->scrn);
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
+ struct drm_mode_crtc arg;
- DBG(("%s: handle %d attached to fb %d\n",
- __FUNCTION__, bo->handle, sna->mode.fb_id));
+ DBG(("%s: disabling crtc [%d]\n", __FUNCTION__, sna_crtc->id));
- for (i = 0; i < xf86_config->num_crtc; i++) {
- xf86CrtcPtr crtc = xf86_config->crtc[i];
- if (crtc->enabled)
- sna_crtc_apply(crtc);
- }
- sna_mode_update(sna);
-
- kgem_bo_retire(&sna->kgem, bo);
- scrn->displayWidth = bo->pitch / sna->mode.cpp;
- sna->mode.fb_pixmap = sna->front->drawable.serialNumber;
+ VG_CLEAR(arg);
+ arg.crtc_id = sna_crtc->id;
+ arg.fb_id = 0;
+ arg.mode_valid = 0;
+ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
+ sna_crtc->active = false;
}
static void
sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
- struct sna_crtc *sna_crtc = crtc->driver_private;
-
DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
- __FUNCTION__, sna_crtc->pipe, mode, mode == DPMSModeOn));
+ __FUNCTION__, to_sna_crtc(crtc)->pipe, mode, mode == DPMSModeOn));
- if (mode != DPMSModeOff)
- sna_crtc_restore(crtc->scrn);
- else
- sna_crtc->active = false;
+ if (mode == DPMSModeOff)
+ sna_crtc_disable(crtc);
}
static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna,
@@ -604,7 +570,7 @@ void sna_copy_fbcon(struct sna *sna)
VG_CLEAR(fbcon);
fbcon.fb_id = 0;
for (i = 0; i < xf86_config->num_crtc; i++) {
- struct sna_crtc *crtc = xf86_config->crtc[i]->driver_private;
+ struct sna_crtc *crtc = to_sna_crtc(xf86_config->crtc[i]);
struct drm_mode_crtc mode;
VG_CLEAR(mode);
@@ -704,7 +670,7 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
{
ScrnInfoPtr scrn = crtc->scrn;
struct sna *sna = to_sna(scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
struct sna_mode *sna_mode = &sna->mode;
int saved_x, saved_y;
Rotation saved_rotation;
@@ -779,10 +745,10 @@ static void
sna_crtc_hide_cursor(xf86CrtcPtr crtc)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
struct drm_mode_cursor arg;
- __DBG(("%s: CRTC:%d\n", __FUNCTION__, crtc_id(sna_crtc)));
+ __DBG(("%s: CRTC:%d\n", __FUNCTION__, sna_crtc->id));
VG_CLEAR(arg);
arg.flags = DRM_MODE_CURSOR_BO;
@@ -790,17 +756,17 @@ sna_crtc_hide_cursor(xf86CrtcPtr crtc)
arg.width = arg.height = 64;
arg.handle = 0;
- drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
+ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
static void
sna_crtc_show_cursor(xf86CrtcPtr crtc)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
struct drm_mode_cursor arg;
- __DBG(("%s: CRTC:%d\n", __FUNCTION__, crtc_id(sna_crtc)));
+ __DBG(("%s: CRTC:%d\n", __FUNCTION__, sna_crtc->id));
VG_CLEAR(arg);
arg.flags = DRM_MODE_CURSOR_BO;
@@ -808,24 +774,24 @@ sna_crtc_show_cursor(xf86CrtcPtr crtc)
arg.width = arg.height = 64;
arg.handle = sna_crtc->cursor;
- drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
+ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
static void
sna_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
{
__DBG(("%s: CRTC:%d (bg=%x, fg=%x)\n", __FUNCTION__,
- crtc_id(crtc->driver_private), bg, fg));
+ to_sna_crtc(crtc)->id, bg, fg));
}
static void
sna_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
struct drm_mode_cursor arg;
- __DBG(("%s: CRTC:%d (%d, %d)\n", __FUNCTION__, crtc_id(sna_crtc), x, y));
+ __DBG(("%s: CRTC:%d (%d, %d)\n", __FUNCTION__, sna_crtc->id, x, y));
VG_CLEAR(arg);
arg.flags = DRM_MODE_CURSOR_MOVE;
@@ -834,17 +800,17 @@ sna_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
arg.y = y;
arg.handle = sna_crtc->cursor;
- drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
+ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
static void
sna_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
struct drm_i915_gem_pwrite pwrite;
- __DBG(("%s: CRTC:%d\n", __FUNCTION__, crtc_id(sna_crtc)));
+ __DBG(("%s: CRTC:%d\n", __FUNCTION__, sna_crtc->id));
VG_CLEAR(pwrite);
pwrite.handle = sna_crtc->cursor;
@@ -859,7 +825,7 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
ScrnInfoPtr scrn = crtc->scrn;
struct sna *sna = to_sna(scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
PixmapPtr shadow;
struct kgem_bo *bo;
@@ -897,7 +863,7 @@ sna_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
static void
sna_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr pixmap, void *data)
{
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
/* We may have not called shadow_create() on the data yet and
* be cleaning up a NULL shadow_pixmap.
@@ -918,9 +884,9 @@ sna_crtc_gamma_set(xf86CrtcPtr crtc,
CARD16 *red, CARD16 *green, CARD16 *blue, int size)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
- drmModeCrtcSetGamma(sna->kgem.fd, crtc_id(sna_crtc),
+ drmModeCrtcSetGamma(sna->kgem.fd, sna_crtc->id,
size, red, green, blue);
}
@@ -928,7 +894,7 @@ static void
sna_crtc_destroy(xf86CrtcPtr crtc)
{
struct sna *sna = to_sna(crtc->scrn);
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
sna_crtc_hide_cursor(crtc);
gem_close(sna->kgem.fd, sna_crtc->cursor);
@@ -1014,9 +980,12 @@ sna_crtc_init(ScrnInfoPtr scrn, struct sna_mode *mode, int num)
VG_CLEAR(get_pipe);
get_pipe.pipe = 0;
get_pipe.crtc_id = sna_crtc->id;
- drmIoctl(sna->kgem.fd,
- DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
- &get_pipe);
+ if (drmIoctl(sna->kgem.fd,
+ DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
+ &get_pipe)) {
+ free(sna_crtc);
+ return;
+ }
sna_crtc->pipe = get_pipe.pipe;
sna_crtc->plane = sna_crtc_find_plane(sna, sna_crtc->pipe);
@@ -1904,18 +1873,18 @@ static int do_page_flip(struct sna *sna, void *data, int ref_crtc_hw_id)
evdata |= crtc->pipe == ref_crtc_hw_id;
DBG(("%s: crtc %d [ref? %d] --> fb %d\n",
- __FUNCTION__, crtc_id(crtc),
+ __FUNCTION__, crtc->id,
crtc->pipe == ref_crtc_hw_id,
sna->mode.fb_id));
if (drmModePageFlip(sna->kgem.fd,
- crtc_id(crtc),
+ crtc->id,
sna->mode.fb_id,
DRM_MODE_PAGE_FLIP_EVENT,
(void*)evdata)) {
int err = errno;
DBG(("%s: flip [fb=%d] on crtc %d [%d] failed - %d\n",
__FUNCTION__, sna->mode.fb_id,
- i, crtc_id(crtc), err));
+ i, crtc->id, err));
xf86DrvMsg(sna->scrn->scrnIndex, X_WARNING,
"flip queue failed: %s\n", strerror(err));
continue;
@@ -1927,22 +1896,6 @@ static int do_page_flip(struct sna *sna, void *data, int ref_crtc_hw_id)
return count;
}
-PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap)
-{
- PixmapPtr old = sna->front;
- ScrnInfoPtr scrn = sna->scrn;
-
- assert(sna->front != pixmap);
-
- sna->front = pixmap;
- pixmap->refcnt++;
-
- sna_redirect_screen_pixmap(scrn, old, pixmap);
- scrn->displayWidth = sna_pixmap_get_bo(pixmap)->pitch / sna->mode.cpp;
-
- return old;
-}
-
int
sna_page_flip(struct sna *sna,
struct kgem_bo *bo,
@@ -2334,7 +2287,7 @@ void sna_mode_update(struct sna *sna)
/* Validate CRTC attachments */
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
- struct sna_crtc *sna_crtc = crtc->driver_private;
+ struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
if (crtc->enabled)
sna_crtc->active = sna_crtc_is_bound(sna, crtc);
else