diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2016-10-21 09:46:23 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2016-10-21 11:33:47 +0100 |
commit | 6a2e5bca4214a3785f20fa8ba3dce5325ef75a27 (patch) | |
tree | 136a674ad6600be638d2b9abeb6e03585e441f73 | |
parent | a43455d4a317a13fe422c92b86083ed8a4fbeab9 (diff) |
sna: Force a reprobe for the specified hotplug connector
If the kernel can provide us with the exact connector that needs
reprobing following a hotplug event, use it.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/sna.h | 1 | ||||
-rw-r--r-- | src/sna/sna_display.c | 23 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 9 |
3 files changed, 30 insertions, 3 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index fb5c0074..09f57cc8 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -470,6 +470,7 @@ extern void sna_shadow_unset_crtc(struct sna *sna, xf86CrtcPtr crtc); extern bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv, const RegionRec *region); extern void sna_mode_set_primary(struct sna *sna); +extern bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id); extern void sna_mode_close(struct sna *sna); extern void sna_mode_fini(struct sna *sna); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index ea7e2879..5e8c50a5 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -273,6 +273,7 @@ struct sna_output { uint32_t last_detect; uint32_t status; bool update_properties; + bool reprobe; int num_modes; struct drm_mode_modeinfo *modes; @@ -3548,6 +3549,7 @@ sna_output_detect(xf86OutputPtr output) DBG(("%s(%s): found %d modes, connection status=%d\n", __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection)); + sna_output->reprobe = false; sna_output->last_detect = now; switch (compat_conn.conn.connection) { case DRM_MODE_CONNECTED: @@ -5147,6 +5149,22 @@ static bool disable_unused_crtc(struct sna *sna) return update; } +bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn); + int i; + + for (i = 0; i < sna->mode.num_real_output; i++) { + struct sna_output *output = to_sna_output(config->output[i]); + if (output->id == id) { + output->reprobe = true; + return true; + } + } + + return false; +} + static bool output_check_status(struct sna *sna, struct sna_output *output) { @@ -5156,6 +5174,9 @@ output_check_status(struct sna *sna, struct sna_output *output) xf86OutputStatus status; char *edid; + if (output->reprobe) + return false; + VG_CLEAR(compat_conn); compat_conn.conn.connection = -1; @@ -5237,7 +5258,7 @@ void sna_mode_discover(struct sna *sna, bool tell) res.count_connectors, sna->mode.num_real_output, res.count_encoders, res.count_crtcs)); if (res.count_connectors > 32) - return; + res.count_connectors = 32; assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn)); assert(sna->mode.max_crtc_width == res.max_width); diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index 57562b2c..c731e581 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -796,8 +796,13 @@ sna_handle_uevents(int fd, void *closure) const char *str; str = udev_device_get_property_value(dev, "HOTPLUG"); - if (str && atoi(str) == 1) - hotplug = true; + if (str && atoi(str) == 1) { + str = udev_device_get_property_value(dev, "CONNECTOR"); + if (str) + hotplug |= sna_mode_find_hotplug_connector(sna, atoi(str)); + else + hotplug = true; + } } udev_device_unref(dev); |