diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2012-10-11 18:10:17 -0300 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-10-12 09:45:37 +0100 |
commit | 1ec41590c9d142a77a2fdcfcd9a762aca99d9d86 (patch) | |
tree | dc337d4a281463f9897686b8212582eaeb2a8918 /src/sna/sna_display.c | |
parent | 0b92a5a3062d73666279e17ac2d711314bcd8dfe (diff) |
Fix possible_clones computation for shared encoders between outputs
Libdrm's possible_clones is a mask of encoders. Xorg's possible_clones
is a mask of outputs, so we just can't do the following:
output->possible_clones = kencoder->possible_clones;
This is a problem on Haswell because, at least with the current
patches floating on the mailing list, there is more than one connector
per encoder.
This patch writes the code to properly translate libdrm's encoder mask
into Xorg's output mask.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_display.c')
-rw-r--r-- | src/sna/sna_display.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index fc5cbfc5..ed323755 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -2291,6 +2291,35 @@ cleanup_connector: drmModeFreeConnector(koutput); } +/* The kernel reports possible encoder clones, whereas X uses a list of + * possible connector clones. This is works when we have a 1:1 mapping + * between encoders and connectors, but breaks for Haswell which has a pair + * of DP/HDMI connectors hanging off a single encoder. + */ +static void +sna_mode_compute_possible_clones(ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + unsigned clones[32] = { 0 }; + int i, j; + + assert(config->num_output <= 32); + + /* Convert from encoder numbering to output numbering */ + for (i = 0; i < config->num_output; i++) { + unsigned mask = config->output[i]->possible_clones; + for (j = 0; mask != 0; j++, mask >>= 1) { + if ((mask & 1) == 0) + continue; + + clones[j] |= 1 << i; + } + } + + for (i = 0; i < config->num_output; i++) + config->output[i]->possible_clones = clones[i]; +} + struct sna_visit_set_pixmap_window { PixmapPtr old, new; }; @@ -2574,6 +2603,9 @@ bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna) for (i = 0; i < mode->kmode->count_connectors; i++) sna_output_init(scrn, mode, i); + if (!xf86IsEntityShared(scrn->entityList[0])) + sna_mode_compute_possible_clones(scrn); + #if HAS_PIXMAP_SHARING xf86ProviderSetup(scrn, NULL, "Intel"); #endif |