1
--- a/src/intel_display.c
2
+++ b/src/intel_display.c
4
intel_output_backlight_init(output);
6
output->possible_crtcs = kencoder->possible_crtcs;
7
- output->possible_clones = kencoder->possible_clones;
8
output->interlaceAllowed = TRUE;
10
intel_output->output = output;
11
@@ -1680,6 +1679,60 @@
12
drmHandleEvent(mode->fd, &mode->event_context);
15
+static drmModeEncoderPtr
16
+intel_get_kencoder(struct intel_mode *mode, int num)
18
+ struct intel_output *iterator;
19
+ int id = mode->mode_res->encoders[num];
21
+ list_for_each_entry(iterator, &mode->outputs, link)
22
+ if (iterator->mode_encoder->encoder_id == id)
23
+ return iterator->mode_encoder;
29
+ * Libdrm's possible_clones is a mask of encoders, Xorg's possible_clones is a
30
+ * mask of outputs. This function sets Xorg's possible_clones based on the
31
+ * values read from libdrm.
34
+intel_compute_possible_clones(ScrnInfoPtr scrn, struct intel_mode *mode)
36
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
37
+ struct intel_output *intel_output, *clone;
38
+ drmModeEncoderPtr cloned_encoder;
41
+ CARD32 possible_clones;
43
+ for (i = 0; i < config->num_output; i++) {
44
+ possible_clones = 0;
45
+ intel_output = config->output[i]->driver_private;
47
+ mask = intel_output->mode_encoder->possible_clones;
48
+ for (j = 0; mask != 0; j++, mask >>= 1) {
50
+ if ((mask & 1) == 0)
53
+ cloned_encoder = intel_get_kencoder(mode, j);
54
+ if (!cloned_encoder)
57
+ for (k = 0; k < config->num_output; k++) {
58
+ clone = config->output[k]->driver_private;
59
+ if (clone->mode_encoder->encoder_id ==
60
+ cloned_encoder->encoder_id)
61
+ possible_clones |= (1 << k);
65
+ config->output[i]->possible_clones = possible_clones;
69
Bool intel_mode_pre_init(ScrnInfoPtr scrn, int fd, int cpp)
71
intel_screen_private *intel = intel_get_screen_private(scrn);
74
for (i = 0; i < mode->mode_res->count_connectors; i++)
75
intel_output_init(scrn, mode, i);
76
+ intel_compute_possible_clones(scrn, mode);
78
#ifdef INTEL_PIXMAP_SHARING
79
xf86ProviderSetup(scrn, NULL, "Intel");
80
--- a/src/sna/sna_display.c
81
+++ b/src/sna/sna_display.c
82
@@ -2291,6 +2291,35 @@
83
drmModeFreeConnector(koutput);
86
+/* The kernel reports possible encoder clones, whereas X uses a list of
87
+ * possible connector clones. This is works when we have a 1:1 mapping
88
+ * between encoders and connectors, but breaks for Haswell which has a pair
89
+ * of DP/HDMI connectors hanging off a single encoder.
92
+sna_mode_compute_possible_clones(ScrnInfoPtr scrn)
94
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
95
+ unsigned clones[32] = { 0 };
98
+ assert(config->num_output <= 32);
100
+ /* Convert from encoder numbering to output numbering */
101
+ for (i = 0; i < config->num_output; i++) {
102
+ unsigned mask = config->output[i]->possible_clones;
103
+ for (j = 0; mask != 0; j++, mask >>= 1) {
104
+ if ((mask & 1) == 0)
107
+ clones[j] |= 1 << i;
111
+ for (i = 0; i < config->num_output; i++)
112
+ config->output[i]->possible_clones = clones[i];
115
struct sna_visit_set_pixmap_window {
118
@@ -2573,6 +2602,8 @@
120
for (i = 0; i < mode->kmode->count_connectors; i++)
121
sna_output_init(scrn, mode, i);
122
+ if (!xf86IsEntityShared(scrn->entityList[0]))
123
+ sna_mode_compute_possible_clones(scrn);
125
#if HAS_PIXMAP_SHARING
126
xf86ProviderSetup(scrn, NULL, "Intel");