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

Reply via email to