summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2016-10-21 09:46:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2016-10-21 11:33:47 +0100
commit6a2e5bca4214a3785f20fa8ba3dce5325ef75a27 (patch)
tree136a674ad6600be638d2b9abeb6e03585e441f73 /src
parenta43455d4a317a13fe422c92b86083ed8a4fbeab9 (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>
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna.h1
-rw-r--r--src/sna/sna_display.c23
-rw-r--r--src/sna/sna_driver.c9
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);