debian/changelog | 8 debian/patches/randr.patch | 296 +++++++++++++++++++++++++++++++++++ debian/patches/revert-dpms-fix.patch | 2 debian/patches/series | 1 4 files changed, 306 insertions(+), 1 deletion(-)
New commits: commit a18a59406278b8448717c8a708170b1fc5131f75 Author: Robert Ancell <robert.anc...@canonical.com> Date: Wed Oct 14 15:06:48 2015 +0100 * debian/patches/randr.patch: - Combine upstream RandR changes to fix hotplug events not working (LP: #1505695) diff --git a/debian/changelog b/debian/changelog index 004324a..75dd66c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +xserver-xorg-video-intel (2:2.99.917+git20150808-0ubuntu4) wily; urgency=medium + + * debian/patches/randr.patch: + - Combine upstream RandR changes to fix hotplug events not working + (LP: #1505695) + + -- Robert Ancell <robert.anc...@canonical.com> Wed, 14 Oct 2015 14:59:19 +0100 + xserver-xorg-video-intel (2:2.99.917+git20150808-0ubuntu3) wily; urgency=medium * debian/patches/revert-dpms-fix.patch: diff --git a/debian/patches/randr.patch b/debian/patches/randr.patch new file mode 100644 index 0000000..9e963b8 --- /dev/null +++ b/debian/patches/randr.patch @@ -0,0 +1,296 @@ +commit bf63eba5f1900ab5314e3d37dff55cfca800d400 +Author: Chris Wilson <ch...@chris-wilson.co.uk> +Date: Wed Sep 9 11:18:15 2015 +0100 + + Combined RandR changes: + f5aabb7bddc6fc5dc910a983d1291c9864f65f06 + f384af433cbb39ad74e02b10d3700e71c8668506 + d50d336605e9be7280529b0eb565402d7646c913 + 2c08d72393e4c8ddf5926571b087459aaa225cb1 + 650da13c7257019728cfca361dfcbe34a6c526ef + 717b6208d0d7bdcdacaf30b871216e6084c7205c + 23986f0a31dbdec2e2086ca898bee43842ab73d4 + 15215651a992b7aa06314b9118ad9028b51c7e3e + 31d42ed5637a1b2223d48d0db4d7c512b27aee07 + 679ee12079a7d2682d41506b81973c7c7d4fa1d8 + 096ddef22d6c57198a424eef00845dc7302b0cfe + +diff --git a/src/sna/sna.h b/src/sna/sna.h +index 6c4d179..7592f7b 100644 +--- a/src/sna/sna.h ++++ b/src/sna/sna.h +@@ -442,7 +442,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna); + bool sna_mode_fake_init(struct sna *sna, int num_fake); + bool sna_mode_wants_tear_free(struct sna *sna); + void sna_mode_adjust_frame(struct sna *sna, int x, int y); +-extern void sna_mode_discover(struct sna *sna); ++extern void sna_mode_discover(struct sna *sna, bool tell); + extern void sna_mode_check(struct sna *sna); + extern bool sna_mode_disable(struct sna *sna); + extern void sna_mode_enable(struct sna *sna); +diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c +index 34d19bb..f562660 100644 +--- a/src/sna/sna_display.c ++++ b/src/sna/sna_display.c +@@ -90,6 +90,8 @@ void *alloca(size_t); + #include <memcheck.h> + #endif + ++#define COLDPLUG_DELAY_MS 2000 ++ + /* Minor discrepancy between 32-bit/64-bit ABI in old kernels */ + union compat_mode_get_connector{ + struct drm_mode_get_connector conn; +@@ -951,6 +953,8 @@ static void + sna_crtc_force_outputs_on(xf86CrtcPtr crtc) + { + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); ++ /* All attached outputs are valid, so update our timestamps */ ++ unsigned now = GetTimeInMillis(); + int i; + + assert(to_sna_crtc(crtc)); +@@ -970,6 +974,7 @@ sna_crtc_force_outputs_on(xf86CrtcPtr crtc) + continue; + + __sna_output_dpms(output, DPMSModeOn, false); ++ to_sna_output(output)->last_detect = now; + } + + #if XF86_CRTC_VERSION >= 3 +@@ -1211,9 +1216,10 @@ sna_crtc_apply(xf86CrtcPtr crtc) + output_count, output_count ? output_ids[0] : 0)); + + ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg) == 0; +- +- sna_crtc->mode_serial++; +- sna_crtc_force_outputs_on(crtc); ++ if (ret) { ++ sna_crtc->mode_serial++; ++ sna_crtc_force_outputs_on(crtc); ++ } + unblock: + sigio_unblock(sigio); + return ret; +@@ -2633,7 +2639,7 @@ error: + sna_crtc->cursor_transform = saved_cursor_transform; + sna_crtc->hwcursor = saved_hwcursor; + sna_crtc->bo = saved_bo; +- sna_mode_discover(sna); ++ sna_mode_discover(sna, true); + return FALSE; + } + +@@ -4787,17 +4793,53 @@ static bool disable_unused_crtc(struct sna *sna) + return update; + } + +-void sna_mode_discover(struct sna *sna) ++static bool ++output_check_status(struct sna *sna, struct sna_output *output) ++{ ++ union compat_mode_get_connector compat_conn; ++ struct drm_mode_modeinfo dummy; ++ xf86OutputStatus status; ++ ++ VG_CLEAR(compat_conn); ++ ++ compat_conn.conn.connector_id = output->id; ++ compat_conn.conn.count_modes = 1; /* skip detect */ ++ compat_conn.conn.modes_ptr = (uintptr_t)&dummy; ++ compat_conn.conn.count_encoders = 0; ++ compat_conn.conn.count_props = 0; ++ ++ (void)drmIoctl(sna->kgem.fd, ++ DRM_IOCTL_MODE_GETCONNECTOR, ++ &compat_conn.conn); ++ ++ switch (compat_conn.conn.connection) { ++ case DRM_MODE_CONNECTED: ++ status = XF86OutputStatusConnected; ++ break; ++ case DRM_MODE_DISCONNECTED: ++ status = XF86OutputStatusDisconnected; ++ break; ++ default: ++ case DRM_MODE_UNKNOWNCONNECTION: ++ status = XF86OutputStatusUnknown; ++ break; ++ } ++ return output->status == status; ++} ++ ++void sna_mode_discover(struct sna *sna, bool tell) + { + ScreenPtr screen = xf86ScrnToScreen(sna->scrn); + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); + struct drm_mode_card_res res; +- uint32_t connectors[32]; ++ uint32_t connectors[32], now; + unsigned changed = 0; + unsigned serial; + int i, j; + + DBG(("%s()\n", __FUNCTION__)); ++ sna->flags &= ~SNA_REPROBE; ++ + VG_CLEAR(connectors); + + memset(&res, 0, sizeof(res)); +@@ -4822,6 +4864,7 @@ void sna_mode_discover(struct sna *sna) + if (serial == 0) + serial = ++sna->mode.serial; + ++ now = GetTimeInMillis(); + for (i = 0; i < res.count_connectors; i++) { + DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i])); + for (j = 0; j < sna->mode.num_real_output; j++) { +@@ -4846,10 +4889,17 @@ void sna_mode_discover(struct sna *sna) + if (sna_output->id == 0) + continue; + +- sna_output->last_detect = 0; + if (sna_output->serial == serial) { +- if (sna_output_detect(output) != output->status) +- RROutputChanged(output->randr_output, TRUE); ++ if (output_check_status(sna, sna_output)) { ++ DBG(("%s: output %s (id=%d), retained state\n", ++ __FUNCTION__, output->name, sna_output->id)); ++ sna_output->last_detect = now; ++ } else { ++ DBG(("%s: output %s (id=%d), changed state, reprobing\n", ++ __FUNCTION__, output->name, sna_output->id)); ++ sna_output->last_detect = 0; ++ changed |= 4; ++ } + continue; + } + +@@ -4861,12 +4911,14 @@ void sna_mode_discover(struct sna *sna) + "Disabled output %s\n", + output->name); + sna_output->id = 0; ++ sna_output->last_detect = 0; + output->crtc = NULL; + RROutputChanged(output->randr_output, TRUE); + changed |= 2; + } + +- if (changed) { ++ /* Have the list of available outputs been updated? */ ++ if (changed & 3) { + DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__)); + + sna_mode_set_primary(sna); +@@ -4881,7 +4933,50 @@ void sna_mode_discover(struct sna *sna) + xf86RandR12TellChanged(screen); + } + +- RRTellChanged(screen); ++ /* If anything has changed, refresh the RandR information. ++ * Note this could recurse once from udevless RRGetInfo() probes, ++ * but only once. ++ */ ++ if (changed && tell) ++ RRGetInfo(screen, TRUE); ++} ++ ++/* Since we only probe the current mode on startup, we may not have the full ++ * list of modes available until the user explicitly requests them. Fake a ++ * hotplug event after a second after starting to fill in any missing modes. ++ */ ++static CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data) ++{ ++ struct sna *sna = data; ++ ScreenPtr screen = xf86ScrnToScreen(sna->scrn); ++ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); ++ bool reprobe = false; ++ int i; ++ ++ DBG(("%s()\n", __FUNCTION__)); ++ ++ for (i = 0; i < sna->mode.num_real_output; i++) { ++ xf86OutputPtr output = config->output[i]; ++ struct sna_output *sna_output = to_sna_output(output); ++ ++ if (sna_output->id == 0) ++ continue; ++ if (sna_output->last_detect) ++ continue; ++ if (output->status == XF86OutputStatusDisconnected) ++ continue; ++ ++ DBG(("%s: output %s connected, needs reprobe\n", ++ __FUNCTION__, output->name)); ++ reprobe = true; ++ } ++ ++ if (reprobe) { ++ RRGetInfo(screen, TRUE); ++ RRTellChanged(screen); ++ } ++ free(timer); ++ return 0; + } + + static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new) +@@ -6818,6 +6913,7 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) + } + } + sort_config_outputs(sna); ++ TimerSet(NULL, 0, COLDPLUG_DELAY_MS, sna_mode_coldplug, sna); + + sna_setup_provider(scrn); + return scrn->modes != NULL; +diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c +index 18fc48d..8cbabb0 100644 +--- a/src/sna/sna_driver.c ++++ b/src/sna/sna_driver.c +@@ -755,7 +755,7 @@ sna_handle_uevents(int fd, void *closure) + if (fstat(sna->kgem.fd, &s)) + memset(&s, 0, sizeof(s)); + +- do { ++ while (poll(&pfd, 1, 0) > 0) { + struct udev_device *dev; + dev_t devnum; + +@@ -773,14 +773,14 @@ sna_handle_uevents(int fd, void *closure) + } + + udev_device_unref(dev); +- } while (poll(&pfd, 1, 0) > 0); ++ } + + if (hotplug) { + DBG(("%s: hotplug event (vtSema?=%d)\n", + __FUNCTION__, sna->scrn->vtSema)); + + if (sna->scrn->vtSema) { +- sna_mode_discover(sna); ++ sna_mode_discover(sna, true); + sna_mode_check(sna); + } else + sna->flags |= SNA_REPROBE; +@@ -890,8 +890,10 @@ sna_randr_getinfo(ScreenPtr screen, Rotation *rotations) + { + struct sna *sna = to_sna_from_screen(screen); + ++ DBG(("%s()\n", __FUNCTION__)); ++ + if (!sna_uevent_poll(sna)) +- sna_mode_discover(sna); ++ sna_mode_discover(sna, false); + + return sna->mode.rrGetInfo(screen, rotations); + } +@@ -1220,8 +1222,7 @@ static Bool sna_enter_vt(VT_FUNC_ARGS_DECL) + + if (sna->flags & SNA_REPROBE) { + DBG(("%s: reporting deferred hotplug event\n", __FUNCTION__)); +- sna_mode_discover(sna); +- sna->flags &= ~SNA_REPROBE; ++ sna_mode_discover(sna, true); + } + + sna_set_desired_mode(sna); diff --git a/debian/patches/revert-dpms-fix.patch b/debian/patches/revert-dpms-fix.patch index b08933b..283c1f3 100644 --- a/debian/patches/revert-dpms-fix.patch +++ b/debian/patches/revert-dpms-fix.patch @@ -36,9 +36,9 @@ Index: xserver-xorg-video-intel-2.99.917+git20150808/src/sna/sna_display.c - __sna_output_dpms(output, DPMSModeOn, false); + output->funcs->dpms(output, DPMSModeOn); + to_sna_output(output)->last_detect = now; } - #if XF86_CRTC_VERSION >= 3 @@ -999,7 +998,7 @@ sna_crtc_force_outputs_off(xf86CrtcPtr c if (output->crtc != crtc) continue; diff --git a/debian/patches/series b/debian/patches/series index e4d479f..10fd925 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,2 +1,3 @@ sna-check-for-system-memory-contents.diff +randr.patch revert-dpms-fix.patch