1 /*
2 * Copyright © 2007 Red Hat, Inc.
3 * Copyright © 2013-2014 Intel Corporation
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Dave Airlie <airlied@redhat.com>
26 *
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <stdint.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/mman.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <errno.h>
40 #include <poll.h>
41 #include <ctype.h>
42 #include <dirent.h>
43
44 #if HAVE_ALLOCA_H
45 #include <alloca.h>
46 #elif defined __GNUC__
47 #define alloca __builtin_alloca
48 #elif defined _AIX
49 #define alloca __alloca
50 #elif defined _MSC_VER
51 #include <malloc.h>
52 #define alloca _alloca
53 #else
54 void *alloca(size_t);
55 #endif
56
57 #define _PARSE_EDID_
58 /* Jump through a few hoops in order to fixup EDIDs */
59 #undef VERSION
60 #undef REVISION
61
62 #include "sna.h"
63 #include "sna_reg.h"
64 #include "fb/fbpict.h"
65 #include "intel_options.h"
66 #include "backlight.h"
67
68 #include <xf86Crtc.h>
69 #include <xf86RandR12.h>
70 #include <cursorstr.h>
71
72 #if XF86_CRTC_VERSION >= 3
73 #define HAS_GAMMA 1
74 #else
75 #define HAS_GAMMA 0
76 #endif
77
78 #include <X11/Xatom.h>
79 #if defined(HAVE_X11_EXTENSIONS_DPMSCONST_H)
80 #include <X11/extensions/dpmsconst.h>
81 #else
82 #define DPMSModeOn 0
83 #define DPMSModeOff 3
84 #endif
85 #include <xf86DDC.h> /* for xf86InterpretEDID */
86
87 #include <xf86drm.h>
88
89 #ifdef HAVE_VALGRIND
90 #include <valgrind.h>
91 #include <memcheck.h>
92 #endif
93
94 #define FAIL_CURSOR_IOCTL 0
95
96 /* Minor discrepancy between 32-bit/64-bit ABI in old kernels */
97 union compat_mode_get_connector{
98 struct drm_mode_get_connector conn;
99 uint32_t pad[20];
100 };
101
102 #define KNOWN_MODE_FLAGS ((1<<14)-1)
103
104 #ifndef MONITOR_EDID_COMPLETE_RAWDATA
105 #define MONITOR_EDID_COMPLETE_RAWDATA 1
106 #endif
107
108 #ifndef DEFAULT_DPI
109 #define DEFAULT_DPI 96
110 #endif
111
112 #define OUTPUT_STATUS_CACHE_MS 15000
113
114 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
115
116 #define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
117 #define DRM_PLANE_TYPE_OVERLAY 0
118 #define DRM_PLANE_TYPE_PRIMARY 1
119 #define DRM_PLANE_TYPE_CURSOR 2
120
121 #define LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xb9, struct local_mode_obj_get_properties)
122 struct local_mode_obj_get_properties {
123 uint64_t props_ptr;
124 uint64_t prop_values_ptr;
125 uint32_t count_props;
126 uint32_t obj_id;
127 uint32_t obj_type;
128 uint32_t pad;
129 };
130 #define LOCAL_MODE_OBJECT_CRTC 0xcccccccc
131 #define LOCAL_MODE_OBJECT_PLANE 0xeeeeeeee
132
133 struct local_mode_set_plane {
134 uint32_t plane_id;
135 uint32_t crtc_id;
136 uint32_t fb_id; /* fb object contains surface format type */
137 uint32_t flags;
138
139 /* Signed dest location allows it to be partially off screen */
140 int32_t crtc_x, crtc_y;
141 uint32_t crtc_w, crtc_h;
142
143 /* Source values are 16.16 fixed point */
144 uint32_t src_x, src_y;
145 uint32_t src_h, src_w;
146 };
147 #define LOCAL_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct local_mode_set_plane)
148
149 struct local_mode_get_plane {
150 uint32_t plane_id;
151
152 uint32_t crtc_id;
153 uint32_t fb_id;
154
155 uint32_t possible_crtcs;
156 uint32_t gamma_size;
157
158 uint32_t count_format_types;
159 uint64_t format_type_ptr;
160 };
161 #define LOCAL_IOCTL_MODE_GETPLANE DRM_IOWR(0xb6, struct local_mode_get_plane)
162
163 struct local_mode_get_plane_res {
164 uint64_t plane_id_ptr;
165 uint64_t count_planes;
166 };
167 #define LOCAL_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xb5, struct local_mode_get_plane_res)
168
169 #if 1
170 #define __DBG DBG
171 #else
172 #define __DBG(x)
173 #endif
174
175 #define DBG_NATIVE_ROTATION ~0 /* minimum RR_Rotate_0 */
176
177 extern XF86ConfigPtr xf86configptr;
178
179 struct sna_cursor {
180 struct sna_cursor *next;
181 uint32_t *image;
182 bool transformed;
183 Rotation rotation;
184 int ref;
185 int size;
186 int last_width;
187 int last_height;
188 unsigned handle;
189 unsigned serial;
190 unsigned alloc;
191 };
192
193 struct sna_crtc {
194 struct sna_crtc_public public;
195 uint32_t id;
196 xf86CrtcPtr base;
197 struct drm_mode_modeinfo kmode;
198 PixmapPtr slave_pixmap;
199 DamagePtr slave_damage;
200 struct kgem_bo *bo, *shadow_bo, *client_bo, *cache_bo;
201 struct sna_cursor *cursor;
202 unsigned int last_cursor_size;
203 uint32_t offset;
204 bool shadow;
205 bool fallback_shadow;
206 bool transform;
207 bool cursor_transform;
208 bool hwcursor;
209 bool flip_pending;
210
211 struct pict_f_transform cursor_to_fb, fb_to_cursor;
212
213 RegionRec crtc_damage;
214 uint16_t shadow_bo_width, shadow_bo_height;
215
216 uint32_t rotation;
217 struct plane {
218 uint32_t id;
219 uint32_t type;
220 struct {
221 uint32_t prop;
222 uint32_t supported;
223 uint32_t current;
224 } rotation;
225 struct {
226 uint32_t prop;
227 uint64_t values[2];
228 } color_encoding;
229 struct list link;
230 } primary;
231 struct list sprites;
232
233 struct drm_color_lut *gamma_lut;
234 uint64_t gamma_lut_prop;
235 uint64_t gamma_lut_blob;
236 uint32_t gamma_lut_size;
237
238 uint32_t mode_serial, flip_serial;
239
240 uint32_t last_seq, wrap_seq;
241 struct ust_msc swap;
242
243 sna_flip_handler_t flip_handler;
244 struct kgem_bo *flip_bo;
245 void *flip_data;
246
247 struct list shadow_link;
248 };
249
250 struct sna_property {
251 drmModePropertyPtr kprop;
252 int num_atoms; /* if range prop, num_atoms == 1; if enum prop, num_atoms == num_enums + 1 */
253 Atom *atoms;
254 };
255
256 struct sna_output {
257 xf86OutputPtr base;
258 unsigned id;
259 unsigned serial;
260
261 unsigned possible_encoders;
262 unsigned attached_encoders;
263
264 unsigned int is_panel : 1;
265 unsigned int add_default_modes : 1;
266 int connector_type;
267 int connector_type_id;
268
269 uint32_t link_status_idx;
270
271 uint32_t edid_idx;
272 uint32_t edid_blob_id;
273 uint32_t edid_len;
274 void *edid_raw;
275 void *fake_edid_raw;
276
277 bool has_panel_limits;
278 int panel_hdisplay;
279 int panel_vdisplay;
280
281 uint32_t dpms_id;
282 uint8_t dpms_mode;
283 struct backlight backlight;
284 int backlight_active_level;
285
286 uint32_t last_detect;
287 uint32_t status;
288 unsigned int hotplug_count;
289 bool update_properties;
290 bool reprobe;
291
292 int num_modes;
293 struct drm_mode_modeinfo *modes;
294
295 int num_props;
296 uint32_t *prop_ids;
297 uint64_t *prop_values;
298 struct sna_property *props;
299 };
300
301 enum { /* XXX copied from hw/xfree86/modes/xf86Crtc.c */
302 OPTION_PREFERRED_MODE,
303 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,14,99,1,0)
304 OPTION_ZOOM_MODES,
305 #endif
306 OPTION_POSITION,
307 OPTION_BELOW,
308 OPTION_RIGHT_OF,
309 OPTION_ABOVE,
310 OPTION_LEFT_OF,
311 OPTION_ENABLE,
312 OPTION_DISABLE,
313 OPTION_MIN_CLOCK,
314 OPTION_MAX_CLOCK,
315 OPTION_IGNORE,
316 OPTION_ROTATE,
317 OPTION_PANNING,
318 OPTION_PRIMARY,
319 OPTION_DEFAULT_MODES,
320 };
321
322 static void __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup);
323 static void sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc);
324 static bool sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc,
325 struct kgem_bo *bo, int x, int y);
326 static void sna_crtc_gamma_set(xf86CrtcPtr crtc,
327 CARD16 *red, CARD16 *green,
328 CARD16 *blue, int size);
329
is_zaphod(ScrnInfoPtr scrn)330 static bool is_zaphod(ScrnInfoPtr scrn)
331 {
332 return xf86IsEntityShared(scrn->entityList[0]);
333 }
334
335 static bool
sna_zaphod_match(struct sna * sna,const char * output)336 sna_zaphod_match(struct sna *sna, const char *output)
337 {
338 const char *s, *colon;
339 char t[20];
340 unsigned int i = 0;
341
342 s = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
343 if (s == NULL)
344 return false;
345
346 colon = strchr(s, ':');
347 if (colon) /* Skip over the ZaphodPipes */
348 s = colon + 1;
349
350 do {
351 /* match any outputs in a comma list, stopping at whitespace */
352 switch (*s) {
353 case '\0':
354 t[i] = '\0';
355 return strcmp(t, output) == 0;
356
357 case ',':
358 t[i] ='\0';
359 if (strcmp(t, output) == 0)
360 return TRUE;
361 i = 0;
362 break;
363
364 case ' ':
365 case '\t':
366 case '\n':
367 case '\r':
368 break;
369
370 default:
371 t[i++] = *s;
372 break;
373 }
374
375 s++;
376 } while (i < sizeof(t));
377
378 return false;
379 }
380
381 static unsigned
get_zaphod_crtcs(struct sna * sna)382 get_zaphod_crtcs(struct sna *sna)
383 {
384 const char *str, *colon;
385 unsigned crtcs = 0;
386
387 str = xf86GetOptValString(sna->Options, OPTION_ZAPHOD);
388 if (str == NULL || (colon = strchr(str, ':')) == NULL) {
389 DBG(("%s: no zaphod pipes, using screen number: %x\n",
390 __FUNCTION__,
391 sna->scrn->confScreen->device->screen));
392 return 1 << sna->scrn->confScreen->device->screen;
393 }
394
395 DBG(("%s: ZaphodHeads='%s'\n", __FUNCTION__, str));
396 while (str < colon) {
397 char *end;
398 unsigned crtc = strtoul(str, &end, 0);
399 if (end == str)
400 break;
401 DBG(("%s: adding CRTC %d to zaphod pipes\n",
402 __FUNCTION__, crtc));
403 crtcs |= 1 << crtc;
404 str = end + 1;
405 }
406 DBG(("%s: ZaphodPipes=%x\n", __FUNCTION__, crtcs));
407 return crtcs;
408 }
409
count_to_mask(int x)410 inline static unsigned count_to_mask(int x)
411 {
412 return (1 << x) - 1;
413 }
414
to_sna_output(xf86OutputPtr output)415 static inline struct sna_output *to_sna_output(xf86OutputPtr output)
416 {
417 return output->driver_private;
418 }
419
to_connector_id(xf86OutputPtr output)420 static inline int to_connector_id(xf86OutputPtr output)
421 {
422 assert(to_sna_output(output));
423 assert(to_sna_output(output)->id);
424 return to_sna_output(output)->id;
425 }
426
to_sna_crtc(xf86CrtcPtr crtc)427 static inline struct sna_crtc *to_sna_crtc(xf86CrtcPtr crtc)
428 {
429 return crtc->driver_private;
430 }
431
__sna_crtc_pipe(struct sna_crtc * crtc)432 static inline unsigned __sna_crtc_pipe(struct sna_crtc *crtc)
433 {
434 return crtc->public.flags >> 8 & 0xff;
435 }
436
__sna_crtc_id(struct sna_crtc * crtc)437 static inline unsigned __sna_crtc_id(struct sna_crtc *crtc)
438 {
439 return crtc->id;
440 }
441
sna_crtc_id(xf86CrtcPtr crtc)442 uint32_t sna_crtc_id(xf86CrtcPtr crtc)
443 {
444 return __sna_crtc_id(to_sna_crtc(crtc));
445 }
446
event_pending(int fd)447 static inline bool event_pending(int fd)
448 {
449 struct pollfd pfd;
450 pfd.fd = fd;
451 pfd.events = POLLIN;
452 return poll(&pfd, 1, 0) == 1;
453 }
454
sna_mode_wait_for_event(struct sna * sna)455 static bool sna_mode_wait_for_event(struct sna *sna)
456 {
457 struct pollfd pfd;
458 pfd.fd = sna->kgem.fd;
459 pfd.events = POLLIN;
460 return poll(&pfd, 1, -1) == 1;
461 }
462
fb_id(struct kgem_bo * bo)463 static inline uint32_t fb_id(struct kgem_bo *bo)
464 {
465 return bo->delta;
466 }
467
sna_crtc_count_sprites(xf86CrtcPtr crtc)468 unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc)
469 {
470 struct plane *sprite;
471 unsigned count;
472
473 count = 0;
474 list_for_each_entry(sprite, &to_sna_crtc(crtc)->sprites, link)
475 count++;
476
477 return count;
478 }
479
lookup_sprite(struct sna_crtc * crtc,unsigned idx)480 static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx)
481 {
482 struct plane *sprite;
483
484 list_for_each_entry(sprite, &crtc->sprites, link)
485 if (idx-- == 0)
486 return sprite;
487
488 return NULL;
489 }
490
sna_crtc_to_sprite(xf86CrtcPtr crtc,unsigned idx)491 uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx)
492 {
493 struct plane *sprite;
494
495 assert(to_sna_crtc(crtc));
496
497 sprite = lookup_sprite(to_sna_crtc(crtc), idx);
498 return sprite ? sprite->id : 0;
499 }
500
sna_crtc_is_transformed(xf86CrtcPtr crtc)501 bool sna_crtc_is_transformed(xf86CrtcPtr crtc)
502 {
503 assert(to_sna_crtc(crtc));
504 return to_sna_crtc(crtc)->transform;
505 }
506
msc64(struct sna_crtc * sna_crtc,uint32_t seq,uint64_t * msc)507 static inline bool msc64(struct sna_crtc *sna_crtc, uint32_t seq, uint64_t *msc)
508 {
509 bool record = true;
510 if (seq < sna_crtc->last_seq) {
511 if (sna_crtc->last_seq - seq > 0x40000000) {
512 sna_crtc->wrap_seq++;
513 DBG(("%s: pipe=%d wrapped; was %u, now %u, wraps=%u\n",
514 __FUNCTION__, __sna_crtc_pipe(sna_crtc),
515 sna_crtc->last_seq, seq, sna_crtc->wrap_seq));
516 } else {
517 DBG(("%s: pipe=%d msc went backwards; was %u, now %u; ignoring for last_swap\n",
518 __FUNCTION__, __sna_crtc_pipe(sna_crtc), sna_crtc->last_seq, seq));
519
520 record = false;
521 }
522 }
523 *msc = (uint64_t)sna_crtc->wrap_seq << 32 | seq;
524 return record;
525 }
526
sna_crtc_record_swap(xf86CrtcPtr crtc,int tv_sec,int tv_usec,unsigned seq)527 uint64_t sna_crtc_record_swap(xf86CrtcPtr crtc,
528 int tv_sec, int tv_usec, unsigned seq)
529 {
530 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
531 uint64_t msc;
532
533 assert(sna_crtc);
534
535 if (msc64(sna_crtc, seq, &msc)) {
536 DBG(("%s: recording last swap on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n",
537 __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc,
538 tv_sec, tv_usec));
539 sna_crtc->swap.tv_sec = tv_sec;
540 sna_crtc->swap.tv_usec = tv_usec;
541 sna_crtc->swap.msc = msc;
542 } else {
543 DBG(("%s: swap event on pipe=%d, frame %d [msc=%08lld], time %d.%06d\n",
544 __FUNCTION__, __sna_crtc_pipe(sna_crtc), seq, (long long)msc,
545 tv_sec, tv_usec));
546 }
547
548 return msc;
549 }
550
sna_crtc_last_swap(xf86CrtcPtr crtc)551 const struct ust_msc *sna_crtc_last_swap(xf86CrtcPtr crtc)
552 {
553 static struct ust_msc zero;
554
555 if (crtc == NULL) {
556 return &zero;
557 } else {
558 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
559 assert(sna_crtc);
560 return &sna_crtc->swap;
561 }
562 }
563
564 #ifndef NDEBUG
565 static void gem_close(int fd, uint32_t handle);
assert_scanout(struct kgem * kgem,struct kgem_bo * bo,int width,int height)566 static void assert_scanout(struct kgem *kgem, struct kgem_bo *bo,
567 int width, int height)
568 {
569 struct drm_mode_fb_cmd info;
570
571 assert(bo->scanout);
572
573 VG_CLEAR(info);
574 info.fb_id = fb_id(bo);
575
576 assert(drmIoctl(kgem->fd, DRM_IOCTL_MODE_GETFB, &info) == 0);
577 gem_close(kgem->fd, info.handle);
578
579 assert(width <= info.width && height <= info.height);
580 }
581 #else
582 #define assert_scanout(k, b, w, h)
583 #endif
584
assert_crtc_fb(struct sna * sna,struct sna_crtc * crtc)585 static void assert_crtc_fb(struct sna *sna, struct sna_crtc *crtc)
586 {
587 #ifndef NDEBUG
588 struct drm_mode_crtc mode = { .crtc_id = __sna_crtc_id(crtc) };
589 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode);
590 assert(mode.fb_id == fb_id(crtc->bo));
591 #endif
592 }
593
get_fb(struct sna * sna,struct kgem_bo * bo,int width,int height)594 static unsigned get_fb(struct sna *sna, struct kgem_bo *bo,
595 int width, int height)
596 {
597 ScrnInfoPtr scrn = sna->scrn;
598 struct drm_mode_fb_cmd arg;
599
600 if (!kgem_bo_is_fenced(&sna->kgem, bo))
601 return 0;
602
603 assert(bo->refcnt);
604 assert(bo->proxy == NULL);
605 assert(!bo->snoop);
606 assert(8*bo->pitch >= width * scrn->bitsPerPixel);
607 assert(height * bo->pitch <= kgem_bo_size(bo)); /* XXX crtc offset */
608 if (fb_id(bo)) {
609 DBG(("%s: reusing fb=%d for handle=%d\n",
610 __FUNCTION__, fb_id(bo), bo->handle));
611 assert_scanout(&sna->kgem, bo, width, height);
612 return fb_id(bo);
613 }
614
615 DBG(("%s: create fb %dx%d@%d/%d\n",
616 __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
617
618 assert(bo->tiling != I915_TILING_Y || sna->kgem.can_scanout_y);
619 assert((bo->pitch & 63) == 0);
620 assert(scrn->vtSema); /* must be master */
621
622 VG_CLEAR(arg);
623 arg.width = width;
624 arg.height = height;
625 arg.pitch = bo->pitch;
626 arg.bpp = scrn->bitsPerPixel;
627 arg.depth = scrn->depth;
628 arg.handle = bo->handle;
629
630 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
631 /* Try again with the fancy version */
632 struct local_mode_fb_cmd2 {
633 uint32_t fb_id;
634 uint32_t width, height;
635 uint32_t pixel_format;
636 uint32_t flags;
637
638 uint32_t handles[4];
639 uint32_t pitches[4]; /* pitch for each plane */
640 uint32_t offsets[4]; /* offset of each plane */
641 uint64_t modifiers[4];
642 } f;
643 #define LOCAL_IOCTL_MODE_ADDFB2 DRM_IOWR(0xb8, struct local_mode_fb_cmd2)
644 memset(&f, 0, sizeof(f));
645 f.width = width;
646 f.height = height;
647 /* XXX interlaced */
648 f.flags = 1 << 1; /* +modifiers */
649 f.handles[0] = bo->handle;
650 f.pitches[0] = bo->pitch;
651
652 switch (bo->tiling) {
653 case I915_TILING_NONE:
654 break;
655 case I915_TILING_X:
656 /* I915_FORMAT_MOD_X_TILED */
657 f.modifiers[0] = (uint64_t)1 << 56 | 1;
658 break;
659 case I915_TILING_Y:
660 /* I915_FORMAT_MOD_X_TILED */
661 f.modifiers[0] = (uint64_t)1 << 56 | 2;
662 break;
663 }
664
665 #define fourcc(a,b,c,d) ((a) | (b) << 8 | (c) << 16 | (d) << 24)
666 switch (scrn->depth) {
667 default:
668 ERR(("%s: unhandled screen format, depth=%d\n",
669 __FUNCTION__, scrn->depth));
670 goto fail;
671 case 8:
672 f.pixel_format = fourcc('C', '8', ' ', ' ');
673 break;
674 case 15:
675 f.pixel_format = fourcc('X', 'R', '1', '5');
676 break;
677 case 16:
678 f.pixel_format = fourcc('R', 'G', '1', '6');
679 break;
680 case 24:
681 f.pixel_format = fourcc('X', 'R', '2', '4');
682 break;
683 case 30:
684 f.pixel_format = fourcc('X', 'R', '3', '0');
685 break;
686 }
687 #undef fourcc
688
689 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_ADDFB2, &f)) {
690 fail:
691 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
692 "%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d: %d\n",
693 __FUNCTION__, width, height,
694 scrn->depth, scrn->bitsPerPixel, bo->pitch, errno);
695 return 0;
696 }
697
698 arg.fb_id = f.fb_id;
699 }
700 assert(arg.fb_id != 0);
701 bo->delta = arg.fb_id;
702 DBG(("%s: attached fb=%d to handle=%d\n",
703 __FUNCTION__, bo->delta, arg.handle));
704
705 bo->scanout = true;
706 return bo->delta;
707 }
708
gem_create(int fd,int size)709 static uint32_t gem_create(int fd, int size)
710 {
711 struct drm_i915_gem_create create;
712
713 assert((size & 4095) == 0);
714
715 VG_CLEAR(create);
716 create.handle = 0;
717 create.size = size;
718 (void)drmIoctl(fd, DRM_IOCTL_I915_GEM_CREATE, &create);
719
720 return create.handle;
721 }
722
gem_mmap(int fd,int handle,int size)723 static void *gem_mmap(int fd, int handle, int size)
724 {
725 struct drm_i915_gem_mmap_gtt mmap_arg;
726 struct drm_i915_gem_set_domain set_domain;
727 void *ptr;
728
729 VG_CLEAR(mmap_arg);
730 mmap_arg.handle = handle;
731 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_MMAP_GTT, &mmap_arg))
732 return NULL;
733
734 ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mmap_arg.offset);
735 if (ptr == MAP_FAILED)
736 return NULL;
737
738 VG_CLEAR(set_domain);
739 set_domain.handle = handle;
740 set_domain.read_domains = I915_GEM_DOMAIN_GTT;
741 set_domain.write_domain = I915_GEM_DOMAIN_GTT;
742 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_SET_DOMAIN, &set_domain)) {
743 munmap(ptr, size);
744 return NULL;
745 }
746
747 return ptr;
748 }
749
gem_close(int fd,uint32_t handle)750 static void gem_close(int fd, uint32_t handle)
751 {
752 struct drm_gem_close close;
753
754 VG_CLEAR(close);
755 close.handle = handle;
756 (void)drmIoctl(fd, DRM_IOCTL_GEM_CLOSE, &close);
757 }
758
759 #define BACKLIGHT_NAME "Backlight"
760 #define BACKLIGHT_DEPRECATED_NAME "BACKLIGHT"
761 static Atom backlight_atom, backlight_deprecated_atom;
762
763 #if HAVE_UDEV
764 static void
sna_backlight_uevent(int fd,void * closure)765 sna_backlight_uevent(int fd, void *closure)
766 {
767 struct sna *sna = closure;
768 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
769 int i;
770
771 DBG(("%s()\n", __FUNCTION__));
772
773 /* Drain the event queue */
774 while (event_pending(fd)) {
775 struct udev_device *dev;
776
777 DBG(("%s: waiting for uevent\n", __FUNCTION__));
778 dev = udev_monitor_receive_device(sna->mode.backlight_monitor);
779 if (dev == NULL)
780 break;
781
782 udev_device_unref(dev);
783 }
784
785 /* Query all backlights for any changes */
786 DBG(("%s: probing backlights for changes\n", __FUNCTION__));
787 for (i = 0; i < sna->mode.num_real_output; i++) {
788 xf86OutputPtr output = config->output[i];
789 struct sna_output *sna_output = to_sna_output(output);
790 int val;
791
792 if (sna_output->dpms_mode != DPMSModeOn)
793 continue;
794
795 val = backlight_get(&sna_output->backlight);
796 if (val < 0)
797 continue;
798 DBG(("%s(%s): backlight '%s' was %d, now %d\n",
799 __FUNCTION__, output->name, sna_output->backlight.iface,
800 sna_output->backlight_active_level, val));
801
802 if (val == sna_output->backlight_active_level)
803 continue;
804
805 sna_output->backlight_active_level = val;
806
807 if (output->randr_output) {
808 DBG(("%s(%s): sending change notification\n", __FUNCTION__, output->name));
809 RRChangeOutputProperty(output->randr_output,
810 backlight_atom, XA_INTEGER,
811 32, PropModeReplace, 1, &val,
812 TRUE, FALSE);
813 RRChangeOutputProperty(output->randr_output,
814 backlight_deprecated_atom, XA_INTEGER,
815 32, PropModeReplace, 1, &val,
816 TRUE, FALSE);
817 }
818 }
819 DBG(("%s: complete\n", __FUNCTION__));
820 }
821
sna_backlight_pre_init(struct sna * sna)822 static void sna_backlight_pre_init(struct sna *sna)
823 {
824 struct udev *u;
825 struct udev_monitor *mon;
826
827 #if !USE_BACKLIGHT
828 return;
829 #endif
830
831 u = udev_new();
832 if (!u)
833 return;
834
835 mon = udev_monitor_new_from_netlink(u, "udev");
836 if (!mon)
837 goto free_udev;
838
839 if (udev_monitor_filter_add_match_subsystem_devtype(mon, "backlight", NULL))
840 goto free_monitor;
841
842 if (udev_monitor_enable_receiving(mon))
843 goto free_monitor;
844
845 sna->mode.backlight_handler =
846 xf86AddGeneralHandler(udev_monitor_get_fd(mon),
847 sna_backlight_uevent, sna);
848 if (!sna->mode.backlight_handler)
849 goto free_monitor;
850
851 DBG(("%s: installed backlight monitor\n", __FUNCTION__));
852 sna->mode.backlight_monitor = mon;
853
854 return;
855
856 free_monitor:
857 udev_monitor_unref(mon);
858 free_udev:
859 udev_unref(u);
860 }
861
sna_backlight_drain_uevents(struct sna * sna)862 static void sna_backlight_drain_uevents(struct sna *sna)
863 {
864 if (sna->mode.backlight_monitor == NULL)
865 return;
866
867 DBG(("%s()\n", __FUNCTION__));
868 sna_backlight_uevent(udev_monitor_get_fd(sna->mode.backlight_monitor),
869 sna);
870 }
871
sna_backlight_close(struct sna * sna)872 static void sna_backlight_close(struct sna *sna)
873 {
874 struct udev *u;
875
876 if (sna->mode.backlight_handler == NULL)
877 return;
878
879 xf86RemoveGeneralHandler(sna->mode.backlight_handler);
880
881 u = udev_monitor_get_udev(sna->mode.backlight_monitor);
882 udev_monitor_unref(sna->mode.backlight_monitor);
883 udev_unref(u);
884
885 sna->mode.backlight_handler = NULL;
886 sna->mode.backlight_monitor = NULL;
887 }
888 #else
sna_backlight_pre_init(struct sna * sna)889 static void sna_backlight_pre_init(struct sna *sna) { }
sna_backlight_drain_uevents(struct sna * sna)890 static void sna_backlight_drain_uevents(struct sna *sna) { }
sna_backlight_close(struct sna * sna)891 static void sna_backlight_close(struct sna *sna) { }
892 #endif
893
894 static void
sna_output_backlight_disable(struct sna_output * sna_output)895 sna_output_backlight_disable(struct sna_output *sna_output)
896 {
897 xf86OutputPtr output = sna_output->base;
898
899 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
900 "Failed to set backlight %s for output %s, disabling\n",
901 sna_output->backlight.iface, output->name);
902 backlight_disable(&sna_output->backlight);
903 if (output->randr_output) {
904 RRDeleteOutputProperty(output->randr_output, backlight_atom);
905 RRDeleteOutputProperty(output->randr_output, backlight_deprecated_atom);
906 }
907 }
908
909 static int
sna_output_backlight_set(struct sna_output * sna_output,int level)910 sna_output_backlight_set(struct sna_output *sna_output, int level)
911 {
912 int ret = 0;
913
914 DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
915 sna_output->base->name, level, sna_output->backlight.max));
916
917 if (backlight_set(&sna_output->backlight, level)) {
918 sna_output_backlight_disable(sna_output);
919 ret = -1;
920 }
921
922 /* Consume the uevent notification now so that we don't misconstrue
923 * the change latter when we wake up and the output is in a different
924 * state.
925 */
926 sna_backlight_drain_uevents(to_sna(sna_output->base->scrn));
927 return ret;
928 }
929
930 static bool
has_native_backlight(struct sna_output * sna_output)931 has_native_backlight(struct sna_output *sna_output)
932 {
933 return sna_output->backlight.type == BL_RAW;
934 }
935
936 static void
sna_output_backlight_off(struct sna_output * sna_output)937 sna_output_backlight_off(struct sna_output *sna_output)
938 {
939 /* Trust the kernel to turn the native backlight off. However, we
940 * do explicitly turn the backlight back on (when we wake the output)
941 * just in case a third party turns it off!
942 */
943 if (has_native_backlight(sna_output))
944 return;
945
946 DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
947 backlight_off(&sna_output->backlight);
948 sna_output_backlight_set(sna_output, 0);
949 }
950
951 static void
sna_output_backlight_on(struct sna_output * sna_output)952 sna_output_backlight_on(struct sna_output *sna_output)
953 {
954 DBG(("%s(%s)\n", __FUNCTION__, sna_output->base->name));
955 sna_output_backlight_set(sna_output,
956 sna_output->backlight_active_level);
957 if (backlight_on(&sna_output->backlight) < 0)
958 sna_output_backlight_disable(sna_output);
959 }
960
961 static int
sna_output_backlight_get(xf86OutputPtr output)962 sna_output_backlight_get(xf86OutputPtr output)
963 {
964 struct sna_output *sna_output = output->driver_private;
965 int level = backlight_get(&sna_output->backlight);
966 DBG(("%s(%s) level=%d, max=%d\n", __FUNCTION__,
967 output->name, level, sna_output->backlight.max));
968 return level;
969 }
970
971 static char *
has_user_backlight_override(xf86OutputPtr output)972 has_user_backlight_override(xf86OutputPtr output)
973 {
974 struct sna *sna = to_sna(output->scrn);
975 const char *str;
976
977 str = xf86GetOptValString(sna->Options, OPTION_BACKLIGHT);
978 if (str == NULL)
979 return NULL;
980
981 DBG(("%s(%s) requested %s\n", __FUNCTION__, output->name, str));
982 if (*str == '\0')
983 return (char *)str;
984
985 if (!backlight_exists(str)) {
986 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
987 "Unrecognised backlight control interface '%s'\n",
988 str);
989 return NULL;
990 }
991
992 return strdup(str);
993 }
994
get_device_minor(int fd)995 static int get_device_minor(int fd)
996 {
997 struct stat st;
998
999 if (fstat(fd, &st) || !S_ISCHR(st.st_mode))
1000 return -1;
1001
1002 return st.st_rdev & 0x63;
1003 }
1004
1005 static const char * const sysfs_connector_types[] = {
1006 /* DRM_MODE_CONNECTOR_Unknown */ "Unknown",
1007 /* DRM_MODE_CONNECTOR_VGA */ "VGA",
1008 /* DRM_MODE_CONNECTOR_DVII */ "DVI-I",
1009 /* DRM_MODE_CONNECTOR_DVID */ "DVI-D",
1010 /* DRM_MODE_CONNECTOR_DVIA */ "DVI-A",
1011 /* DRM_MODE_CONNECTOR_Composite */ "Composite",
1012 /* DRM_MODE_CONNECTOR_SVIDEO */ "SVIDEO",
1013 /* DRM_MODE_CONNECTOR_LVDS */ "LVDS",
1014 /* DRM_MODE_CONNECTOR_Component */ "Component",
1015 /* DRM_MODE_CONNECTOR_9PinDIN */ "DIN",
1016 /* DRM_MODE_CONNECTOR_DisplayPort */ "DP",
1017 /* DRM_MODE_CONNECTOR_HDMIA */ "HDMI-A",
1018 /* DRM_MODE_CONNECTOR_HDMIB */ "HDMI-B",
1019 /* DRM_MODE_CONNECTOR_TV */ "TV",
1020 /* DRM_MODE_CONNECTOR_eDP */ "eDP",
1021 /* DRM_MODE_CONNECTOR_VIRTUAL */ "Virtual",
1022 /* DRM_MODE_CONNECTOR_DSI */ "DSI",
1023 /* DRM_MODE_CONNECTOR_DPI */ "DPI"
1024 };
1025
has_connector_backlight(xf86OutputPtr output)1026 static char *has_connector_backlight(xf86OutputPtr output)
1027 {
1028 struct sna_output *sna_output = output->driver_private;
1029 struct sna *sna = to_sna(output->scrn);
1030 char path[1024];
1031 DIR *dir;
1032 struct dirent *de;
1033 int minor, len;
1034 char *str = NULL;
1035
1036 if (sna_output->connector_type >= ARRAY_SIZE(sysfs_connector_types))
1037 return NULL;
1038
1039 minor = get_device_minor(sna->kgem.fd);
1040 if (minor < 0)
1041 return NULL;
1042
1043 len = snprintf(path, sizeof(path),
1044 "/sys/class/drm/card%d-%s-%d",
1045 minor,
1046 sysfs_connector_types[sna_output->connector_type],
1047 sna_output->connector_type_id);
1048 DBG(("%s: lookup %s\n", __FUNCTION__, path));
1049
1050 dir = opendir(path);
1051 if (dir == NULL)
1052 return NULL;
1053
1054 while ((de = readdir(dir))) {
1055 struct stat st;
1056
1057 if (*de->d_name == '.')
1058 continue;
1059
1060 snprintf(path + len, sizeof(path) - len,
1061 "/%s", de->d_name);
1062
1063 if (stat(path, &st))
1064 continue;
1065
1066 if (!S_ISDIR(st.st_mode))
1067 continue;
1068
1069 DBG(("%s: testing %s as backlight\n",
1070 __FUNCTION__, de->d_name));
1071
1072 if (backlight_exists(de->d_name)) {
1073 str = strdup(de->d_name); /* leak! */
1074 break;
1075 }
1076 }
1077
1078 closedir(dir);
1079 return str;
1080 }
1081
1082 static void
sna_output_backlight_init(xf86OutputPtr output)1083 sna_output_backlight_init(xf86OutputPtr output)
1084 {
1085 struct sna_output *sna_output = output->driver_private;
1086 struct pci_device *pci;
1087 MessageType from;
1088 char *best_iface;
1089
1090 #if !USE_BACKLIGHT
1091 return;
1092 #endif
1093
1094 if (sna_output->is_panel) {
1095 from = X_CONFIG;
1096 best_iface = has_user_backlight_override(output);
1097 if (best_iface)
1098 goto done;
1099 }
1100
1101 best_iface = has_connector_backlight(output);
1102 if (best_iface)
1103 goto done;
1104
1105 if (!sna_output->is_panel)
1106 return;
1107
1108 /* XXX detect right backlight for multi-GPU/panels */
1109 from = X_PROBED;
1110 pci = xf86GetPciInfoForEntity(to_sna(output->scrn)->pEnt->index);
1111 if (pci != NULL)
1112 best_iface = backlight_find_for_device(pci);
1113
1114 done:
1115 DBG(("%s(%s) opening backlight %s\n", __FUNCTION__,
1116 output->name, best_iface ?: "none"));
1117 sna_output->backlight_active_level =
1118 backlight_open(&sna_output->backlight, best_iface);
1119 DBG(("%s(%s): initial backlight value %d\n",
1120 __FUNCTION__, output->name, sna_output->backlight_active_level));
1121 if (sna_output->backlight_active_level < 0)
1122 return;
1123
1124 switch (sna_output->backlight.type) {
1125 case BL_FIRMWARE: best_iface = (char *)"firmware"; break;
1126 case BL_PLATFORM: best_iface = (char *)"platform"; break;
1127 case BL_RAW: best_iface = (char *)"raw"; break;
1128 default: best_iface = (char *)"unknown"; break;
1129 }
1130 xf86DrvMsg(output->scrn->scrnIndex, from,
1131 "Found backlight control interface %s (type '%s') for output %s\n",
1132 sna_output->backlight.iface, best_iface, output->name);
1133 }
1134
1135 #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(22, 0)
sigio_block(void)1136 static inline int sigio_block(void)
1137 {
1138 return 0;
1139 }
sigio_unblock(int was_blocked)1140 static inline void sigio_unblock(int was_blocked)
1141 {
1142 (void)was_blocked;
1143 }
1144 #elif XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,12,99,901,0)
sigio_block(void)1145 static inline int sigio_block(void)
1146 {
1147 OsBlockSIGIO();
1148 return 0;
1149 }
sigio_unblock(int was_blocked)1150 static inline void sigio_unblock(int was_blocked)
1151 {
1152 OsReleaseSIGIO();
1153 (void)was_blocked;
1154 }
1155 #else
1156 #include <xf86_OSproc.h>
sigio_block(void)1157 static inline int sigio_block(void)
1158 {
1159 return xf86BlockSIGIO();
1160 }
sigio_unblock(int was_blocked)1161 static inline void sigio_unblock(int was_blocked)
1162 {
1163 xf86UnblockSIGIO(was_blocked);
1164 }
1165 #endif
1166
canonical_kmode_name(const struct drm_mode_modeinfo * kmode)1167 static char *canonical_kmode_name(const struct drm_mode_modeinfo *kmode)
1168 {
1169 char tmp[32], *buf;
1170 int len;
1171
1172 len = sprintf(tmp, "%dx%d%s",
1173 kmode->hdisplay, kmode->vdisplay,
1174 kmode->flags & V_INTERLACE ? "i" : "");
1175 if ((unsigned)len >= sizeof(tmp))
1176 return NULL;
1177
1178 buf = malloc(len + 1);
1179 if (buf == NULL)
1180 return NULL;
1181
1182 return memcpy(buf, tmp, len + 1);
1183 }
1184
get_kmode_name(const struct drm_mode_modeinfo * kmode)1185 static char *get_kmode_name(const struct drm_mode_modeinfo *kmode)
1186 {
1187 if (*kmode->name == '\0')
1188 return canonical_kmode_name(kmode);
1189
1190 return strdup(kmode->name);
1191 }
1192
1193 static DisplayModePtr
mode_from_kmode(ScrnInfoPtr scrn,const struct drm_mode_modeinfo * kmode,DisplayModePtr mode)1194 mode_from_kmode(ScrnInfoPtr scrn,
1195 const struct drm_mode_modeinfo *kmode,
1196 DisplayModePtr mode)
1197 {
1198 DBG(("kmode: %s, clock=%d, %d %d %d %d %d, %d %d %d %d %d, flags=%x, type=%x\n",
1199 kmode->name, kmode->clock,
1200 kmode->hdisplay, kmode->hsync_start, kmode->hsync_end, kmode->htotal, kmode->hskew,
1201 kmode->vdisplay, kmode->vsync_start, kmode->vsync_end, kmode->vtotal, kmode->vscan,
1202 kmode->flags, kmode->type));
1203
1204 mode->status = MODE_OK;
1205
1206 mode->Clock = kmode->clock;
1207
1208 mode->HDisplay = kmode->hdisplay;
1209 mode->HSyncStart = kmode->hsync_start;
1210 mode->HSyncEnd = kmode->hsync_end;
1211 mode->HTotal = kmode->htotal;
1212 mode->HSkew = kmode->hskew;
1213
1214 mode->VDisplay = kmode->vdisplay;
1215 mode->VSyncStart = kmode->vsync_start;
1216 mode->VSyncEnd = kmode->vsync_end;
1217 mode->VTotal = kmode->vtotal;
1218 mode->VScan = kmode->vscan;
1219
1220 mode->VRefresh = kmode->vrefresh;
1221 mode->Flags = kmode->flags;
1222 mode->name = get_kmode_name(kmode);
1223
1224 if (kmode->type & DRM_MODE_TYPE_DRIVER)
1225 mode->type = M_T_DRIVER;
1226 if (kmode->type & DRM_MODE_TYPE_PREFERRED)
1227 mode->type |= M_T_PREFERRED;
1228
1229 if (mode->status == MODE_OK && kmode->flags & ~KNOWN_MODE_FLAGS)
1230 mode->status = MODE_BAD; /* unknown flags => unhandled */
1231
1232 xf86SetModeCrtc(mode, scrn->adjustFlags);
1233 return mode;
1234 }
1235
1236 static void
mode_to_kmode(struct drm_mode_modeinfo * kmode,DisplayModePtr mode)1237 mode_to_kmode(struct drm_mode_modeinfo *kmode, DisplayModePtr mode)
1238 {
1239 memset(kmode, 0, sizeof(*kmode));
1240
1241 kmode->clock = mode->Clock;
1242 kmode->hdisplay = mode->HDisplay;
1243 kmode->hsync_start = mode->HSyncStart;
1244 kmode->hsync_end = mode->HSyncEnd;
1245 kmode->htotal = mode->HTotal;
1246 kmode->hskew = mode->HSkew;
1247
1248 kmode->vdisplay = mode->VDisplay;
1249 kmode->vsync_start = mode->VSyncStart;
1250 kmode->vsync_end = mode->VSyncEnd;
1251 kmode->vtotal = mode->VTotal;
1252 kmode->vscan = mode->VScan;
1253
1254 kmode->vrefresh = mode->VRefresh;
1255 kmode->flags = mode->Flags;
1256 if (mode->name)
1257 strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
1258 kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
1259 }
1260
1261 static void
sna_crtc_force_outputs_on(xf86CrtcPtr crtc)1262 sna_crtc_force_outputs_on(xf86CrtcPtr crtc)
1263 {
1264 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1265 /* All attached outputs are valid, so update our timestamps */
1266 unsigned now = GetTimeInMillis();
1267 int i;
1268
1269 assert(to_sna_crtc(crtc));
1270 DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc)));
1271
1272 /* DPMS handling by the kernel is inconsistent, so after setting a
1273 * mode on an output presume that we intend for it to be on, or that
1274 * the kernel will force it on.
1275 *
1276 * So force DPMS to be on for all connected outputs, and restore
1277 * the backlight.
1278 */
1279 for (i = 0; i < config->num_output; i++) {
1280 xf86OutputPtr output = config->output[i];
1281
1282 if (output->crtc != crtc)
1283 continue;
1284
1285 __sna_output_dpms(output, DPMSModeOn, false);
1286 if (to_sna_output(output)->last_detect)
1287 to_sna_output(output)->last_detect = now;
1288 }
1289
1290 #if XF86_CRTC_VERSION >= 3
1291 crtc->active = TRUE;
1292 #endif
1293 }
1294
1295 static void
sna_crtc_force_outputs_off(xf86CrtcPtr crtc)1296 sna_crtc_force_outputs_off(xf86CrtcPtr crtc)
1297 {
1298 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1299 int i;
1300
1301 assert(to_sna_crtc(crtc));
1302 DBG(("%s(pipe=%d)\n", __FUNCTION__, sna_crtc_pipe(crtc)));
1303
1304 /* DPMS handling by the kernel is inconsistent, so after setting a
1305 * mode on an output presume that we intend for it to be on, or that
1306 * the kernel will force it on.
1307 *
1308 * So force DPMS to be on for all connected outputs, and restore
1309 * the backlight.
1310 */
1311 for (i = 0; i < config->num_output; i++) {
1312 xf86OutputPtr output = config->output[i];
1313
1314 if (output->crtc != crtc)
1315 continue;
1316
1317 __sna_output_dpms(output, DPMSModeOff, false);
1318 }
1319 }
1320
1321 static unsigned
rotation_reflect(unsigned rotation)1322 rotation_reflect(unsigned rotation)
1323 {
1324 unsigned other_bits;
1325
1326 /* paranoia for future extensions */
1327 other_bits = rotation & ~RR_Rotate_All;
1328
1329 /* flip the reflection to compensate for reflecting the rotation */
1330 other_bits ^= RR_Reflect_X | RR_Reflect_Y;
1331
1332 /* Reflect the screen by rotating the rotation bit,
1333 * which has to have at least RR_Rotate_0 set. This allows
1334 * us to reflect any of the rotation bits, not just 0.
1335 */
1336 rotation &= RR_Rotate_All;
1337 assert(rotation);
1338 rotation <<= 2; /* RR_Rotate_0 -> RR_Rotate_180 etc */
1339 rotation |= rotation >> 4; /* RR_Rotate_270' to RR_Rotate_90 */
1340 rotation &= RR_Rotate_All;
1341 assert(rotation);
1342
1343 return rotation | other_bits;
1344 }
1345
1346 static unsigned
rotation_reduce(struct plane * p,unsigned rotation)1347 rotation_reduce(struct plane *p, unsigned rotation)
1348 {
1349 /* If unsupported try exchanging rotation for a reflection */
1350 if (rotation & ~p->rotation.supported) {
1351 unsigned new_rotation = rotation_reflect(rotation);
1352 if ((new_rotation & p->rotation.supported) == new_rotation)
1353 rotation = new_rotation;
1354 }
1355
1356 /* Only one rotation bit should be set */
1357 assert(is_power_of_two(rotation & RR_Rotate_All));
1358
1359 return rotation;
1360 }
1361
1362 static bool
rotation_set(struct sna * sna,struct plane * p,uint32_t desired)1363 rotation_set(struct sna *sna, struct plane *p, uint32_t desired)
1364 {
1365 #define LOCAL_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xbA, struct local_mode_obj_set_property)
1366 struct local_mode_obj_set_property {
1367 uint64_t value;
1368 uint32_t prop_id;
1369 uint32_t obj_id;
1370 uint32_t obj_type;
1371 uint32_t pad;
1372 } prop;
1373
1374 if (desired == p->rotation.current)
1375 return true;
1376
1377 if ((desired & p->rotation.supported) != desired) {
1378 errno = EINVAL;
1379 return false;
1380 }
1381
1382 DBG(("%s: obj=%d, type=%x prop=%d set-rotation=%x\n",
1383 __FUNCTION__, p->id, LOCAL_MODE_OBJECT_PLANE, p->rotation.prop, desired));
1384
1385 assert(p->id);
1386 assert(p->rotation.prop);
1387
1388 VG_CLEAR(prop);
1389 prop.obj_id = p->id;
1390 prop.obj_type = LOCAL_MODE_OBJECT_PLANE;
1391 prop.prop_id = p->rotation.prop;
1392 prop.value = desired;
1393
1394 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_SETPROPERTY, &prop))
1395 return false;
1396
1397 p->rotation.current = desired;
1398 return true;
1399 }
1400
1401 static void
rotation_reset(struct plane * p)1402 rotation_reset(struct plane *p)
1403 {
1404 if (p->rotation.prop == 0)
1405 return;
1406
1407 p->rotation.current = 0;
1408 }
1409
sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,unsigned idx,uint32_t rotation)1410 bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc,
1411 unsigned idx,
1412 uint32_t rotation)
1413 {
1414 struct plane *sprite;
1415 assert(to_sna_crtc(crtc));
1416
1417 sprite = lookup_sprite(to_sna_crtc(crtc), idx);
1418 if (!sprite)
1419 return false;
1420
1421 DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n",
1422 __FUNCTION__,
1423 sna_crtc_id(crtc), sna_crtc_pipe(crtc),
1424 sprite->id, rotation));
1425
1426 return rotation_set(to_sna(crtc->scrn), sprite,
1427 rotation_reduce(sprite, rotation));
1428 }
1429
1430 #if HAS_DEBUG_FULL
1431 #if !HAS_DEBUG_FULL
1432 #define LogF ErrorF
1433 #endif
1434 struct kmsg {
1435 int fd;
1436 int saved_loglevel;
1437 };
1438
kmsg_get_debug(void)1439 static int kmsg_get_debug(void)
1440 {
1441 int v = -1;
1442 int fd;
1443
1444 fd = open("/sys/module/drm/parameters/debug", O_RDONLY);
1445 if (fd != -1) {
1446 char buf[128];
1447 int len;
1448
1449 len = read(fd, buf, sizeof(buf) - 1);
1450 if (len != -1) {
1451 buf[len] = '\0';
1452 v = atoi(buf);
1453 }
1454 close(fd);
1455 }
1456
1457 return v;
1458 }
1459
kmsg_set_debug(int v)1460 static void kmsg_set_debug(int v)
1461 {
1462 char buf[128];
1463 int len;
1464 int fd;
1465
1466 len = snprintf(buf, sizeof(buf), "%d\n", v);
1467
1468 fd = open("/sys/module/drm/parameters/debug", O_WRONLY);
1469 if (fd != -1) {
1470 write(fd, buf, len);
1471 close(fd);
1472 }
1473 }
1474
kmsg_open(struct kmsg * k)1475 static void kmsg_open(struct kmsg *k)
1476 {
1477 k->saved_loglevel = kmsg_get_debug();
1478 if (k->saved_loglevel != -1)
1479 kmsg_set_debug(0xff);
1480
1481 k->fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
1482 if (k->fd != -1)
1483 lseek(k->fd, 0, SEEK_END);
1484 }
1485
kmsg_close(struct kmsg * k,int dump)1486 static void kmsg_close(struct kmsg *k, int dump)
1487 {
1488 FILE *file;
1489
1490 file = NULL;
1491 if (k->fd != -1 && dump)
1492 file = fdopen(k->fd, "r");
1493 if (file) {
1494 size_t len = 0;
1495 char *line = NULL;
1496
1497 while (getline(&line, &len, file) != -1) {
1498 char *start = strchr(line, ';');
1499 if (start)
1500 LogF("KMSG: %s", start + 1);
1501 }
1502
1503 free(line);
1504 fclose(file);
1505 }
1506
1507 if (k->fd != -1)
1508 close(k->fd);
1509
1510 if (k->saved_loglevel != -1)
1511 kmsg_set_debug(k->saved_loglevel);
1512 }
1513 #else
1514 struct kmsg { int unused; };
kmsg_open(struct kmsg * k)1515 static void kmsg_open(struct kmsg *k) {}
kmsg_close(struct kmsg * k,int dump)1516 static void kmsg_close(struct kmsg *k, int dump) {}
1517 #endif
1518
1519 static int
sna_crtc_apply(xf86CrtcPtr crtc)1520 sna_crtc_apply(xf86CrtcPtr crtc)
1521 {
1522 struct sna *sna = to_sna(crtc->scrn);
1523 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
1524 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
1525 struct drm_mode_crtc arg;
1526 uint32_t output_ids[32];
1527 int output_count = 0;
1528 int sigio, i;
1529 struct kmsg kmsg;
1530 int ret = EINVAL;
1531
1532 DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__,
1533 __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1534 sna_crtc->bo->handle));
1535 if (!sna_crtc->kmode.clock) {
1536 ERR(("%s(CRTC:%d [pipe=%d]): attempted to set an invalid mode\n",
1537 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc)));
1538 return EINVAL;
1539 }
1540
1541 kmsg_open(&kmsg);
1542 sigio = sigio_block();
1543
1544 assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
1545 sna_crtc_disable_cursor(sna, sna_crtc);
1546
1547 if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
1548 memset(&arg, 0, sizeof(arg));
1549 arg.crtc_id = __sna_crtc_id(sna_crtc);
1550 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
1551 }
1552
1553 if (!rotation_set(sna, &sna_crtc->primary, sna_crtc->rotation)) {
1554 ERR(("%s: set-primary-rotation failed (rotation-id=%d, rotation=%d) on CRTC:%d [pipe=%d], errno=%d\n",
1555 __FUNCTION__, sna_crtc->primary.rotation.prop, sna_crtc->rotation, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno));
1556 sna_crtc->primary.rotation.supported &= ~sna_crtc->rotation;
1557 goto unblock;
1558 }
1559 DBG(("%s: CRTC:%d [pipe=%d] primary rotation set to %x\n",
1560 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna_crtc->rotation));
1561
1562 for (i = 0; i < sna->mode.num_real_output; i++) {
1563 xf86OutputPtr output = config->output[i];
1564
1565 /* Make sure we mark the output as off (and save the backlight)
1566 * before the kernel turns it off due to changing the pipe.
1567 * This is necessary as the kernel may turn off the backlight
1568 * and we lose track of the user settings.
1569 */
1570 if (output->crtc == NULL)
1571 __sna_output_dpms(output, DPMSModeOff, false);
1572
1573 if (output->crtc != crtc)
1574 continue;
1575
1576 /* Skip over any hotunplugged outputs so that we can
1577 * recover in cases where the previous mode is now
1578 * only partially valid.
1579 */
1580 if (!to_sna_output(output)->id)
1581 continue;
1582
1583 DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
1584 __FUNCTION__, output->name, i, to_connector_id(output),
1585 __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1586 (uint32_t)output->possible_crtcs,
1587 (uint32_t)output->possible_clones));
1588
1589 assert(output->possible_crtcs & (1 << __sna_crtc_pipe(sna_crtc)) ||
1590 is_zaphod(crtc->scrn));
1591
1592 output_ids[output_count] = to_connector_id(output);
1593 if (++output_count == ARRAY_SIZE(output_ids)) {
1594 DBG(("%s: too many outputs (%d) for me!\n",
1595 __FUNCTION__, output_count));
1596 goto unblock;
1597 }
1598 }
1599 if (output_count == 0) {
1600 DBG(("%s: no outputs\n", __FUNCTION__));
1601 goto unblock;
1602 }
1603
1604 VG_CLEAR(arg);
1605 arg.crtc_id = __sna_crtc_id(sna_crtc);
1606 arg.fb_id = fb_id(sna_crtc->bo);
1607 if (sna_crtc->transform || sna_crtc->slave_pixmap) {
1608 arg.x = 0;
1609 arg.y = 0;
1610 sna_crtc->offset = 0;
1611 } else {
1612 arg.x = crtc->x;
1613 arg.y = crtc->y;
1614 sna_crtc->offset = arg.y << 16 | arg.x;
1615 }
1616 arg.set_connectors_ptr = (uintptr_t)output_ids;
1617 arg.count_connectors = output_count;
1618 arg.mode = sna_crtc->kmode;
1619 arg.mode_valid = 1;
1620
1621 DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d%s%s update to %d outputs [%d...]\n",
1622 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
1623 arg.mode.hdisplay,
1624 arg.mode.vdisplay,
1625 arg.x, arg.y,
1626 arg.mode.clock,
1627 arg.fb_id,
1628 sna_crtc->shadow ? " [shadow]" : "",
1629 sna_crtc->transform ? " [transformed]" : "",
1630 output_count, output_count ? output_ids[0] : 0));
1631
1632 ret = 0;
1633 if (unlikely(drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))) {
1634 ret = errno;
1635 goto unblock;
1636 }
1637
1638 sna_crtc->mode_serial++;
1639 sna_crtc_force_outputs_on(crtc);
1640
1641 unblock:
1642 sigio_unblock(sigio);
1643 kmsg_close(&kmsg, ret);
1644 return ret;
1645 }
1646
overlap(const BoxRec * a,const BoxRec * b)1647 static bool overlap(const BoxRec *a, const BoxRec *b)
1648 {
1649 if (a->x1 >= b->x2)
1650 return false;
1651 if (a->x2 <= b->x1)
1652 return false;
1653
1654 if (a->y1 >= b->y2)
1655 return false;
1656 if (a->y2 <= b->y1)
1657 return false;
1658
1659 return true;
1660 }
1661
defer_event(struct sna * sna,struct drm_event * base)1662 static void defer_event(struct sna *sna, struct drm_event *base)
1663 {
1664 if (sna->mode.shadow_nevent == sna->mode.shadow_size) {
1665 int size = sna->mode.shadow_size * 2;
1666 void *ptr;
1667
1668 ptr = realloc(sna->mode.shadow_events,
1669 sizeof(struct drm_event_vblank)*size);
1670 if (!ptr)
1671 return;
1672
1673 sna->mode.shadow_events = ptr;
1674 sna->mode.shadow_size = size;
1675 }
1676
1677 memcpy(&sna->mode.shadow_events[sna->mode.shadow_nevent++],
1678 base, sizeof(struct drm_event_vblank));
1679 DBG(("%s: deferring event count=%d\n",
1680 __func__, sna->mode.shadow_nevent));
1681 }
1682
flush_events(struct sna * sna)1683 static void flush_events(struct sna *sna)
1684 {
1685 int n;
1686
1687 if (!sna->mode.shadow_nevent)
1688 return;
1689
1690 DBG(("%s: flushing %d events=%d\n", __func__, sna->mode.shadow_nevent));
1691
1692 for (n = 0; n < sna->mode.shadow_nevent; n++) {
1693 struct drm_event_vblank *vb = &sna->mode.shadow_events[n];
1694
1695 if ((uintptr_t)(vb->user_data) & 2)
1696 sna_present_vblank_handler(vb);
1697 else
1698 sna_dri2_vblank_handler(vb);
1699 }
1700
1701 sna->mode.shadow_nevent = 0;
1702 }
1703
1704
wait_for_shadow(struct sna * sna,struct sna_pixmap * priv,unsigned flags)1705 static bool wait_for_shadow(struct sna *sna,
1706 struct sna_pixmap *priv,
1707 unsigned flags)
1708 {
1709 PixmapPtr pixmap = priv->pixmap;
1710 struct kgem_bo *bo, *tmp;
1711 int flip_active;
1712 bool ret = true;
1713
1714 DBG(("%s: enabled? %d flags=%x, flips=%d, pixmap=%ld [front?=%d], handle=%d, shadow=%d\n",
1715 __FUNCTION__, sna->mode.shadow_enabled,
1716 flags, sna->mode.flip_active,
1717 pixmap->drawable.serialNumber, pixmap == sna->front,
1718 priv->gpu_bo->handle, sna->mode.shadow->handle));
1719
1720 assert(priv->move_to_gpu_data == sna);
1721 assert(sna->mode.shadow != priv->gpu_bo);
1722
1723 if (flags == 0 || pixmap != sna->front || !sna->mode.shadow_enabled)
1724 goto done;
1725
1726 assert(sna->mode.shadow_damage);
1727
1728 if ((flags & MOVE_WRITE) == 0) {
1729 if ((flags & __MOVE_SCANOUT) == 0) {
1730 struct sna_crtc *crtc;
1731
1732 list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link) {
1733 if (overlap(&sna->mode.shadow_region.extents,
1734 &crtc->base->bounds)) {
1735 DrawableRec draw;
1736 RegionRec region;
1737
1738 draw.width = crtc->base->mode.HDisplay;
1739 draw.height = crtc->base->mode.VDisplay;
1740 draw.depth = sna->front->drawable.depth;
1741 draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1742
1743 DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1744 __FUNCTION__,
1745 crtc->base->bounds.x1,
1746 crtc->base->bounds.y1,
1747 crtc->base->bounds.x2,
1748 crtc->base->bounds.y2,
1749 crtc->client_bo->handle));
1750
1751 ret &= sna->render.copy_boxes(sna, GXcopy,
1752 &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1753 &pixmap->drawable, priv->gpu_bo, 0, 0,
1754 &crtc->base->bounds, 1,
1755 0);
1756
1757 region.extents = crtc->base->bounds;
1758 region.data = NULL;
1759 RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion);
1760 }
1761 }
1762 }
1763
1764 return ret;
1765 }
1766
1767 assert(sna->mode.shadow_active);
1768
1769 flip_active = sna->mode.flip_active;
1770 if (flip_active) {
1771 struct sna_crtc *crtc;
1772 list_for_each_entry(crtc, &sna->mode.shadow_crtc, shadow_link)
1773 flip_active -= crtc->flip_pending;
1774 DBG(("%s: %d flips still pending, shadow flip_active=%d\n",
1775 __FUNCTION__, sna->mode.flip_active, flip_active));
1776 }
1777
1778 bo = sna->mode.shadow;
1779 if (flip_active) {
1780 bo = kgem_create_2d(&sna->kgem,
1781 pixmap->drawable.width,
1782 pixmap->drawable.height,
1783 pixmap->drawable.bitsPerPixel,
1784 priv->gpu_bo->tiling,
1785 CREATE_EXACT | CREATE_SCANOUT);
1786 if (bo == NULL)
1787 return false;
1788
1789 DBG(("%s: replacing still-attached GPU bo handle=%d, flips=%d\n",
1790 __FUNCTION__, priv->gpu_bo->tiling, sna->mode.flip_active));
1791
1792 RegionUninit(&sna->mode.shadow_region);
1793 sna->mode.shadow_region.extents.x1 = 0;
1794 sna->mode.shadow_region.extents.y1 = 0;
1795 sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1796 sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1797 sna->mode.shadow_region.data = NULL;
1798 }
1799
1800 if (bo->refcnt > 1) {
1801 bo = kgem_create_2d(&sna->kgem,
1802 pixmap->drawable.width,
1803 pixmap->drawable.height,
1804 pixmap->drawable.bitsPerPixel,
1805 priv->gpu_bo->tiling,
1806 CREATE_EXACT | CREATE_SCANOUT);
1807 if (bo != NULL) {
1808 DBG(("%s: replacing exported GPU bo\n",
1809 __FUNCTION__));
1810
1811 RegionUninit(&sna->mode.shadow_region);
1812 sna->mode.shadow_region.extents.x1 = 0;
1813 sna->mode.shadow_region.extents.y1 = 0;
1814 sna->mode.shadow_region.extents.x2 = pixmap->drawable.width;
1815 sna->mode.shadow_region.extents.y2 = pixmap->drawable.height;
1816 sna->mode.shadow_region.data = NULL;
1817 } else
1818 bo = sna->mode.shadow;
1819 }
1820
1821 RegionSubtract(&sna->mode.shadow_region,
1822 &sna->mode.shadow_region,
1823 &sna->mode.shadow_cancel);
1824
1825 while (!list_is_empty(&sna->mode.shadow_crtc)) {
1826 struct sna_crtc *crtc =
1827 list_first_entry(&sna->mode.shadow_crtc, struct sna_crtc, shadow_link);
1828 if (overlap(&crtc->base->bounds,
1829 &sna->mode.shadow_region.extents)) {
1830 RegionRec region;
1831 DrawableRec draw;
1832
1833 draw.width = crtc->base->mode.HDisplay;
1834 draw.height = crtc->base->mode.VDisplay;
1835 draw.depth = sna->front->drawable.depth;
1836 draw.bitsPerPixel = sna->front->drawable.bitsPerPixel;
1837
1838 DBG(("%s: copying replaced CRTC: (%d, %d), (%d, %d), handle=%d\n",
1839 __FUNCTION__,
1840 crtc->base->bounds.x1,
1841 crtc->base->bounds.y1,
1842 crtc->base->bounds.x2,
1843 crtc->base->bounds.y2,
1844 crtc->client_bo->handle));
1845
1846 ret = sna->render.copy_boxes(sna, GXcopy,
1847 &draw, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
1848 &pixmap->drawable, bo, 0, 0,
1849 &crtc->base->bounds, 1,
1850 0);
1851
1852
1853 region.extents = crtc->base->bounds;
1854 region.data = NULL;
1855 RegionSubtract(&sna->mode.shadow_region, &sna->mode.shadow_region, ®ion);
1856 }
1857
1858 crtc->client_bo->active_scanout--;
1859 kgem_bo_destroy(&sna->kgem, crtc->client_bo);
1860 crtc->client_bo = NULL;
1861 list_del(&crtc->shadow_link);
1862 }
1863
1864 if (RegionNotEmpty(&sna->mode.shadow_region)) {
1865 DBG(("%s: copying existing GPU damage: %dx(%d, %d), (%d, %d)\n",
1866 __FUNCTION__, region_num_rects(&sna->mode.shadow_region),
1867 sna->mode.shadow_region.extents.x1,
1868 sna->mode.shadow_region.extents.y1,
1869 sna->mode.shadow_region.extents.x2,
1870 sna->mode.shadow_region.extents.y2));
1871 if (!sna->render.copy_boxes(sna, GXcopy,
1872 &pixmap->drawable, priv->gpu_bo, 0, 0,
1873 &pixmap->drawable, bo, 0, 0,
1874 region_rects(&sna->mode.shadow_region),
1875 region_num_rects(&sna->mode.shadow_region),
1876 0))
1877 ERR(("%s: copy failed\n", __FUNCTION__));
1878 }
1879
1880 if (priv->cow)
1881 sna_pixmap_undo_cow(sna, priv, 0);
1882
1883 sna_pixmap_unmap(pixmap, priv);
1884
1885 DBG(("%s: setting front pixmap to handle=%d\n", __FUNCTION__, bo->handle));
1886 assert(sna->mode.shadow->active_scanout);
1887 sna->mode.shadow->active_scanout--;
1888 tmp = priv->gpu_bo;
1889 priv->gpu_bo = bo;
1890 if (bo != sna->mode.shadow)
1891 kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
1892 sna->mode.shadow = tmp;
1893 sna->mode.shadow->active_scanout++;
1894 assert(sna->mode.shadow->active_scanout);
1895
1896 sna_dri2_pixmap_update_bo(sna, pixmap, bo);
1897
1898 done:
1899 RegionEmpty(&sna->mode.shadow_cancel);
1900 RegionEmpty(&sna->mode.shadow_region);
1901 sna->mode.shadow_dirty = false;
1902
1903 priv->move_to_gpu_data = NULL;
1904 priv->move_to_gpu = NULL;
1905
1906 assert(sna->mode.shadow->active_scanout);
1907 return ret;
1908 }
1909
sna_pixmap_discard_shadow_damage(struct sna_pixmap * priv,const RegionRec * region)1910 bool sna_pixmap_discard_shadow_damage(struct sna_pixmap *priv,
1911 const RegionRec *region)
1912 {
1913 struct sna *sna;
1914
1915 if (priv->move_to_gpu != wait_for_shadow)
1916 return false;
1917
1918 sna = priv->move_to_gpu_data;
1919 if (region) {
1920 DBG(("%s: discarding region %dx[(%d, %d), (%d, %d)] from damage %dx[(%d, %d], (%d, %d)]\n",
1921 __FUNCTION__,
1922 region_num_rects(region),
1923 region->extents.x1, region->extents.y1,
1924 region->extents.x2, region->extents.y2,
1925 region_num_rects(&sna->mode.shadow_region),
1926 sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1927 sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1928
1929 RegionSubtract(&sna->mode.shadow_region,
1930 &sna->mode.shadow_region,
1931 (RegionPtr)region);
1932 RegionUnion(&sna->mode.shadow_cancel,
1933 &sna->mode.shadow_cancel,
1934 (RegionPtr)region);
1935 } else {
1936 DBG(("%s: discarding all damage %dx[(%d, %d], (%d, %d)]\n",
1937 __FUNCTION__,
1938 region_num_rects(&sna->mode.shadow_region),
1939 sna->mode.shadow_region.extents.x1, sna->mode.shadow_region.extents.y1,
1940 sna->mode.shadow_region.extents.x2, sna->mode.shadow_region.extents.y2));
1941 RegionEmpty(&sna->mode.shadow_region);
1942
1943 RegionUninit(&sna->mode.shadow_cancel);
1944 sna->mode.shadow_cancel.extents.x1 = 0;
1945 sna->mode.shadow_cancel.extents.y1 = 0;
1946 sna->mode.shadow_cancel.extents.x2 = sna->front->drawable.width;
1947 sna->mode.shadow_cancel.extents.y2 = sna->front->drawable.height;
1948 sna->mode.shadow_cancel.data = NULL;
1949 }
1950
1951 return RegionNil(&sna->mode.shadow_region);
1952 }
1953
sna_mode_damage(DamagePtr damage,RegionPtr region,void * closure)1954 static void sna_mode_damage(DamagePtr damage, RegionPtr region, void *closure)
1955 {
1956 struct sna *sna = closure;
1957
1958 if (sna->mode.rr_active)
1959 return;
1960
1961 /* Throw away the rectangles if the region grows too big */
1962 region = DamageRegion(damage);
1963 if (region->data) {
1964 RegionRec dup;
1965
1966 dup = *region;
1967 RegionUninit(&dup);
1968
1969 region->data = NULL;
1970 }
1971 }
1972
sna_mode_enable_shadow(struct sna * sna)1973 static bool sna_mode_enable_shadow(struct sna *sna)
1974 {
1975 ScreenPtr screen = to_screen_from_sna(sna);
1976
1977 DBG(("%s\n", __FUNCTION__));
1978 assert(sna->mode.shadow == NULL);
1979 assert(sna->mode.shadow_damage == NULL);
1980 assert(sna->mode.shadow_active == 0);
1981 assert(!sna->mode.shadow_enabled);
1982
1983 sna->mode.shadow_damage = DamageCreate(sna_mode_damage, NULL,
1984 DamageReportRawRegion,
1985 TRUE, screen, sna);
1986 if (!sna->mode.shadow_damage)
1987 return false;
1988
1989 DamageRegister(&sna->front->drawable, sna->mode.shadow_damage);
1990 sna->mode.shadow_enabled = true;
1991 return true;
1992 }
1993
sna_mode_disable_shadow(struct sna * sna)1994 static void sna_mode_disable_shadow(struct sna *sna)
1995 {
1996 struct sna_pixmap *priv;
1997
1998 if (!sna->mode.shadow_damage) {
1999 assert(!sna->mode.shadow_enabled);
2000 return;
2001 }
2002
2003 DBG(("%s\n", __FUNCTION__));
2004
2005 priv = sna_pixmap(sna->front);
2006 if (priv->move_to_gpu == wait_for_shadow)
2007 priv->move_to_gpu(sna, priv, 0);
2008
2009 DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage);
2010 DamageDestroy(sna->mode.shadow_damage);
2011 sna->mode.shadow_damage = NULL;
2012 sna->mode.shadow_enabled = false;
2013
2014 if (sna->mode.shadow) {
2015 sna->mode.shadow->active_scanout--;
2016 kgem_bo_destroy(&sna->kgem, sna->mode.shadow);
2017 sna->mode.shadow = NULL;
2018 }
2019
2020 assert(sna->mode.shadow_active == 0);
2021 sna->mode.shadow_dirty = false;
2022 }
2023
sna_crtc_slave_damage(DamagePtr damage,RegionPtr region,void * closure)2024 static void sna_crtc_slave_damage(DamagePtr damage, RegionPtr region, void *closure)
2025 {
2026 struct sna_crtc *crtc = closure;
2027 struct sna *sna = to_sna(crtc->base->scrn);
2028 RegionPtr scr;
2029
2030 DBG(("%s: pushing damage [(%d, %d), (%d, %d) x %d] to CRTC [pipe=%d] (%d, %d)\n",
2031 __FUNCTION__,
2032 region->extents.x1, region->extents.y1, region->extents.x2, region->extents.y2,
2033 region_num_rects(region),
2034 __sna_crtc_pipe(crtc), crtc->base->x, crtc->base->y));
2035
2036 assert(crtc->slave_damage == damage);
2037 assert(sna->mode.shadow_damage);
2038
2039 RegionTranslate(region, crtc->base->x, crtc->base->y);
2040 scr = DamageRegion(sna->mode.shadow_damage);
2041 RegionUnion(scr, scr, region);
2042 RegionTranslate(region, -crtc->base->x, -crtc->base->y);
2043 }
2044
sna_crtc_enable_shadow(struct sna * sna,struct sna_crtc * crtc)2045 static bool sna_crtc_enable_shadow(struct sna *sna, struct sna_crtc *crtc)
2046 {
2047 if (crtc->shadow) {
2048 assert(sna->mode.shadow_damage && sna->mode.shadow_active);
2049 return true;
2050 }
2051
2052 DBG(("%s: enabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc)));
2053
2054 if (!sna->mode.shadow_active) {
2055 if (!sna_mode_enable_shadow(sna))
2056 return false;
2057 assert(sna->mode.shadow_damage);
2058 assert(sna->mode.shadow == NULL);
2059 }
2060
2061 if (crtc->slave_pixmap) {
2062 assert(crtc->slave_damage == NULL);
2063
2064 DBG(("%s: enabling PRIME slave tracking on CRTC %d [pipe=%d], pixmap=%ld\n",
2065 __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->slave_pixmap->drawable.serialNumber));
2066 crtc->slave_damage = DamageCreate(sna_crtc_slave_damage, NULL,
2067 DamageReportRawRegion, TRUE,
2068 to_screen_from_sna(sna),
2069 crtc);
2070 if (crtc->slave_damage == NULL) {
2071 if (!--sna->mode.shadow_active)
2072 sna_mode_disable_shadow(sna);
2073 return false;
2074 }
2075
2076 DamageRegister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
2077 }
2078
2079 crtc->shadow = true;
2080 sna->mode.shadow_active++;
2081 return true;
2082 }
2083
sna_crtc_disable_override(struct sna * sna,struct sna_crtc * crtc)2084 static void sna_crtc_disable_override(struct sna *sna, struct sna_crtc *crtc)
2085 {
2086 if (crtc->client_bo == NULL)
2087 return;
2088
2089 assert(crtc->client_bo->refcnt >= crtc->client_bo->active_scanout);
2090 crtc->client_bo->active_scanout--;
2091
2092 if (!crtc->transform) {
2093 DrawableRec tmp;
2094
2095 tmp.width = crtc->base->mode.HDisplay;
2096 tmp.height = crtc->base->mode.VDisplay;
2097 tmp.depth = sna->front->drawable.depth;
2098 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
2099
2100 sna->render.copy_boxes(sna, GXcopy,
2101 &tmp, crtc->client_bo, -crtc->base->bounds.x1, -crtc->base->bounds.y1,
2102 &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
2103 &crtc->base->bounds, 1, 0);
2104 list_del(&crtc->shadow_link);
2105 }
2106 kgem_bo_destroy(&sna->kgem, crtc->client_bo);
2107 crtc->client_bo = NULL;
2108 }
2109
sna_crtc_disable_shadow(struct sna * sna,struct sna_crtc * crtc)2110 static void sna_crtc_disable_shadow(struct sna *sna, struct sna_crtc *crtc)
2111 {
2112 crtc->fallback_shadow = false;
2113 if (!crtc->shadow)
2114 return;
2115
2116 DBG(("%s: disabling for crtc %d\n", __FUNCTION__, __sna_crtc_id(crtc)));
2117 assert(sna->mode.shadow_active > 0);
2118
2119 if (crtc->slave_damage) {
2120 assert(crtc->slave_pixmap);
2121 DamageUnregister(&crtc->slave_pixmap->drawable, crtc->slave_damage);
2122 DamageDestroy(crtc->slave_damage);
2123 crtc->slave_damage = NULL;
2124 }
2125
2126 sna_crtc_disable_override(sna, crtc);
2127
2128 if (!--sna->mode.shadow_active)
2129 sna_mode_disable_shadow(sna);
2130
2131 crtc->shadow = false;
2132 }
2133
2134 static void
__sna_crtc_disable(struct sna * sna,struct sna_crtc * sna_crtc)2135 __sna_crtc_disable(struct sna *sna, struct sna_crtc *sna_crtc)
2136 {
2137 sna_crtc->mode_serial++;
2138
2139 sna_crtc_disable_cursor(sna, sna_crtc);
2140 rotation_set(sna, &sna_crtc->primary, RR_Rotate_0);
2141 sna_crtc_disable_shadow(sna, sna_crtc);
2142
2143 if (sna_crtc->bo) {
2144 DBG(("%s: releasing handle=%d from scanout, active=%d\n",
2145 __FUNCTION__,sna_crtc->bo->handle, sna_crtc->bo->active_scanout-1));
2146 assert(sna_crtc->public.flags & CRTC_ON);
2147 assert(sna_crtc->bo->active_scanout);
2148 assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
2149 sna_crtc->bo->active_scanout--;
2150 kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
2151 sna_crtc->bo = NULL;
2152 sna_crtc->public.flags &= ~CRTC_ON;
2153
2154 if (sna->mode.hidden) {
2155 sna->mode.hidden--;
2156 assert(sna->mode.hidden);
2157 assert(sna->mode.front_active == 0);
2158 } else {
2159 assert(sna->mode.front_active);
2160 sna->mode.front_active--;
2161 }
2162 sna->mode.dirty = true;
2163 }
2164
2165 if (sna_crtc->shadow_bo) {
2166 kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
2167 sna_crtc->shadow_bo = NULL;
2168 }
2169 if (sna_crtc->transform) {
2170 assert(sna->mode.rr_active);
2171 sna->mode.rr_active--;
2172 sna_crtc->transform = false;
2173 }
2174
2175 sna_crtc->cursor_transform = false;
2176 sna_crtc->hwcursor = true;
2177 assert(!sna_crtc->shadow);
2178 }
2179
2180 static void
sna_crtc_disable(xf86CrtcPtr crtc,bool force)2181 sna_crtc_disable(xf86CrtcPtr crtc, bool force)
2182 {
2183 struct sna *sna = to_sna(crtc->scrn);
2184 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2185 struct drm_mode_crtc arg;
2186
2187 if (sna_crtc == NULL)
2188 return;
2189
2190 if (!force && sna_crtc->bo == NULL)
2191 return;
2192
2193 DBG(("%s: disabling crtc [%d, pipe=%d], force?=%d\n", __FUNCTION__,
2194 __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), force));
2195
2196 sna_crtc_force_outputs_off(crtc);
2197
2198 memset(&arg, 0, sizeof(arg));
2199 arg.crtc_id = __sna_crtc_id(sna_crtc);
2200 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
2201
2202 __sna_crtc_disable(sna, sna_crtc);
2203 }
2204
update_flush_interval(struct sna * sna)2205 static void update_flush_interval(struct sna *sna)
2206 {
2207 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
2208 int i, max_vrefresh = 0;
2209
2210 DBG(("%s: front_active=%d\n", __FUNCTION__, sna->mode.front_active));
2211
2212 for (i = 0; i < sna->mode.num_real_crtc; i++) {
2213 xf86CrtcPtr crtc = config->crtc[i];
2214
2215 assert(to_sna_crtc(crtc) != NULL);
2216
2217 if (!crtc->enabled) {
2218 DBG(("%s: CRTC:%d (pipe %d) disabled\n",
2219 __FUNCTION__,i, sna_crtc_pipe(crtc)));
2220 assert(to_sna_crtc(crtc)->bo == NULL);
2221 continue;
2222 }
2223
2224 if (to_sna_crtc(crtc)->bo == NULL) {
2225 DBG(("%s: CRTC:%d (pipe %d) turned off\n",
2226 __FUNCTION__,i, sna_crtc_pipe(crtc)));
2227 continue;
2228 }
2229
2230 DBG(("%s: CRTC:%d (pipe %d) vrefresh=%f\n",
2231 __FUNCTION__, i, sna_crtc_pipe(crtc),
2232 xf86ModeVRefresh(&crtc->mode)));
2233 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(&crtc->mode));
2234 }
2235
2236 if (max_vrefresh == 0) {
2237 assert(sna->mode.front_active == 0);
2238 sna->vblank_interval = 0;
2239 } else
2240 sna->vblank_interval = 1000 / max_vrefresh; /* Hz -> ms */
2241
2242 DBG(("max_vrefresh=%d, vblank_interval=%d ms\n",
2243 max_vrefresh, sna->vblank_interval));
2244 }
2245
sna_create_bo_for_fbcon(struct sna * sna,const struct drm_mode_fb_cmd * fbcon)2246 static struct kgem_bo *sna_create_bo_for_fbcon(struct sna *sna,
2247 const struct drm_mode_fb_cmd *fbcon)
2248 {
2249 struct drm_gem_flink flink;
2250 struct kgem_bo *bo;
2251 int ret;
2252
2253 /* Create a new reference for the fbcon so that we can track it
2254 * using a normal bo and so that when we call gem_close on it we
2255 * delete our reference and not fbcon's!
2256 */
2257 VG_CLEAR(flink);
2258 flink.handle = fbcon->handle;
2259 ret = drmIoctl(sna->kgem.fd, DRM_IOCTL_GEM_FLINK, &flink);
2260 if (ret)
2261 return NULL;
2262
2263 bo = kgem_create_for_name(&sna->kgem, flink.name);
2264 if (bo == NULL)
2265 return NULL;
2266
2267 bo->pitch = fbcon->pitch;
2268 return bo;
2269 }
2270
2271 /* Copy the current framebuffer contents into the front-buffer for a seamless
2272 * transition from e.g. plymouth.
2273 */
sna_copy_fbcon(struct sna * sna)2274 void sna_copy_fbcon(struct sna *sna)
2275 {
2276 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
2277 struct drm_mode_fb_cmd fbcon;
2278 PixmapRec scratch;
2279 struct sna_pixmap *priv;
2280 struct kgem_bo *bo;
2281 BoxRec box;
2282 bool ok;
2283 int sx, sy;
2284 int dx, dy;
2285 int i;
2286
2287 if (wedged(sna) || isGPU(sna->scrn))
2288 return;
2289
2290 DBG(("%s\n", __FUNCTION__));
2291 assert((sna->flags & SNA_IS_HOSTED) == 0);
2292
2293 priv = sna_pixmap_move_to_gpu(sna->front, MOVE_WRITE | __MOVE_SCANOUT);
2294 if (priv == NULL)
2295 return;
2296
2297 /* Scan the connectors for a framebuffer and assume that is the fbcon */
2298 VG_CLEAR(fbcon);
2299 fbcon.fb_id = 0;
2300 for (i = 0; i < sna->mode.num_real_crtc; i++) {
2301 struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]);
2302 struct drm_mode_crtc mode;
2303
2304 assert(crtc != NULL);
2305
2306 VG_CLEAR(mode);
2307 mode.crtc_id = __sna_crtc_id(crtc);
2308 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
2309 continue;
2310 if (!mode.fb_id)
2311 continue;
2312
2313 fbcon.fb_id = mode.fb_id;
2314 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETFB, &fbcon)) {
2315 fbcon.fb_id = 0;
2316 continue;
2317 }
2318 break;
2319 }
2320 if (fbcon.fb_id == 0) {
2321 DBG(("%s: no fbcon found\n", __FUNCTION__));
2322 return;
2323 }
2324
2325 if (fbcon.fb_id == fb_id(priv->gpu_bo)) {
2326 DBG(("%s: fb already installed as scanout\n", __FUNCTION__));
2327 return;
2328 }
2329
2330 DBG(("%s: found fbcon, size=%dx%d, depth=%d, bpp=%d\n",
2331 __FUNCTION__, fbcon.width, fbcon.height, fbcon.depth, fbcon.bpp));
2332
2333 bo = sna_create_bo_for_fbcon(sna, &fbcon);
2334 if (bo == NULL)
2335 return;
2336
2337 DBG(("%s: fbcon handle=%d\n", __FUNCTION__, bo->handle));
2338
2339 scratch.drawable.width = fbcon.width;
2340 scratch.drawable.height = fbcon.height;
2341 scratch.drawable.depth = fbcon.depth;
2342 scratch.drawable.bitsPerPixel = fbcon.bpp;
2343 scratch.devPrivate.ptr = NULL;
2344
2345 box.x1 = box.y1 = 0;
2346 box.x2 = min(fbcon.width, sna->front->drawable.width);
2347 box.y2 = min(fbcon.height, sna->front->drawable.height);
2348
2349 sx = dx = 0;
2350 if (box.x2 < (uint16_t)fbcon.width)
2351 sx = (fbcon.width - box.x2) / 2;
2352 if (box.x2 < sna->front->drawable.width)
2353 dx = (sna->front->drawable.width - box.x2) / 2;
2354
2355 sy = dy = 0;
2356 if (box.y2 < (uint16_t)fbcon.height)
2357 sy = (fbcon.height - box.y2) / 2;
2358 if (box.y2 < sna->front->drawable.height)
2359 dy = (sna->front->drawable.height - box.y2) / 2;
2360
2361 ok = sna->render.copy_boxes(sna, GXcopy,
2362 &scratch.drawable, bo, sx, sy,
2363 &sna->front->drawable, priv->gpu_bo, dx, dy,
2364 &box, 1, 0);
2365 if (!DAMAGE_IS_ALL(priv->gpu_damage))
2366 sna_damage_add_box(&priv->gpu_damage, &box);
2367
2368 kgem_bo_destroy(&sna->kgem, bo);
2369
2370 #if ABI_VIDEODRV_VERSION >= SET_ABI_VERSION(10, 0)
2371 to_screen_from_sna(sna)->canDoBGNoneRoot = ok;
2372 #endif
2373 }
2374
use_shadow(struct sna * sna,xf86CrtcPtr crtc)2375 static bool use_shadow(struct sna *sna, xf86CrtcPtr crtc)
2376 {
2377 RRTransformPtr transform;
2378 PictTransform crtc_to_fb;
2379 struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
2380 unsigned pitch_limit;
2381 BoxRec b;
2382
2383 assert(sna->scrn->virtualX && sna->scrn->virtualY);
2384
2385 if (sna->flags & SNA_FORCE_SHADOW) {
2386 DBG(("%s: forcing shadow\n", __FUNCTION__));
2387 return true;
2388 }
2389
2390 if (to_sna_crtc(crtc)->fallback_shadow) {
2391 DBG(("%s: fallback shadow\n", __FUNCTION__));
2392 return true;
2393 }
2394
2395 if (sna->flags & SNA_TEAR_FREE && to_sna_crtc(crtc)->slave_pixmap) {
2396 DBG(("%s: TearFree shadow required\n", __FUNCTION__));
2397 return true;
2398 }
2399
2400 if (sna->scrn->virtualX > sna->mode.max_crtc_width ||
2401 sna->scrn->virtualY > sna->mode.max_crtc_height) {
2402 DBG(("%s: framebuffer too large (%dx%d) > (%dx%d)\n",
2403 __FUNCTION__,
2404 sna->scrn->virtualX, sna->scrn->virtualY,
2405 sna->mode.max_crtc_width, sna->mode.max_crtc_height));
2406 return true;
2407 }
2408
2409 if (!isGPU(sna->scrn)) {
2410 struct sna_pixmap *priv;
2411
2412 priv = sna_pixmap_force_to_gpu(sna->front, MOVE_READ | __MOVE_SCANOUT);
2413 if (priv == NULL)
2414 return true; /* maybe we can create a bo for the scanout? */
2415
2416 if (sna->kgem.gen == 071)
2417 pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
2418 else if ((sna->kgem.gen >> 3) > 4)
2419 pitch_limit = 32 * 1024;
2420 else if ((sna->kgem.gen >> 3) == 4)
2421 pitch_limit = priv->gpu_bo->tiling ? 16 * 1024 : 32 * 1024;
2422 else if ((sna->kgem.gen >> 3) == 3)
2423 pitch_limit = priv->gpu_bo->tiling ? 8 * 1024 : 16 * 1024;
2424 else
2425 pitch_limit = 8 * 1024;
2426 DBG(("%s: gpu bo handle=%d tiling=%d pitch=%d, limit=%d\n", __FUNCTION__, priv->gpu_bo->handle, priv->gpu_bo->tiling, priv->gpu_bo->pitch, pitch_limit));
2427 if (priv->gpu_bo->pitch > pitch_limit)
2428 return true;
2429
2430 if (priv->gpu_bo->tiling && sna->flags & SNA_LINEAR_FB) {
2431 DBG(("%s: gpu bo is tiled, need linear, forcing shadow\n", __FUNCTION__));
2432 return true;
2433 }
2434 }
2435
2436 transform = NULL;
2437 if (crtc->transformPresent)
2438 transform = &crtc->transform;
2439 if (RRTransformCompute(crtc->x, crtc->y,
2440 crtc->mode.HDisplay, crtc->mode.VDisplay,
2441 crtc->rotation, transform,
2442 &crtc_to_fb,
2443 &f_crtc_to_fb,
2444 &f_fb_to_crtc)) {
2445 bool needs_transform = true;
2446 unsigned rotation = rotation_reduce(&to_sna_crtc(crtc)->primary, crtc->rotation);
2447 DBG(("%s: natively supported rotation? rotation=%x & supported=%x == %d\n",
2448 __FUNCTION__, rotation, to_sna_crtc(crtc)->primary.rotation.supported,
2449 rotation == (rotation & to_sna_crtc(crtc)->primary.rotation.supported)));
2450 if ((to_sna_crtc(crtc)->primary.rotation.supported & rotation) == rotation)
2451 needs_transform = RRTransformCompute(crtc->x, crtc->y,
2452 crtc->mode.HDisplay, crtc->mode.VDisplay,
2453 RR_Rotate_0, transform,
2454 NULL, NULL, NULL);
2455 if (needs_transform) {
2456 DBG(("%s: RandR transform present\n", __FUNCTION__));
2457 return true;
2458 }
2459 }
2460
2461 /* And finally check that it is entirely visible */
2462 b.x1 = b.y1 = 0;
2463 b.x2 = crtc->mode.HDisplay;
2464 b.y2 = crtc->mode.VDisplay;
2465 pixman_f_transform_bounds(&f_crtc_to_fb, &b);
2466 DBG(("%s? bounds (%d, %d), (%d, %d), framebufer %dx%d\n",
2467 __FUNCTION__, b.x1, b.y1, b.x2, b.y2,
2468 sna->scrn->virtualX, sna->scrn->virtualY));
2469
2470 if (b.x1 < 0 || b.y1 < 0 ||
2471 b.x2 > sna->scrn->virtualX ||
2472 b.y2 > sna->scrn->virtualY) {
2473 DBG(("%s: scanout is partly outside the framebuffer\n",
2474 __FUNCTION__));
2475 return true;
2476 }
2477
2478 return false;
2479 }
2480
set_shadow(struct sna * sna,RegionPtr region)2481 static void set_shadow(struct sna *sna, RegionPtr region)
2482 {
2483 struct sna_pixmap *priv = sna_pixmap(sna->front);
2484
2485 assert(priv->gpu_bo);
2486 assert(sna->mode.shadow);
2487 assert(sna->mode.shadow->active_scanout);
2488
2489 DBG(("%s: waiting for region %dx[(%d, %d), (%d, %d)], front handle=%d, shadow handle=%d\n",
2490 __FUNCTION__,
2491 region_num_rects(region),
2492 region->extents.x1, region->extents.y1,
2493 region->extents.x2, region->extents.y2,
2494 priv->gpu_bo->handle, sna->mode.shadow->handle));
2495
2496 assert(priv->pinned & PIN_SCANOUT);
2497 assert((priv->pinned & PIN_PRIME) == 0);
2498 assert(sna->mode.shadow != priv->gpu_bo);
2499
2500 RegionCopy(&sna->mode.shadow_region, region);
2501
2502 priv->move_to_gpu = wait_for_shadow;
2503 priv->move_to_gpu_data = sna;
2504 }
2505
2506 static struct kgem_bo *
get_scanout_bo(struct sna * sna,PixmapPtr pixmap)2507 get_scanout_bo(struct sna *sna, PixmapPtr pixmap)
2508 {
2509 struct sna_pixmap *priv;
2510
2511 priv = sna_pixmap_force_to_gpu(pixmap, MOVE_READ | __MOVE_SCANOUT);
2512 if (!priv)
2513 return NULL;
2514
2515 if (priv->gpu_bo->pitch & 63) {
2516 struct kgem_bo *tmp;
2517 BoxRec b;
2518
2519 DBG(("%s: converting to scanout bo due to bad pitch [%d]\n",
2520 __FUNCTION__, priv->gpu_bo->pitch));
2521
2522 if (priv->pinned) {
2523 DBG(("%s: failed as the Pixmap is already pinned [%x]\n",
2524 __FUNCTION__, priv->pinned));
2525 return NULL;
2526 }
2527
2528 tmp = kgem_create_2d(&sna->kgem,
2529 pixmap->drawable.width,
2530 pixmap->drawable.height,
2531 sna->scrn->bitsPerPixel,
2532 priv->gpu_bo->tiling,
2533 CREATE_EXACT | CREATE_SCANOUT);
2534 if (tmp == NULL) {
2535 DBG(("%s: allocation failed\n", __FUNCTION__));
2536 return NULL;
2537 }
2538
2539 b.x1 = 0;
2540 b.y1 = 0;
2541 b.x2 = pixmap->drawable.width;
2542 b.y2 = pixmap->drawable.height;
2543
2544 if (sna->render.copy_boxes(sna, GXcopy,
2545 &pixmap->drawable, priv->gpu_bo, 0, 0,
2546 &pixmap->drawable, tmp, 0, 0,
2547 &b, 1, COPY_LAST)) {
2548 DBG(("%s: copy failed\n", __FUNCTION__));
2549 kgem_bo_destroy(&sna->kgem, tmp);
2550 return NULL;
2551 }
2552
2553 kgem_bo_destroy(&sna->kgem, priv->gpu_bo);
2554 priv->gpu_bo = tmp;
2555 }
2556
2557 priv->pinned |= PIN_SCANOUT;
2558 return priv->gpu_bo;
2559 }
2560
shadow_clear(struct sna * sna,PixmapPtr front,struct kgem_bo * bo,xf86CrtcPtr crtc)2561 static void shadow_clear(struct sna *sna,
2562 PixmapPtr front, struct kgem_bo *bo,
2563 xf86CrtcPtr crtc)
2564 {
2565 bool ok = false;
2566 if (!wedged(sna))
2567 ok = sna->render.fill_one(sna, front, bo, 0,
2568 0, 0, crtc->mode.HDisplay, crtc->mode.VDisplay,
2569 GXclear);
2570 if (!ok) {
2571 void *ptr = kgem_bo_map__gtt(&sna->kgem, bo);
2572 if (ptr)
2573 memset(ptr, 0, bo->pitch * crtc->mode.VDisplay);
2574 }
2575 sna->mode.shadow_dirty = true;
2576 }
2577
rr_active(xf86CrtcPtr crtc)2578 static bool rr_active(xf86CrtcPtr crtc)
2579 {
2580 return crtc->transformPresent || crtc->rotation != RR_Rotate_0;
2581 }
2582
sna_crtc_attach(xf86CrtcPtr crtc)2583 static struct kgem_bo *sna_crtc_attach(xf86CrtcPtr crtc)
2584 {
2585 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2586 ScrnInfoPtr scrn = crtc->scrn;
2587 struct sna *sna = to_sna(scrn);
2588 struct kgem_bo *bo;
2589
2590 if (sna_crtc->transform) {
2591 assert(sna->mode.rr_active);
2592 sna_crtc->transform = false;
2593 sna->mode.rr_active--;
2594 }
2595 sna_crtc->rotation = RR_Rotate_0;
2596
2597 if (sna_crtc->cache_bo) {
2598 kgem_bo_destroy(&sna->kgem, sna_crtc->cache_bo);
2599 sna_crtc->cache_bo = NULL;
2600 }
2601
2602 if (use_shadow(sna, crtc)) {
2603 PixmapPtr front;
2604 unsigned long tiled_limit;
2605 int tiling;
2606
2607 force_shadow:
2608 if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
2609 DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
2610 return NULL;
2611 }
2612
2613 DBG(("%s: attaching to per-crtc pixmap %dx%d\n",
2614 __FUNCTION__, crtc->mode.HDisplay, crtc->mode.VDisplay));
2615
2616 bo = sna_crtc->shadow_bo;
2617 if (bo) {
2618 if (sna_crtc->shadow_bo_width == crtc->mode.HDisplay &&
2619 sna_crtc->shadow_bo_height == crtc->mode.VDisplay) {
2620 DBG(("%s: reusing current shadow bo handle=%d\n",
2621 __FUNCTION__, bo->handle));
2622 goto out_shadow;
2623 }
2624
2625 kgem_bo_destroy(&sna->kgem, bo);
2626 sna_crtc->shadow_bo = NULL;
2627 }
2628
2629 tiling = I915_TILING_X;
2630 if (crtc->rotation & (RR_Rotate_90 | RR_Rotate_270) &&
2631 sna->kgem.can_scanout_y)
2632 tiling = I915_TILING_Y;
2633
2634 if (sna->kgem.gen == 071)
2635 tiled_limit = 16 * 1024 * 8;
2636 else if ((sna->kgem.gen >> 3) > 4)
2637 tiled_limit = 32 * 1024 * 8;
2638 else if ((sna->kgem.gen >> 3) == 4)
2639 tiled_limit = 16 * 1024 * 8;
2640 else
2641 tiled_limit = 8 * 1024 * 8;
2642 if ((unsigned long)crtc->mode.HDisplay * scrn->bitsPerPixel > tiled_limit)
2643 tiling = I915_TILING_NONE;
2644 if (sna->flags & SNA_LINEAR_FB)
2645 tiling = I915_TILING_NONE;
2646
2647 bo = kgem_create_2d(&sna->kgem,
2648 crtc->mode.HDisplay, crtc->mode.VDisplay,
2649 scrn->bitsPerPixel,
2650 tiling, CREATE_SCANOUT);
2651 if (bo == NULL) {
2652 DBG(("%s: failed to allocate crtc scanout\n", __FUNCTION__));
2653 return NULL;
2654 }
2655
2656 if (!get_fb(sna, bo, crtc->mode.HDisplay, crtc->mode.VDisplay)) {
2657 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2658 kgem_bo_destroy(&sna->kgem, bo);
2659 return NULL;
2660 }
2661
2662 front = sna_crtc->slave_pixmap ?: sna->front;
2663 if (__sna_pixmap_get_bo(front) && !rr_active(crtc)) {
2664 BoxRec b;
2665
2666 b.x1 = crtc->x;
2667 b.y1 = crtc->y;
2668 b.x2 = crtc->x + crtc->mode.HDisplay;
2669 b.y2 = crtc->y + crtc->mode.VDisplay;
2670
2671 if (b.x1 < 0)
2672 b.x1 = 0;
2673 if (b.y1 < 0)
2674 b.y1 = 0;
2675 if (b.x2 > scrn->virtualX)
2676 b.x2 = scrn->virtualX;
2677 if (b.y2 > scrn->virtualY)
2678 b.y2 = scrn->virtualY;
2679 if (b.x2 - b.x1 < crtc->mode.HDisplay ||
2680 b.y2 - b.y1 < crtc->mode.VDisplay)
2681 shadow_clear(sna, front, bo, crtc);
2682
2683 if (b.y2 > b.y1 && b.x2 > b.x1) {
2684 DrawableRec tmp;
2685
2686 DBG(("%s: copying onto shadow CRTC: (%d, %d)x(%d, %d) [fb=%dx%d], handle=%d\n",
2687 __FUNCTION__,
2688 b.x1, b.y1,
2689 b.x2-b.x1, b.y2-b.y1,
2690 scrn->virtualX, scrn->virtualY,
2691 bo->handle));
2692
2693 tmp.width = crtc->mode.HDisplay;
2694 tmp.height = crtc->mode.VDisplay;
2695 tmp.depth = front->drawable.depth;
2696 tmp.bitsPerPixel = front->drawable.bitsPerPixel;
2697
2698 if (!sna->render.copy_boxes(sna, GXcopy,
2699 &front->drawable, __sna_pixmap_get_bo(front), 0, 0,
2700 &tmp, bo, -crtc->x, -crtc->y,
2701 &b, 1, COPY_LAST))
2702 shadow_clear(sna, front, bo, crtc);
2703 }
2704 } else
2705 shadow_clear(sna, front, bo, crtc);
2706
2707 sna_crtc->shadow_bo_width = crtc->mode.HDisplay;
2708 sna_crtc->shadow_bo_height = crtc->mode.VDisplay;
2709 sna_crtc->shadow_bo = bo;
2710 out_shadow:
2711 sna_crtc->transform = true;
2712 sna->mode.rr_active++;
2713 return kgem_bo_reference(bo);
2714 } else {
2715 if (sna_crtc->shadow_bo) {
2716 kgem_bo_destroy(&sna->kgem, sna_crtc->shadow_bo);
2717 sna_crtc->shadow_bo = NULL;
2718 }
2719
2720 if (sna_crtc->slave_pixmap) {
2721 DBG(("%s: attaching to scanout pixmap\n", __FUNCTION__));
2722 bo = get_scanout_bo(sna, sna_crtc->slave_pixmap);
2723 if (bo == NULL) {
2724 DBG(("%s: failed to pin crtc scanout\n", __FUNCTION__));
2725 sna_crtc->fallback_shadow = true;
2726 goto force_shadow;
2727 }
2728
2729 if (!get_fb(sna, bo,
2730 sna_crtc->slave_pixmap->drawable.width,
2731 sna_crtc->slave_pixmap->drawable.height)) {
2732 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2733 sna_crtc->fallback_shadow = true;
2734 goto force_shadow;
2735 }
2736 } else {
2737 DBG(("%s: attaching to framebuffer\n", __FUNCTION__));
2738 bo = get_scanout_bo(sna, sna->front);
2739 if (bo == NULL) {
2740 DBG(("%s: failed to pin framebuffer\n", __FUNCTION__));
2741 sna_crtc->fallback_shadow = true;
2742 goto force_shadow;
2743 }
2744
2745 if (!get_fb(sna, bo, scrn->virtualX, scrn->virtualY)) {
2746 DBG(("%s: failed to bind fb for crtc scanout\n", __FUNCTION__));
2747 sna_crtc->fallback_shadow = true;
2748 goto force_shadow;
2749 }
2750 }
2751
2752 if (sna->flags & SNA_TEAR_FREE) {
2753 RegionRec region;
2754
2755 assert(sna_crtc->slave_pixmap == NULL);
2756
2757 DBG(("%s: enabling TearFree shadow\n", __FUNCTION__));
2758 region.extents.x1 = 0;
2759 region.extents.y1 = 0;
2760 region.extents.x2 = sna->scrn->virtualX;
2761 region.extents.y2 = sna->scrn->virtualY;
2762 region.data = NULL;
2763
2764 if (!sna_crtc_enable_shadow(sna, sna_crtc)) {
2765 DBG(("%s: failed to enable crtc shadow\n", __FUNCTION__));
2766 return NULL;
2767 }
2768
2769 if (sna->mode.shadow == NULL) {
2770 struct kgem_bo *shadow;
2771
2772 DBG(("%s: creating TearFree shadow bo\n", __FUNCTION__));
2773 shadow = kgem_create_2d(&sna->kgem,
2774 region.extents.x2,
2775 region.extents.y2,
2776 scrn->bitsPerPixel,
2777 kgem_choose_tiling(&sna->kgem,
2778 I915_TILING_X,
2779 region.extents.x2,
2780 region.extents.y2,
2781 sna->scrn->bitsPerPixel),
2782 CREATE_SCANOUT);
2783 if (shadow == NULL) {
2784 DBG(("%s: failed to allocate TearFree shadow bo\n", __FUNCTION__));
2785 sna_crtc->fallback_shadow = true;
2786 goto force_shadow;
2787 }
2788
2789 if (!get_fb(sna, shadow,
2790 region.extents.x2,
2791 region.extents.y2)) {
2792 DBG(("%s: failed to bind fb for TearFeee shadow\n", __FUNCTION__));
2793 kgem_bo_destroy(&sna->kgem, shadow);
2794 sna_crtc->fallback_shadow = true;
2795 goto force_shadow;
2796 }
2797
2798 assert(__sna_pixmap_get_bo(sna->front) == NULL ||
2799 __sna_pixmap_get_bo(sna->front)->pitch == shadow->pitch);
2800 sna->mode.shadow = shadow;
2801 sna->mode.shadow->active_scanout++;
2802 }
2803 set_shadow(sna, ®ion);
2804
2805 sna_crtc_disable_override(sna, sna_crtc);
2806 } else
2807 sna_crtc_disable_shadow(sna, sna_crtc);
2808
2809 sna_crtc->rotation = rotation_reduce(&sna_crtc->primary, crtc->rotation);
2810 assert(sna_crtc->primary.rotation.supported & sna_crtc->rotation);
2811 return kgem_bo_reference(bo);
2812 }
2813 }
2814
2815 #define SCALING_EPSILON (1./256)
2816
2817 static bool
is_affine(const struct pixman_f_transform * t)2818 is_affine(const struct pixman_f_transform *t)
2819 {
2820 return (fabs(t->m[2][0]) < SCALING_EPSILON &&
2821 fabs(t->m[2][1]) < SCALING_EPSILON);
2822 }
2823
determinant(const struct pixman_f_transform * t)2824 static double determinant(const struct pixman_f_transform *t)
2825 {
2826 return t->m[0][0]*t->m[1][1] - t->m[1][0]*t->m[0][1];
2827 }
2828
2829 static bool
affine_is_pixel_exact(const struct pixman_f_transform * t)2830 affine_is_pixel_exact(const struct pixman_f_transform *t)
2831 {
2832 double det = t->m[2][2] * determinant(t);
2833 if (fabs (det * det - 1.0) < SCALING_EPSILON) {
2834 if (fabs(t->m[0][1]) < SCALING_EPSILON &&
2835 fabs(t->m[1][0]) < SCALING_EPSILON)
2836 return true;
2837
2838 if (fabs(t->m[0][0]) < SCALING_EPSILON &&
2839 fabs(t->m[1][1]) < SCALING_EPSILON)
2840 return true;
2841 }
2842
2843 return false;
2844 }
2845
sna_crtc_randr(xf86CrtcPtr crtc)2846 static void sna_crtc_randr(xf86CrtcPtr crtc)
2847 {
2848 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
2849 struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
2850 PictTransform crtc_to_fb;
2851 PictFilterPtr filter;
2852 xFixed *params;
2853 int nparams;
2854 RRTransformPtr transform;
2855 int needs_transform;
2856
2857 transform = NULL;
2858 if (crtc->transformPresent)
2859 transform = &crtc->transform;
2860
2861 needs_transform =
2862 RRTransformCompute(crtc->x, crtc->y,
2863 crtc->mode.HDisplay, crtc->mode.VDisplay,
2864 crtc->rotation, transform,
2865 &crtc_to_fb,
2866 &f_crtc_to_fb,
2867 &f_fb_to_crtc);
2868
2869 filter = NULL;
2870 params = NULL;
2871 nparams = 0;
2872 if (sna_crtc->transform) {
2873 #ifdef RANDR_12_INTERFACE
2874 if (transform) {
2875 if (transform->nparams) {
2876 params = malloc(transform->nparams * sizeof(xFixed));
2877 if (params) {
2878 memcpy(params, transform->params,
2879 transform->nparams * sizeof(xFixed));
2880 nparams = transform->nparams;
2881 filter = transform->filter;
2882 }
2883 } else
2884 filter = transform->filter;
2885 }
2886 #endif
2887 crtc->transform_in_use = needs_transform;
2888 } else
2889 crtc->transform_in_use = sna_crtc->rotation != RR_Rotate_0;
2890
2891 /* Recompute the cursor after a potential change in transform */
2892 if (sna_crtc->cursor) {
2893 assert(sna_crtc->cursor->ref > 0);
2894 sna_crtc->cursor->ref--;
2895 sna_crtc->cursor = NULL;
2896 }
2897
2898 if (needs_transform) {
2899 sna_crtc->hwcursor = is_affine(&f_fb_to_crtc);
2900 sna_crtc->cursor_transform =
2901 sna_crtc->hwcursor &&
2902 !affine_is_pixel_exact(&f_fb_to_crtc);
2903 } else {
2904 sna_crtc->hwcursor = true;
2905 sna_crtc->cursor_transform = false;
2906 }
2907 DBG(("%s: hwcursor?=%d, cursor_transform?=%d\n",
2908 __FUNCTION__, sna_crtc->hwcursor, sna_crtc->cursor_transform));
2909
2910 crtc->crtc_to_framebuffer = crtc_to_fb;
2911 crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
2912 crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
2913
2914 free(crtc->params);
2915 crtc->params = params;
2916 crtc->nparams = nparams;
2917
2918 crtc->filter = filter;
2919 if (filter) {
2920 crtc->filter_width = filter->width;
2921 crtc->filter_height = filter->height;
2922 } else {
2923 crtc->filter_width = 0;
2924 crtc->filter_height = 0;
2925 }
2926
2927 crtc->bounds.x1 = 0;
2928 crtc->bounds.x2 = crtc->mode.HDisplay;
2929 crtc->bounds.y1 = 0;
2930 crtc->bounds.y2 = crtc->mode.VDisplay;
2931 pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds);
2932
2933 DBG(("%s: transform? %d, bounds (%d, %d), (%d, %d)\n",
2934 __FUNCTION__, crtc->transform_in_use,
2935 crtc->bounds.x1, crtc->bounds.y1,
2936 crtc->bounds.x2, crtc->bounds.y2));
2937 }
2938
2939 static void
sna_crtc_damage(xf86CrtcPtr crtc)2940 sna_crtc_damage(xf86CrtcPtr crtc)
2941 {
2942 ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
2943 struct sna *sna = to_sna(crtc->scrn);
2944 RegionRec region, *damage;
2945
2946 region.extents = crtc->bounds;
2947 region.data = NULL;
2948
2949 if (region.extents.x1 < 0)
2950 region.extents.x1 = 0;
2951 if (region.extents.y1 < 0)
2952 region.extents.y1 = 0;
2953 if (region.extents.x2 > screen->width)
2954 region.extents.x2 = screen->width;
2955 if (region.extents.y2 > screen->height)
2956 region.extents.y2 = screen->height;
2957
2958 if (region.extents.x2 <= region.extents.x1 ||
2959 region.extents.y2 <= region.extents.y1) {
2960 DBG(("%s: crtc not damaged, all-clipped\n", __FUNCTION__));
2961 return;
2962 }
2963
2964 DBG(("%s: marking crtc %d as completely damaged (%d, %d), (%d, %d)\n",
2965 __FUNCTION__, sna_crtc_id(crtc),
2966 region.extents.x1, region.extents.y1,
2967 region.extents.x2, region.extents.y2));
2968
2969 assert(sna->mode.shadow_damage && sna->mode.shadow_active);
2970 damage = DamageRegion(sna->mode.shadow_damage);
2971 RegionUnion(damage, damage, ®ion);
2972 to_sna_crtc(crtc)->crtc_damage = region;
2973
2974 DBG(("%s: damage now %dx[(%d, %d), (%d, %d)]\n",
2975 __FUNCTION__,
2976 region_num_rects(damage),
2977 damage->extents.x1, damage->extents.y1,
2978 damage->extents.x2, damage->extents.y2));
2979 }
2980
outputs_for_crtc(xf86CrtcPtr crtc,char * outputs,int max)2981 static char *outputs_for_crtc(xf86CrtcPtr crtc, char *outputs, int max)
2982 {
2983 struct sna *sna = to_sna(crtc->scrn);
2984 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
2985 int len, i;
2986
2987 for (i = len = 0; i < sna->mode.num_real_output; i++) {
2988 xf86OutputPtr output = config->output[i];
2989
2990 if (output->crtc != crtc)
2991 continue;
2992
2993 len += snprintf(outputs+len, max-len, "%s, ", output->name);
2994 }
2995 assert(len >= 2);
2996 outputs[len-2] = '\0';
2997
2998 return outputs;
2999 }
3000
rotation_to_str(Rotation rotation)3001 static const char *rotation_to_str(Rotation rotation)
3002 {
3003 switch (rotation & RR_Rotate_All) {
3004 case 0:
3005 case RR_Rotate_0: return "normal";
3006 case RR_Rotate_90: return "left";
3007 case RR_Rotate_180: return "inverted";
3008 case RR_Rotate_270: return "right";
3009 default: return "unknown";
3010 }
3011 }
3012
reflection_to_str(Rotation rotation)3013 static const char *reflection_to_str(Rotation rotation)
3014 {
3015 switch (rotation & RR_Reflect_All) {
3016 case 0: return "none";
3017 case RR_Reflect_X: return "X axis";
3018 case RR_Reflect_Y: return "Y axis";
3019 case RR_Reflect_X | RR_Reflect_Y: return "X and Y axes";
3020 default: return "invalid";
3021 }
3022 }
3023
reprobe_connectors(xf86CrtcPtr crtc)3024 static void reprobe_connectors(xf86CrtcPtr crtc)
3025 {
3026 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
3027 struct sna *sna = to_sna(crtc->scrn);
3028 int i;
3029
3030 for (i = 0; i < sna->mode.num_real_output; i++) {
3031 xf86OutputPtr output = config->output[i];
3032 if (output->crtc == crtc)
3033 to_sna_output(output)->reprobe = true;
3034 }
3035
3036 sna_mode_discover(sna, true);
3037 }
3038
3039 static Bool
__sna_crtc_set_mode(xf86CrtcPtr crtc)3040 __sna_crtc_set_mode(xf86CrtcPtr crtc)
3041 {
3042 struct sna *sna = to_sna(crtc->scrn);
3043 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3044 struct kgem_bo *saved_bo, *bo;
3045 uint32_t saved_offset;
3046 bool saved_transform;
3047 bool saved_hwcursor;
3048 bool saved_cursor_transform;
3049 int ret;
3050
3051 DBG(("%s: CRTC=%d, pipe=%d, hidden?=%d\n", __FUNCTION__,
3052 __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), sna->mode.hidden));
3053 if (sna->mode.hidden)
3054 return TRUE;
3055
3056 saved_bo = sna_crtc->bo;
3057 saved_transform = sna_crtc->transform;
3058 saved_cursor_transform = sna_crtc->cursor_transform;
3059 saved_hwcursor = sna_crtc->hwcursor;
3060 saved_offset = sna_crtc->offset;
3061
3062 sna_crtc->fallback_shadow = false;
3063 retry: /* Attach per-crtc pixmap or direct */
3064 bo = sna_crtc_attach(crtc);
3065 if (bo == NULL) {
3066 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
3067 "unable to attach scanout\n");
3068 goto error;
3069 }
3070
3071 /* Prevent recursion when enabling outputs during execbuffer */
3072 if (bo->exec && RQ(bo->rq)->bo == NULL) {
3073 _kgem_submit(&sna->kgem);
3074 __kgem_bo_clear_dirty(bo);
3075 }
3076
3077 sna_crtc->bo = bo;
3078 ret = sna_crtc_apply(crtc);
3079 if (ret) {
3080 kgem_bo_destroy(&sna->kgem, bo);
3081
3082 if (!sna_crtc->fallback_shadow) {
3083 sna_crtc->fallback_shadow = true;
3084 goto retry;
3085 }
3086
3087 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
3088 "failed to set mode: %s [%d]\n", strerror(ret), ret);
3089 goto error;
3090 }
3091
3092 sna_crtc->public.flags |= CRTC_ON;
3093 bo->active_scanout++;
3094 DBG(("%s: marking handle=%d as active=%d (removing %d from scanout, active=%d)\n",
3095 __FUNCTION__, bo->handle, bo->active_scanout,
3096 saved_bo ? saved_bo->handle : 0, saved_bo ? saved_bo->active_scanout - 1: -1));
3097 if (saved_bo) {
3098 assert(saved_bo->active_scanout);
3099 assert(saved_bo->refcnt >= saved_bo->active_scanout);
3100 saved_bo->active_scanout--;
3101 kgem_bo_destroy(&sna->kgem, saved_bo);
3102 }
3103
3104 sna_crtc_randr(crtc);
3105 if (sna_crtc->transform)
3106 sna_crtc_damage(crtc);
3107 if (sna_crtc->cursor && /* Reload cursor if RandR maybe changed */
3108 (!sna_crtc->hwcursor ||
3109 saved_cursor_transform || sna_crtc->cursor_transform ||
3110 sna_crtc->cursor->rotation != crtc->rotation))
3111 sna_crtc_disable_cursor(sna, sna_crtc);
3112
3113 assert(!sna->mode.hidden);
3114 sna->mode.front_active += saved_bo == NULL;
3115 sna->mode.dirty = true;
3116 DBG(("%s: handle=%d, scanout_active=%d, front_active=%d\n",
3117 __FUNCTION__, bo->handle, bo->active_scanout, sna->mode.front_active));
3118
3119 return TRUE;
3120
3121 error:
3122 sna_crtc->offset = saved_offset;
3123 if (sna_crtc->transform) {
3124 assert(sna->mode.rr_active);
3125 sna->mode.rr_active--;
3126 }
3127 if (saved_transform)
3128 sna->mode.rr_active++;
3129 sna_crtc->transform = saved_transform;
3130 sna_crtc->cursor_transform = saved_cursor_transform;
3131 sna_crtc->hwcursor = saved_hwcursor;
3132 sna_crtc->bo = saved_bo;
3133
3134 reprobe_connectors(crtc);
3135 return FALSE;
3136 }
3137
3138 static Bool
sna_crtc_set_mode_major(xf86CrtcPtr crtc,DisplayModePtr mode,Rotation rotation,int x,int y)3139 sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
3140 Rotation rotation, int x, int y)
3141 {
3142 struct sna *sna = to_sna(crtc->scrn);
3143 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3144 struct drm_mode_modeinfo saved_kmode;
3145 char outputs[256];
3146
3147 if (mode->HDisplay == 0 || mode->VDisplay == 0)
3148 return FALSE;
3149
3150 assert(sna_crtc);
3151
3152 xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
3153 "switch to mode %dx%d@%.1f on %s using pipe %d, position (%d, %d), rotation %s, reflection %s\n",
3154 mode->HDisplay, mode->VDisplay, xf86ModeVRefresh(mode),
3155 outputs_for_crtc(crtc, outputs, sizeof(outputs)), __sna_crtc_pipe(sna_crtc),
3156 x, y, rotation_to_str(rotation), reflection_to_str(rotation));
3157
3158 assert(mode->HDisplay <= sna->mode.max_crtc_width &&
3159 mode->VDisplay <= sna->mode.max_crtc_height);
3160
3161 #if HAS_GAMMA
3162 sna_crtc_gamma_set(crtc,
3163 crtc->gamma_red, crtc->gamma_green,
3164 crtc->gamma_blue, crtc->gamma_size);
3165 #endif
3166
3167 saved_kmode = sna_crtc->kmode;
3168 mode_to_kmode(&sna_crtc->kmode, mode);
3169 if (__sna_crtc_set_mode(crtc))
3170 return TRUE;
3171
3172 sna_crtc->kmode = saved_kmode;
3173 return FALSE;
3174 }
3175
3176 static void
sna_crtc_dpms(xf86CrtcPtr crtc,int mode)3177 sna_crtc_dpms(xf86CrtcPtr crtc, int mode)
3178 {
3179 DBG(("%s(pipe %d, dpms mode -> %d):= active=%d\n",
3180 __FUNCTION__, sna_crtc_pipe(crtc), mode, mode == DPMSModeOn));
3181
3182 if (mode == DPMSModeOn && crtc->enabled) {
3183 if (__sna_crtc_set_mode(crtc))
3184 update_flush_interval(to_sna(crtc->scrn));
3185 else
3186 mode = DPMSModeOff;
3187 }
3188
3189 if (mode != DPMSModeOn)
3190 sna_crtc_disable(crtc, false);
3191 }
3192
sna_mode_adjust_frame(struct sna * sna,int x,int y)3193 void sna_mode_adjust_frame(struct sna *sna, int x, int y)
3194 {
3195 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3196 xf86CrtcPtr crtc;
3197 int saved_x, saved_y;
3198
3199 if ((unsigned)config->compat_output >= config->num_output)
3200 return;
3201
3202 crtc = config->output[config->compat_output]->crtc;
3203 if (crtc == NULL || !crtc->enabled)
3204 return;
3205
3206 if (crtc->x == x && crtc->y == y)
3207 return;
3208
3209 saved_x = crtc->x;
3210 saved_y = crtc->y;
3211
3212 crtc->x = x;
3213 crtc->y = y;
3214 if (to_sna_crtc(crtc) && !__sna_crtc_set_mode(crtc)) {
3215 crtc->x = saved_x;
3216 crtc->y = saved_y;
3217 }
3218 }
3219
3220 static void
sna_crtc_gamma_set(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)3221 sna_crtc_gamma_set(xf86CrtcPtr crtc,
3222 CARD16 *red, CARD16 *green, CARD16 *blue, int size)
3223 {
3224 struct sna *sna = to_sna(crtc->scrn);
3225 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3226 struct drm_color_lut *lut = sna_crtc->gamma_lut;
3227 uint32_t blob_size = size * sizeof(lut[0]);
3228 uint32_t blob_id;
3229 int ret, i;
3230
3231 DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
3232
3233 if (!lut) {
3234 assert(size == 256);
3235
3236 drmModeCrtcSetGamma(to_sna(crtc->scrn)->kgem.fd,
3237 sna_crtc_id(crtc),
3238 size, red, green, blue);
3239 return;
3240 }
3241
3242 assert(size == sna_crtc->gamma_lut_size);
3243
3244 for (i = 0; i < size; i++) {
3245 lut[i].red = red[i];
3246 lut[i].green = green[i];
3247 lut[i].blue = blue[i];
3248 }
3249
3250 ret = drmModeCreatePropertyBlob(sna->kgem.fd, lut, blob_size, &blob_id);
3251 if (ret)
3252 return;
3253
3254 ret = drmModeObjectSetProperty(sna->kgem.fd,
3255 sna_crtc->id, DRM_MODE_OBJECT_CRTC,
3256 sna_crtc->gamma_lut_prop,
3257 blob_id);
3258
3259 drmModeDestroyPropertyBlob(sna->kgem.fd, blob_id);
3260 }
3261
3262 static void
sna_crtc_destroy(xf86CrtcPtr crtc)3263 sna_crtc_destroy(xf86CrtcPtr crtc)
3264 {
3265 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3266 struct plane *sprite, *sn;
3267
3268 if (sna_crtc == NULL)
3269 return;
3270
3271 free(sna_crtc->gamma_lut);
3272
3273 list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link)
3274 free(sprite);
3275
3276 free(sna_crtc);
3277 crtc->driver_private = NULL;
3278 }
3279
3280 #if HAS_PIXMAP_SHARING
3281 static Bool
sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc,PixmapPtr pixmap)3282 sna_crtc_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr pixmap)
3283 {
3284 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
3285
3286 if (sna_crtc == NULL)
3287 return FALSE;
3288
3289 if (pixmap == sna_crtc->slave_pixmap)
3290 return TRUE;
3291
3292 DBG(("%s: CRTC:%d, pipe=%d setting scanout pixmap=%ld\n",
3293 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
3294 pixmap ? pixmap->drawable.serialNumber : 0));
3295
3296 /* Disable first so that we can unregister the damage tracking */
3297 sna_crtc_disable_shadow(to_sna(crtc->scrn), sna_crtc);
3298
3299 sna_crtc->slave_pixmap = pixmap;
3300
3301 return TRUE;
3302 }
3303 #endif
3304
3305 static const xf86CrtcFuncsRec sna_crtc_funcs = {
3306 #if XF86_CRTC_VERSION >= 1
3307 .dpms = sna_crtc_dpms,
3308 #endif
3309 .set_mode_major = sna_crtc_set_mode_major,
3310 .gamma_set = sna_crtc_gamma_set,
3311 .destroy = sna_crtc_destroy,
3312 #if HAS_PIXMAP_SHARING
3313 .set_scanout_pixmap = sna_crtc_set_scanout_pixmap,
3314 #endif
3315 };
3316
prop_has_type_and_name(const struct drm_mode_get_property * prop,unsigned int type,const char * name)3317 inline static bool prop_has_type_and_name(const struct drm_mode_get_property *prop,
3318 unsigned int type, const char *name)
3319 {
3320 if ((prop->flags & (1 << type)) == 0)
3321 return false;
3322
3323 if (strcmp(prop->name, name))
3324 return false;
3325
3326 return true;
3327 }
3328
prop_is_rotation(const struct drm_mode_get_property * prop)3329 inline static bool prop_is_rotation(const struct drm_mode_get_property *prop)
3330 {
3331 return prop_has_type_and_name(prop, 5, "rotation");
3332 }
3333
parse_rotation_prop(struct sna * sna,struct plane * p,struct drm_mode_get_property * prop,uint64_t value)3334 static void parse_rotation_prop(struct sna *sna, struct plane *p,
3335 struct drm_mode_get_property *prop,
3336 uint64_t value)
3337 {
3338 struct drm_mode_property_enum *enums;
3339 int j;
3340
3341 p->rotation.prop = prop->prop_id;
3342 p->rotation.current = value;
3343
3344 DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n",
3345 __FUNCTION__, prop->prop_id, value, prop->count_enum_blobs));
3346
3347 enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum));
3348 if (!enums)
3349 return;
3350
3351 prop->count_values = 0;
3352 prop->enum_blob_ptr = (uintptr_t)enums;
3353
3354 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) {
3355 free(enums);
3356 return;
3357 }
3358
3359 /* XXX we assume that the mapping between kernel enum and
3360 * RandR remains fixed for our lifetimes.
3361 */
3362 VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs));
3363 for (j = 0; j < prop->count_enum_blobs; j++) {
3364 DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__,
3365 j, enums[j].name, (long)enums[j].value));
3366 p->rotation.supported |= 1 << enums[j].value;
3367 }
3368
3369 free(enums);
3370 }
3371
prop_is_color_encoding(const struct drm_mode_get_property * prop)3372 inline static bool prop_is_color_encoding(const struct drm_mode_get_property *prop)
3373 {
3374 return prop_has_type_and_name(prop, 3, "COLOR_ENCODING");
3375 }
3376
parse_color_encoding_prop(struct sna * sna,struct plane * p,struct drm_mode_get_property * prop,uint64_t value)3377 static void parse_color_encoding_prop(struct sna *sna, struct plane *p,
3378 struct drm_mode_get_property *prop,
3379 uint64_t value)
3380 {
3381 struct drm_mode_property_enum *enums;
3382 unsigned int supported = 0;
3383 int j;
3384
3385 DBG(("%s: found color encoding property .id=%d, value=%ld, num_enums=%d\n",
3386 __FUNCTION__, prop->prop_id, (long)value, prop->count_enum_blobs));
3387
3388 enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum));
3389 if (!enums)
3390 return;
3391
3392 prop->count_values = 0;
3393 prop->enum_blob_ptr = (uintptr_t)enums;
3394
3395 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) {
3396 free(enums);
3397 return;
3398 }
3399
3400 VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs));
3401 for (j = 0; j < prop->count_enum_blobs; j++) {
3402 if (!strcmp(enums[j].name, "ITU-R BT.601 YCbCr")) {
3403 p->color_encoding.values[0] = enums[j].value;
3404 supported |= 1 << 0;
3405 } else if (!strcmp(enums[j].name, "ITU-R BT.709 YCbCr")) {
3406 p->color_encoding.values[1] = enums[j].value;
3407 supported |= 1 << 1;
3408 }
3409 }
3410
3411 free(enums);
3412
3413 if (supported == 3)
3414 p->color_encoding.prop = prop->prop_id;
3415 }
3416
sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,unsigned idx,int colorspace)3417 void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc,
3418 unsigned idx, int colorspace)
3419 {
3420 struct plane *p;
3421
3422 assert(to_sna_crtc(crtc));
3423 assert(colorspace < ARRAY_SIZE(p->color_encoding.values));
3424
3425 p = lookup_sprite(to_sna_crtc(crtc), idx);
3426
3427 if (!p->color_encoding.prop)
3428 return;
3429
3430 drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd,
3431 p->id, DRM_MODE_OBJECT_PLANE,
3432 p->color_encoding.prop,
3433 p->color_encoding.values[colorspace]);
3434 }
3435
3436 typedef void (*parse_prop_func)(struct sna *sna,
3437 struct drm_mode_get_property *prop,
3438 uint64_t value,
3439 void *data);
parse_props(struct sna * sna,uint32_t obj_type,uint32_t obj_id,parse_prop_func parse_prop,void * data)3440 static void parse_props(struct sna *sna,
3441 uint32_t obj_type, uint32_t obj_id,
3442 parse_prop_func parse_prop,
3443 void *data)
3444 {
3445 #define N_STACK_PROPS 32 /* must be a multiple of 2 */
3446 struct local_mode_obj_get_properties arg;
3447 uint64_t stack[N_STACK_PROPS + N_STACK_PROPS/2];
3448 uint64_t *values = stack;
3449 uint32_t *props = (uint32_t *)(values + N_STACK_PROPS);
3450 int i;
3451
3452 memset(&arg, 0, sizeof(struct local_mode_obj_get_properties));
3453 arg.obj_id = obj_id;
3454 arg.obj_type = obj_type;
3455
3456 arg.props_ptr = (uintptr_t)props;
3457 arg.prop_values_ptr = (uintptr_t)values;
3458 arg.count_props = N_STACK_PROPS;
3459
3460 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
3461 return;
3462
3463 DBG(("%s: object %d (type %x) has %d props\n", __FUNCTION__,
3464 obj_id, obj_type, arg.count_props));
3465
3466 if (arg.count_props > N_STACK_PROPS) {
3467 values = malloc(2*sizeof(uint64_t)*arg.count_props);
3468 if (values == NULL)
3469 return;
3470
3471 props = (uint32_t *)(values + arg.count_props);
3472
3473 arg.props_ptr = (uintptr_t)props;
3474 arg.prop_values_ptr = (uintptr_t)values;
3475
3476 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_OBJ_GETPROPERTIES, &arg))
3477 arg.count_props = 0;
3478 }
3479 VG(VALGRIND_MAKE_MEM_DEFINED(arg.props_ptr, sizeof(uint32_t)*arg.count_props));
3480 VG(VALGRIND_MAKE_MEM_DEFINED(arg.prop_values_ptr, sizeof(uint64_t)*arg.count_props));
3481
3482 for (i = 0; i < arg.count_props; i++) {
3483 struct drm_mode_get_property prop;
3484
3485 memset(&prop, 0, sizeof(prop));
3486 prop.prop_id = props[i];
3487 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
3488 ERR(("%s: prop[%d].id=%d GETPROPERTY failed with errno=%d\n",
3489 __FUNCTION__, i, props[i], errno));
3490 continue;
3491 }
3492
3493 DBG(("%s: prop[%d] .id=%ld, .name=%s, .flags=%x, .value=%ld\n", __FUNCTION__, i,
3494 (long)props[i], prop.name, (unsigned)prop.flags, (long)values[i]));
3495
3496 parse_prop(sna, &prop, values[i], data);
3497 }
3498
3499 if (values != stack)
3500 free(values);
3501
3502 #undef N_STACK_PROPS
3503 }
3504
prop_is_type(const struct drm_mode_get_property * prop)3505 static bool prop_is_type(const struct drm_mode_get_property *prop)
3506 {
3507 return prop_has_type_and_name(prop, 3, "type");
3508 }
3509
plane_parse_prop(struct sna * sna,struct drm_mode_get_property * prop,uint64_t value,void * data)3510 static void plane_parse_prop(struct sna *sna,
3511 struct drm_mode_get_property *prop,
3512 uint64_t value, void *data)
3513 {
3514 struct plane *p = data;
3515
3516 if (prop_is_type(prop))
3517 p->type = value;
3518 else if (prop_is_rotation(prop))
3519 parse_rotation_prop(sna, p, prop, value);
3520 else if (prop_is_color_encoding(prop))
3521 parse_color_encoding_prop(sna, p, prop, value);
3522 }
3523
plane_details(struct sna * sna,struct plane * p)3524 static int plane_details(struct sna *sna, struct plane *p)
3525 {
3526 parse_props(sna, LOCAL_MODE_OBJECT_PLANE, p->id,
3527 plane_parse_prop, p);
3528
3529 p->rotation.supported &= DBG_NATIVE_ROTATION;
3530 if (!xf86ReturnOptValBool(sna->Options, OPTION_ROTATION, TRUE))
3531 p->rotation.supported = RR_Rotate_0;
3532
3533 DBG(("%s: plane=%d type=%d\n", __FUNCTION__, p->id, p->type));
3534
3535 return p->type;
3536 }
3537
add_sprite_plane(struct sna_crtc * crtc,struct plane * details)3538 static void add_sprite_plane(struct sna_crtc *crtc,
3539 struct plane *details)
3540 {
3541 struct plane *sprite = malloc(sizeof(*sprite));
3542 if (!sprite)
3543 return;
3544
3545 memcpy(sprite, details, sizeof(*sprite));
3546 list_add_tail(&sprite->link, &crtc->sprites);
3547 }
3548
3549 static void
sna_crtc_find_planes(struct sna * sna,struct sna_crtc * crtc)3550 sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc)
3551 {
3552 #define LOCAL_IOCTL_SET_CAP DRM_IOWR(0x0d, struct local_set_cap)
3553 struct local_set_cap {
3554 uint64_t name;
3555 uint64_t value;
3556 } cap;
3557 struct local_mode_get_plane_res r;
3558 uint32_t stack_planes[32];
3559 uint32_t *planes = stack_planes;
3560 int i;
3561
3562 VG_CLEAR(cap);
3563 cap.name = DRM_CLIENT_CAP_UNIVERSAL_PLANES;
3564 cap.value = 1;
3565 (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_SET_CAP, &cap);
3566
3567 VG_CLEAR(r);
3568 r.plane_id_ptr = (uintptr_t)planes;
3569 r.count_planes = ARRAY_SIZE(stack_planes);
3570 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r)) {
3571 ERR(("%s: GETPLANERESOURCES failed with errno=%d\n", __FUNCTION__, errno));
3572 return;
3573 }
3574
3575 DBG(("%s: %d planes\n", __FUNCTION__, (int)r.count_planes));
3576
3577 if (r.count_planes > ARRAY_SIZE(stack_planes)) {
3578 planes = malloc(sizeof(uint32_t)*r.count_planes);
3579 if (planes == NULL)
3580 return;
3581
3582 r.plane_id_ptr = (uintptr_t)planes;
3583 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANERESOURCES, &r))
3584 r.count_planes = 0;
3585 }
3586
3587 VG(VALGRIND_MAKE_MEM_DEFINED(planes, sizeof(uint32_t)*r.count_planes));
3588
3589 for (i = 0; i < r.count_planes; i++) {
3590 struct local_mode_get_plane p;
3591 struct plane details;
3592
3593 VG_CLEAR(p);
3594 p.plane_id = planes[i];
3595 p.count_format_types = 0;
3596 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_GETPLANE, &p))
3597 continue;
3598
3599 if ((p.possible_crtcs & (1 << __sna_crtc_pipe(crtc))) == 0)
3600 continue;
3601
3602 DBG(("%s: plane %d is attached to our pipe=%d\n",
3603 __FUNCTION__, planes[i], __sna_crtc_pipe(crtc)));
3604
3605 details.id = p.plane_id;
3606 details.rotation.prop = 0;
3607 details.rotation.supported = RR_Rotate_0;
3608 details.rotation.current = RR_Rotate_0;
3609
3610 switch (plane_details(sna, &details)) {
3611 default:
3612 break;
3613
3614 case DRM_PLANE_TYPE_PRIMARY:
3615 crtc->primary = details;
3616 break;
3617
3618 case DRM_PLANE_TYPE_CURSOR:
3619 break;
3620
3621 case DRM_PLANE_TYPE_OVERLAY:
3622 add_sprite_plane(crtc, &details);
3623 break;
3624 }
3625 }
3626
3627 if (planes != stack_planes)
3628 free(planes);
3629 }
3630
plane_has_format(const uint32_t formats[],int count_formats,uint32_t format)3631 static bool plane_has_format(const uint32_t formats[],
3632 int count_formats,
3633 uint32_t format)
3634 {
3635 int i;
3636
3637 for (i = 0; i < count_formats; i++) {
3638 if (formats[i] == format)
3639 return true;
3640 }
3641
3642 return false;
3643 }
3644
sna_has_sprite_format(struct sna * sna,uint32_t format)3645 bool sna_has_sprite_format(struct sna *sna, uint32_t format)
3646 {
3647 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
3648 int i;
3649
3650 if (sna->mode.num_real_crtc == 0)
3651 return false;
3652
3653 for (i = 0; i < sna->mode.num_real_crtc; i++) {
3654 struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
3655 struct plane *plane;
3656
3657 list_for_each_entry(plane, &sna_crtc->sprites, link) {
3658 struct local_mode_get_plane p;
3659 uint32_t *formats;
3660 int count_formats;
3661 bool has_format;
3662
3663 VG_CLEAR(p);
3664 p.plane_id = plane->id;
3665 p.count_format_types = 0;
3666 if (drmIoctl(sna->kgem.fd,
3667 LOCAL_IOCTL_MODE_GETPLANE,
3668 &p))
3669 continue;
3670 count_formats = p.count_format_types;
3671
3672 formats = calloc(count_formats, sizeof(formats[0]));
3673 if (!formats)
3674 continue;
3675
3676 p.count_format_types = count_formats;
3677 p.format_type_ptr = (uintptr_t)formats;
3678 if (drmIoctl(sna->kgem.fd,
3679 LOCAL_IOCTL_MODE_GETPLANE,
3680 &p)) {
3681 free(formats);
3682 continue;
3683 }
3684
3685 assert(p.count_format_types == count_formats);
3686
3687 has_format = plane_has_format(formats,
3688 count_formats,
3689 format);
3690
3691 free(formats);
3692
3693 /*
3694 * As long as one plane supports the
3695 * format we declare it as supported.
3696 * Not all planes may support it, but
3697 * then the GPU fallback will kick in.
3698 */
3699 if (has_format)
3700 return true;
3701 }
3702 }
3703
3704 return false;
3705 }
3706
prop_is_gamma_lut(const struct drm_mode_get_property * prop)3707 inline static bool prop_is_gamma_lut(const struct drm_mode_get_property *prop)
3708 {
3709 return prop_has_type_and_name(prop, 4, "GAMMA_LUT");
3710 }
3711
prop_is_gamma_lut_size(const struct drm_mode_get_property * prop)3712 inline static bool prop_is_gamma_lut_size(const struct drm_mode_get_property *prop)
3713 {
3714 return prop_has_type_and_name(prop, 1, "GAMMA_LUT_SIZE");
3715 }
3716
sna_crtc_parse_prop(struct sna * sna,struct drm_mode_get_property * prop,uint64_t value,void * data)3717 static void sna_crtc_parse_prop(struct sna *sna,
3718 struct drm_mode_get_property *prop,
3719 uint64_t value, void *data)
3720 {
3721 struct sna_crtc *crtc = data;
3722
3723 if (prop_is_gamma_lut(prop)) {
3724 crtc->gamma_lut_prop = prop->prop_id;
3725 crtc->gamma_lut_blob = value;
3726 } else if (prop_is_gamma_lut_size(prop)) {
3727 crtc->gamma_lut_size = value;
3728 }
3729 }
3730
3731 static void
sna_crtc_init__props(struct sna * sna,struct sna_crtc * crtc)3732 sna_crtc_init__props(struct sna *sna, struct sna_crtc *crtc)
3733 {
3734 ScrnInfoPtr scrn = sna->scrn;
3735
3736 parse_props(sna, LOCAL_MODE_OBJECT_CRTC, crtc->id,
3737 sna_crtc_parse_prop, crtc);
3738
3739 /* use high precision gamma LUT for > 8bpc */
3740 /* X-Server < 1.20 mishandles > 256 slots / > 8 bpc color maps. */
3741 if (scrn->rgbBits <= 8 ||
3742 XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,20,0,0,0))
3743 crtc->gamma_lut_size = 0;
3744
3745 if (crtc->gamma_lut_size) {
3746 crtc->gamma_lut = calloc(max(crtc->gamma_lut_size, 256),
3747 sizeof(crtc->gamma_lut[0]));
3748 if (!crtc->gamma_lut)
3749 crtc->gamma_lut_size = 0;
3750 }
3751
3752 DBG(("%s: CRTC:%d, gamma_lut_size=%d\n", __FUNCTION__,
3753 __sna_crtc_id(crtc), crtc->gamma_lut_size));
3754 }
3755
3756 static void
sna_crtc_init__rotation(struct sna * sna,struct sna_crtc * crtc)3757 sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc)
3758 {
3759 crtc->rotation = RR_Rotate_0;
3760 crtc->primary.rotation.supported = RR_Rotate_0;
3761 crtc->primary.rotation.current = RR_Rotate_0;
3762 }
3763
3764 static void
sna_crtc_init__cursor(struct sna * sna,struct sna_crtc * crtc)3765 sna_crtc_init__cursor(struct sna *sna, struct sna_crtc *crtc)
3766 {
3767 struct drm_mode_cursor arg;
3768
3769 VG_CLEAR(arg);
3770 arg.flags = DRM_MODE_CURSOR_BO;
3771 arg.crtc_id = __sna_crtc_id(crtc);
3772 arg.width = arg.height = 0;
3773 arg.handle = 0;
3774
3775 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
3776 crtc->hwcursor = true;
3777 }
3778
3779 static bool
sna_crtc_add(ScrnInfoPtr scrn,unsigned id)3780 sna_crtc_add(ScrnInfoPtr scrn, unsigned id)
3781 {
3782 struct sna *sna = to_sna(scrn);
3783 xf86CrtcPtr crtc;
3784 struct sna_crtc *sna_crtc;
3785 struct drm_i915_get_pipe_from_crtc_id get_pipe;
3786
3787 DBG(("%s(%d): is-zaphod? %d\n", __FUNCTION__, id, is_zaphod(scrn)));
3788
3789 sna_crtc = calloc(sizeof(struct sna_crtc), 1);
3790 if (sna_crtc == NULL)
3791 return false;
3792
3793 list_init(&sna_crtc->public.vblank_queue);
3794 sna_crtc->id = id;
3795
3796 VG_CLEAR(get_pipe);
3797 get_pipe.pipe = 0;
3798 get_pipe.crtc_id = id;
3799 if (drmIoctl(sna->kgem.fd,
3800 DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID,
3801 &get_pipe)) {
3802 free(sna_crtc);
3803 return false;
3804 }
3805 assert((unsigned)get_pipe.pipe < 256);
3806 sna_crtc->public.flags |= get_pipe.pipe << 8;
3807
3808 if (is_zaphod(scrn) &&
3809 (get_zaphod_crtcs(sna) & (1 << get_pipe.pipe)) == 0) {
3810 free(sna_crtc);
3811 return true;
3812 }
3813
3814 list_init(&sna_crtc->sprites);
3815 sna_crtc_init__rotation(sna, sna_crtc);
3816
3817 sna_crtc_init__props(sna, sna_crtc);
3818
3819 sna_crtc_find_planes(sna, sna_crtc);
3820
3821 DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x\n",
3822 __FUNCTION__, id, get_pipe.pipe,
3823 sna_crtc->primary.id, sna_crtc->primary.rotation.supported, sna_crtc->primary.rotation.current));
3824
3825 list_init(&sna_crtc->shadow_link);
3826
3827 crtc = xf86CrtcCreate(scrn, &sna_crtc_funcs);
3828 if (crtc == NULL) {
3829 free(sna_crtc);
3830 return false;
3831 }
3832
3833 sna_crtc_init__cursor(sna, sna_crtc);
3834
3835 crtc->driver_private = sna_crtc;
3836 sna_crtc->base = crtc;
3837 DBG(("%s: attached crtc[%d] pipe=%d\n",
3838 __FUNCTION__, id, __sna_crtc_pipe(sna_crtc)));
3839
3840 return true;
3841 }
3842
3843 static bool
is_panel(int type)3844 is_panel(int type)
3845 {
3846 #define DRM_MODE_CONNECTOR_LVDS 7
3847 #define DRM_MODE_CONNECTOR_eDP 14
3848 #define DRM_MODE_CONNECTOR_DSI 16
3849 return (type == DRM_MODE_CONNECTOR_LVDS ||
3850 type == DRM_MODE_CONNECTOR_eDP ||
3851 type == DRM_MODE_CONNECTOR_DSI);
3852 }
3853
3854 static int
find_property(struct sna * sna,struct sna_output * output,const char * name)3855 find_property(struct sna *sna, struct sna_output *output, const char *name)
3856 {
3857 struct drm_mode_get_property prop;
3858 int i;
3859
3860 VG_CLEAR(prop);
3861 for (i = 0; i < output->num_props; i++) {
3862 prop.prop_id = output->prop_ids[i];
3863 prop.count_values = 0;
3864 prop.count_enum_blobs = 0;
3865 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
3866 continue;
3867
3868 if (strcmp(prop.name, name) == 0)
3869 return i;
3870 }
3871
3872 return -1;
3873 }
3874
update_properties(struct sna * sna,struct sna_output * output)3875 static void update_properties(struct sna *sna, struct sna_output *output)
3876 {
3877 union compat_mode_get_connector compat_conn;
3878 struct drm_mode_modeinfo dummy;
3879
3880 VG_CLEAR(compat_conn);
3881
3882 compat_conn.conn.connector_id = output->id;
3883 compat_conn.conn.count_props = output->num_props;
3884 compat_conn.conn.props_ptr = (uintptr_t)output->prop_ids;
3885 compat_conn.conn.prop_values_ptr = (uintptr_t)output->prop_values;
3886 compat_conn.conn.count_modes = 1; /* skip detect */
3887 compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
3888 compat_conn.conn.count_encoders = 0;
3889
3890 (void)drmIoctl(sna->kgem.fd,
3891 DRM_IOCTL_MODE_GETCONNECTOR,
3892 &compat_conn.conn);
3893
3894 assert(compat_conn.conn.count_props == output->num_props);
3895 output->update_properties = false;
3896 }
3897
3898 static xf86OutputStatus
sna_output_detect(xf86OutputPtr output)3899 sna_output_detect(xf86OutputPtr output)
3900 {
3901 struct sna *sna = to_sna(output->scrn);
3902 struct sna_output *sna_output = output->driver_private;
3903 union compat_mode_get_connector compat_conn;
3904 uint32_t now;
3905
3906 DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
3907 sna_output->update_properties = false;
3908
3909 if (!sna_output->id) {
3910 DBG(("%s(%s) hiding due to lost connection\n", __FUNCTION__, output->name));
3911 return XF86OutputStatusDisconnected;
3912 }
3913
3914 /* Cache detections for 15s or hotplug event */
3915 now = GetTimeInMillis();
3916 if (sna_output->last_detect != 0 &&
3917 (int32_t)(now - sna_output->last_detect) <= OUTPUT_STATUS_CACHE_MS) {
3918 DBG(("%s(%s) reporting cached status (since %dms): %d\n",
3919 __FUNCTION__, output->name, now - sna_output->last_detect,
3920 sna_output->status));
3921 sna_output->update_properties = true;
3922 return sna_output->status;
3923 }
3924
3925 VG_CLEAR(compat_conn);
3926 compat_conn.conn.connector_id = sna_output->id;
3927 sna_output->num_modes = compat_conn.conn.count_modes = 0; /* reprobe */
3928 compat_conn.conn.count_encoders = 0;
3929 compat_conn.conn.count_props = sna_output->num_props;
3930 compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
3931 compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
3932
3933 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn))
3934 return XF86OutputStatusUnknown;
3935 DBG(("%s(%s): num modes %d -> %d, num props %d -> %d\n",
3936 __FUNCTION__, output->name,
3937 sna_output->num_modes, compat_conn.conn.count_modes,
3938 sna_output->num_props, compat_conn.conn.count_props));
3939
3940 assert(compat_conn.conn.count_props == sna_output->num_props);
3941
3942 while (compat_conn.conn.count_modes && compat_conn.conn.count_modes != sna_output->num_modes) {
3943 struct drm_mode_modeinfo *new_modes;
3944 int old_count;
3945
3946 old_count = sna_output->num_modes;
3947 new_modes = realloc(sna_output->modes,
3948 sizeof(*sna_output->modes)*compat_conn.conn.count_modes);
3949 if (new_modes == NULL)
3950 break;
3951
3952 sna_output->modes = new_modes;
3953 sna_output->num_modes = compat_conn.conn.count_modes;
3954 compat_conn.conn.modes_ptr = (uintptr_t)sna_output->modes;
3955 compat_conn.conn.count_encoders = 0;
3956 compat_conn.conn.count_props = 0;
3957 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
3958 sna_output->num_modes = min(old_count, sna_output->num_modes);
3959 break;
3960 }
3961 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->modes, sizeof(*sna_output->modes)*sna_output->num_modes));
3962 }
3963
3964 DBG(("%s(%s): found %d modes, connection status=%d\n",
3965 __FUNCTION__, output->name, sna_output->num_modes, compat_conn.conn.connection));
3966
3967 sna_output->reprobe = false;
3968 sna_output->last_detect = now;
3969 switch (compat_conn.conn.connection) {
3970 case DRM_MODE_CONNECTED:
3971 sna_output->status = XF86OutputStatusConnected;
3972 output->mm_width = compat_conn.conn.mm_width;
3973 output->mm_height = compat_conn.conn.mm_height;
3974 break;
3975 case DRM_MODE_DISCONNECTED:
3976 sna_output->status = XF86OutputStatusDisconnected;
3977 break;
3978 default:
3979 case DRM_MODE_UNKNOWNCONNECTION:
3980 sna_output->status = XF86OutputStatusUnknown;
3981 break;
3982 }
3983 return sna_output->status;
3984 }
3985
3986 static Bool
sna_output_mode_valid(xf86OutputPtr output,DisplayModePtr mode)3987 sna_output_mode_valid(xf86OutputPtr output, DisplayModePtr mode)
3988 {
3989 struct sna_output *sna_output = output->driver_private;
3990 struct sna *sna = to_sna(output->scrn);
3991
3992 if (mode->HDisplay > sna->mode.max_crtc_width)
3993 return MODE_VIRTUAL_X;
3994 if (mode->VDisplay > sna->mode.max_crtc_height)
3995 return MODE_VIRTUAL_Y;
3996
3997 /* Check that we can successfully pin this into the global GTT */
3998 if ((kgem_can_create_2d(&sna->kgem,
3999 mode->HDisplay, mode->VDisplay,
4000 sna->scrn->bitsPerPixel) & KGEM_CAN_CREATE_GTT) == 0)
4001 return MODE_MEM_VIRT;
4002
4003 /*
4004 * If the connector type is a panel, we will use the panel limit to
4005 * verfiy whether the mode is valid.
4006 */
4007 if (sna_output->has_panel_limits) {
4008 if (mode->HDisplay > sna_output->panel_hdisplay ||
4009 mode->VDisplay > sna_output->panel_vdisplay)
4010 return MODE_PANEL;
4011 }
4012
4013 return MODE_OK;
4014 }
4015
sna_output_set_parsed_edid(xf86OutputPtr output,xf86MonPtr mon)4016 static void sna_output_set_parsed_edid(xf86OutputPtr output, xf86MonPtr mon)
4017 {
4018 unsigned conn_mm_width, conn_mm_height;
4019
4020 /* We set the output size based on values from the kernel */
4021 conn_mm_width = output->mm_width;
4022 conn_mm_height = output->mm_height;
4023
4024 xf86OutputSetEDID(output, mon);
4025
4026 if (output->mm_width != conn_mm_width || output->mm_height != conn_mm_height) {
4027 DBG(("%s)%s): kernel and Xorg disagree over physical size: kernel=%dx%dmm, Xorg=%dx%dmm\n",
4028 __FUNCTION__, output->name,
4029 conn_mm_width, conn_mm_height,
4030 output->mm_width, output->mm_height));
4031 }
4032
4033 output->mm_width = conn_mm_width;
4034 output->mm_height = conn_mm_height;
4035 }
4036
4037 static void
sna_output_attach_edid(xf86OutputPtr output)4038 sna_output_attach_edid(xf86OutputPtr output)
4039 {
4040 struct sna *sna = to_sna(output->scrn);
4041 struct sna_output *sna_output = output->driver_private;
4042 struct drm_mode_get_blob blob;
4043 void *old, *raw = NULL;
4044 xf86MonPtr mon = NULL;
4045
4046 if (sna_output->edid_idx == -1)
4047 return;
4048
4049 /* Always refresh the blob as the kernel may randomly update the
4050 * id even if the contents of the blob doesn't change, and a
4051 * request for the stale id will return nothing.
4052 */
4053 if (sna_output->update_properties)
4054 update_properties(sna, sna_output);
4055
4056 raw = sna_output->edid_raw;
4057 blob.length = sna_output->edid_len;
4058
4059 if (blob.length && output->MonInfo) {
4060 old = alloca(blob.length);
4061 memcpy(old, raw, blob.length);
4062 } else
4063 old = NULL;
4064
4065 blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
4066 if (!blob.blob_id)
4067 goto done;
4068
4069 DBG(("%s(%s): attaching EDID id=%d, current=%d\n",
4070 __FUNCTION__, output->name,
4071 blob.blob_id, sna_output->edid_blob_id));
4072 if (blob.blob_id == sna_output->edid_blob_id && 0) { /* sigh */
4073 if (output->MonInfo) {
4074 /* XXX the property keeps on disappearing... */
4075 RRChangeOutputProperty(output->randr_output,
4076 MakeAtom("EDID", strlen("EDID"), TRUE),
4077 XA_INTEGER, 8, PropModeReplace,
4078 sna_output->edid_len,
4079 sna_output->edid_raw,
4080 FALSE, FALSE);
4081
4082 return;
4083 }
4084
4085 goto skip_read;
4086 }
4087
4088 blob.data = (uintptr_t)raw;
4089 do {
4090 while (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
4091 update_properties(sna, sna_output);
4092 if (blob.blob_id == sna_output->prop_values[sna_output->edid_idx]) {
4093 DBG(("%s(%s): failed to read blob, reusing previous\n",
4094 __FUNCTION__, output->name));
4095 goto done;
4096 }
4097 blob.blob_id = sna_output->prop_values[sna_output->edid_idx];
4098 }
4099
4100 DBG(("%s(%s): retrieving blob id=%d, length=%d\n",
4101 __FUNCTION__, output->name, blob.blob_id, blob.length));
4102
4103 if (blob.length < 128)
4104 goto done;
4105
4106 if (blob.length > sna_output->edid_len) {
4107 raw = realloc(raw, blob.length);
4108 if (raw == NULL)
4109 goto done;
4110
4111 VG(memset(raw, 0, blob.length));
4112 blob.data = (uintptr_t)raw;
4113 }
4114 } while (blob.length != sna_output->edid_len &&
4115 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob));
4116
4117 if (blob.length & 127) {
4118 /* Truncated EDID! Make sure no one reads too far */
4119 *SECTION(NO_EDID, (uint8_t*)raw) = blob.length/128 - 1;
4120 blob.length &= -128;
4121 }
4122
4123 if (old &&
4124 blob.length == sna_output->edid_len &&
4125 memcmp(old, raw, blob.length) == 0) {
4126 DBG(("%s(%s): EDID + MonInfo is unchanged\n",
4127 __FUNCTION__, output->name));
4128 assert(sna_output->edid_raw == raw);
4129 sna_output->edid_blob_id = blob.blob_id;
4130 RRChangeOutputProperty(output->randr_output,
4131 MakeAtom("EDID", strlen("EDID"), TRUE),
4132 XA_INTEGER, 8, PropModeReplace,
4133 sna_output->edid_len,
4134 sna_output->edid_raw,
4135 FALSE, FALSE);
4136 return;
4137 }
4138
4139 skip_read:
4140 if (raw) {
4141 mon = xf86InterpretEDID(output->scrn->scrnIndex, raw);
4142 if (mon && blob.length > 128)
4143 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
4144 }
4145
4146 done:
4147 sna_output_set_parsed_edid(output, mon);
4148 if (raw) {
4149 sna_output->edid_raw = raw;
4150 sna_output->edid_len = blob.length;
4151 sna_output->edid_blob_id = blob.blob_id;
4152 }
4153 }
4154
4155 static void
sna_output_attach_tile(xf86OutputPtr output)4156 sna_output_attach_tile(xf86OutputPtr output)
4157 {
4158 #if XF86_OUTPUT_VERSION >= 3
4159 struct sna *sna = to_sna(output->scrn);
4160 struct sna_output *sna_output = output->driver_private;
4161 struct drm_mode_get_blob blob;
4162 struct xf86CrtcTileInfo tile_info, *set = NULL;
4163 char *tile;
4164 int id;
4165
4166 id = find_property(sna, sna_output, "TILE");
4167 DBG(("%s: found? TILE=%d\n", __FUNCTION__, id));
4168 if (id == -1)
4169 goto out;
4170
4171 if (sna_output->update_properties)
4172 update_properties(sna, sna_output);
4173
4174 VG_CLEAR(blob);
4175 blob.blob_id = sna_output->prop_values[id];
4176 blob.length = 0;
4177 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
4178 goto out;
4179
4180 do {
4181 id = blob.length;
4182 tile = alloca(id + 1);
4183 blob.data = (uintptr_t)tile;
4184 VG(memset(tile, 0, id));
4185 DBG(("%s: reading %d bytes for TILE blob\n", __FUNCTION__, id));
4186 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
4187 goto out;
4188 } while (id != blob.length);
4189
4190 tile[blob.length] = '\0'; /* paranoia */
4191 DBG(("%s: TILE='%s'\n", __FUNCTION__, tile));
4192 if (xf86OutputParseKMSTile(tile, blob.length, &tile_info))
4193 set = &tile_info;
4194 out:
4195 xf86OutputSetTile(output, set);
4196 #endif
4197 }
4198
duplicate_mode(DisplayModePtr modes,DisplayModePtr m)4199 static bool duplicate_mode(DisplayModePtr modes, DisplayModePtr m)
4200 {
4201 if (m == NULL)
4202 return false;
4203
4204 while (modes) {
4205 if (xf86ModesEqual(modes, m))
4206 return true;
4207
4208 modes = modes->next;
4209 }
4210
4211 return false;
4212 }
4213
4214 static struct pixel_count {
4215 int16_t width, height;
4216 } common_16_9[] = {
4217 { 640, 360 },
4218 { 720, 405 },
4219 { 864, 486 },
4220 { 960, 540 },
4221 { 1024, 576 },
4222 { 1280, 720 },
4223 { 1366, 768 },
4224 { 1600, 900 },
4225 { 1920, 1080 },
4226 { 2048, 1152 },
4227 { 2560, 1440 },
4228 { 2880, 1620 },
4229 { 3200, 1800 },
4230 { 3840, 2160 },
4231 { 4096, 2304 },
4232 { 5120, 2880 },
4233 { 7680, 4320 },
4234 { 15360, 8640 },
4235 }, common_16_10[] = {
4236 { 1280, 800 },
4237 { 1400, 900 },
4238 { 1680, 1050 },
4239 { 1920, 1200 },
4240 { 2560, 1600 },
4241 };
4242
4243 static DisplayModePtr
default_modes(DisplayModePtr preferred)4244 default_modes(DisplayModePtr preferred)
4245 {
4246 DisplayModePtr modes;
4247 int n;
4248
4249 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,6,99,900,0)
4250 modes = xf86GetDefaultModes();
4251 #else
4252 modes = xf86GetDefaultModes(0, 0);
4253 #endif
4254
4255 /* XXX O(n^2) mode list generation :( */
4256
4257 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,4,99,901,0)
4258 if (preferred) {
4259 DisplayModePtr m;
4260
4261 /* Add a half-resolution mode useful for large panels */
4262 m = xf86GTFMode(preferred->HDisplay/2,
4263 preferred->VDisplay/2,
4264 xf86ModeVRefresh(preferred),
4265 FALSE, FALSE);
4266 if (!duplicate_mode(modes, m))
4267 modes = xf86ModesAdd(modes, m);
4268 else
4269 free(m);
4270
4271 if (preferred->VDisplay * 16 > preferred->HDisplay*9 - preferred->HDisplay/32 &&
4272 preferred->VDisplay * 16 < preferred->HDisplay*9 + preferred->HDisplay/32) {
4273 DBG(("Adding 16:9 modes -- %d < %d > %d\n",
4274 preferred->HDisplay*9 - preferred->HDisplay/32,
4275 preferred->VDisplay * 16,
4276 preferred->HDisplay*9 + preferred->HDisplay/32));
4277 for (n = 0; n < ARRAY_SIZE(common_16_9); n++) {
4278 if (preferred->HDisplay <= common_16_9[n].width ||
4279 preferred->VDisplay <= common_16_9[n].height)
4280 break;
4281
4282 m = xf86GTFMode(common_16_9[n].width,
4283 common_16_9[n].height,
4284 xf86ModeVRefresh(preferred),
4285 FALSE, FALSE);
4286 if (!duplicate_mode(modes, m))
4287 modes = xf86ModesAdd(modes, m);
4288 else
4289 free(m);
4290 }
4291 }
4292
4293 if (preferred->VDisplay * 16 > preferred->HDisplay*10 - preferred->HDisplay/32 &&
4294 preferred->VDisplay * 16 < preferred->HDisplay*10 + preferred->HDisplay/32) {
4295 DBG(("Adding 16:10 modes -- %d < %d > %d\n",
4296 preferred->HDisplay*10 - preferred->HDisplay/32,
4297 preferred->VDisplay * 16,
4298 preferred->HDisplay*10 + preferred->HDisplay/32));
4299 for (n = 0; n < ARRAY_SIZE(common_16_10); n++) {
4300 if (preferred->HDisplay <= common_16_10[n].width ||
4301 preferred->VDisplay <= common_16_10[n].height)
4302 break;
4303
4304 m = xf86GTFMode(common_16_10[n].width,
4305 common_16_10[n].height,
4306 xf86ModeVRefresh(preferred),
4307 FALSE, FALSE);
4308 if (!duplicate_mode(modes, m))
4309 modes = xf86ModesAdd(modes, m);
4310 else
4311 free(m);
4312 }
4313 }
4314 }
4315 #endif
4316
4317 return modes;
4318 }
4319
4320 static DisplayModePtr
sna_output_add_default_modes(xf86OutputPtr output,DisplayModePtr modes)4321 sna_output_add_default_modes(xf86OutputPtr output, DisplayModePtr modes)
4322 {
4323 xf86MonPtr mon = output->MonInfo;
4324 DisplayModePtr i, m, preferred = NULL;
4325 int max_x = 0, max_y = 0, max_clock = 0;
4326 float max_vrefresh = 0.0;
4327
4328 if (mon && GTF_SUPPORTED(mon->features.msc))
4329 return modes;
4330
4331 for (m = modes; m; m = m->next) {
4332 if (m->type & M_T_PREFERRED)
4333 preferred = m;
4334 max_x = max(max_x, m->HDisplay);
4335 max_y = max(max_y, m->VDisplay);
4336 max_clock = max(max_clock, m->Clock);
4337 max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m));
4338 }
4339 max_vrefresh *= (1 + SYNC_TOLERANCE);
4340
4341 m = default_modes(preferred);
4342 xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
4343
4344 for (i = m; i; i = i->next) {
4345 if (i->Clock > max_clock)
4346 i->status = MODE_CLOCK_HIGH;
4347 if (xf86ModeVRefresh(i) > max_vrefresh)
4348 i->status = MODE_VSYNC;
4349 if (preferred &&
4350 i->HDisplay >= preferred->HDisplay &&
4351 i->VDisplay >= preferred->VDisplay &&
4352 xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred))
4353 i->status = MODE_PANEL;
4354 }
4355
4356 xf86PruneInvalidModes(output->scrn, &m, FALSE);
4357
4358 return xf86ModesAdd(modes, m);
4359 }
4360
4361 static DisplayModePtr
sna_output_override_edid(xf86OutputPtr output)4362 sna_output_override_edid(xf86OutputPtr output)
4363 {
4364 struct sna_output *sna_output = output->driver_private;
4365 xf86MonPtr mon = NULL;
4366
4367 if (sna_output->fake_edid_raw == NULL)
4368 return NULL;
4369
4370 mon = xf86InterpretEDID(output->scrn->scrnIndex, sna_output->fake_edid_raw);
4371 if (mon == NULL) {
4372 return NULL;
4373 }
4374
4375 mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
4376
4377 xf86OutputSetEDID(output, mon);
4378
4379 return xf86DDCGetModes(output->scrn->scrnIndex, mon);
4380 }
4381
4382 static DisplayModePtr
sna_output_get_modes(xf86OutputPtr output)4383 sna_output_get_modes(xf86OutputPtr output)
4384 {
4385 struct sna_output *sna_output = output->driver_private;
4386 DisplayModePtr Modes, current;
4387 int i;
4388
4389 DBG(("%s(%s:%d)\n", __FUNCTION__, output->name, sna_output->id));
4390 assert(sna_output->id);
4391
4392 Modes = sna_output_override_edid(output);
4393 if (Modes)
4394 return Modes;
4395
4396 sna_output_attach_edid(output);
4397 sna_output_attach_tile(output);
4398
4399 current = NULL;
4400 if (output->crtc && !sna_output->hotplug_count) {
4401 struct drm_mode_crtc mode;
4402
4403 VG_CLEAR(mode);
4404 assert(to_sna_crtc(output->crtc));
4405 mode.crtc_id = sna_crtc_id(output->crtc);
4406
4407 if (drmIoctl(to_sna(output->scrn)->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode) == 0) {
4408 DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
4409 sna_crtc_id(output->crtc),
4410 sna_crtc_pipe(output->crtc),
4411 mode.mode_valid && mode.mode.clock));
4412
4413 if (mode.mode_valid && mode.mode.clock) {
4414 current = calloc(1, sizeof(DisplayModeRec));
4415 if (current) {
4416 mode_from_kmode(output->scrn, &mode.mode, current);
4417 current->type |= M_T_DRIVER | M_T_PREFERRED;
4418 }
4419 }
4420 }
4421 }
4422
4423 DBG(("%s: adding %d probed modes\n", __FUNCTION__, sna_output->num_modes));
4424
4425 for (i = 0; i < sna_output->num_modes; i++) {
4426 DisplayModePtr mode;
4427
4428 mode = calloc(1, sizeof(DisplayModeRec));
4429 if (mode == NULL)
4430 continue;
4431
4432 mode = mode_from_kmode(output->scrn,
4433 &sna_output->modes[i],
4434 mode);
4435 Modes = xf86ModesAdd(Modes, mode);
4436 if (current && xf86ModesEqual(mode, current)) {
4437 free((void*)current->name);
4438 free(current);
4439 current = NULL;
4440 }
4441 if (current && mode->type & M_T_PREFERRED)
4442 current->type &= ~M_T_PREFERRED;
4443 }
4444
4445 if (current)
4446 Modes = xf86ModesAdd(current, Modes);
4447
4448 /*
4449 * If the connector type is a panel, we will traverse the kernel mode to
4450 * get the panel limit. And then add all the standard modes to fake
4451 * the fullscreen experience.
4452 * If it is incorrect, please fix me.
4453 */
4454 sna_output->has_panel_limits = false;
4455 if (sna_output->is_panel) {
4456 sna_output->panel_hdisplay = sna_output->panel_vdisplay = 0;
4457 for (i = 0; i < sna_output->num_modes; i++) {
4458 struct drm_mode_modeinfo *m;
4459
4460 m = &sna_output->modes[i];
4461 if (m->hdisplay > sna_output->panel_hdisplay)
4462 sna_output->panel_hdisplay = m->hdisplay;
4463 if (m->vdisplay > sna_output->panel_vdisplay)
4464 sna_output->panel_vdisplay = m->vdisplay;
4465 }
4466 sna_output->has_panel_limits =
4467 sna_output->panel_hdisplay &&
4468 sna_output->panel_vdisplay;
4469 }
4470
4471 if (sna_output->add_default_modes)
4472 Modes = sna_output_add_default_modes(output, Modes);
4473
4474 return Modes;
4475 }
4476
4477 static void
sna_output_destroy(xf86OutputPtr output)4478 sna_output_destroy(xf86OutputPtr output)
4479 {
4480 struct sna_output *sna_output = output->driver_private;
4481 int i;
4482
4483 if (sna_output == NULL)
4484 return;
4485
4486 free(sna_output->edid_raw);
4487 free(sna_output->fake_edid_raw);
4488
4489 for (i = 0; i < sna_output->num_props; i++) {
4490 if (sna_output->props[i].kprop == NULL)
4491 continue;
4492
4493 if (sna_output->props[i].atoms) {
4494 if (output->randr_output)
4495 RRDeleteOutputProperty(output->randr_output, sna_output->props[i].atoms[0]);
4496 free(sna_output->props[i].atoms);
4497 }
4498
4499 drmModeFreeProperty(sna_output->props[i].kprop);
4500 }
4501 free(sna_output->props);
4502 free(sna_output->prop_ids);
4503 free(sna_output->prop_values);
4504
4505 backlight_close(&sna_output->backlight);
4506
4507 free(sna_output);
4508 output->driver_private = NULL;
4509 }
4510
4511 static void
__sna_output_dpms(xf86OutputPtr output,int dpms,int fixup)4512 __sna_output_dpms(xf86OutputPtr output, int dpms, int fixup)
4513 {
4514 struct sna *sna = to_sna(output->scrn);
4515 struct sna_output *sna_output = output->driver_private;
4516 int old_dpms = sna_output->dpms_mode;
4517
4518 DBG(("%s(%s:%d): dpms=%d (current: %d), active? %d\n",
4519 __FUNCTION__, output->name, sna_output->id,
4520 dpms, sna_output->dpms_mode,
4521 output->crtc != NULL));
4522
4523 if (!sna_output->id)
4524 return;
4525
4526 if (old_dpms == dpms)
4527 return;
4528
4529 /* Record the value of the backlight before turning
4530 * off the display, and reset if after turning it on.
4531 * Order is important as the kernel may record and also
4532 * reset the backlight across DPMS. Hence we need to
4533 * record the value before the kernel modifies it
4534 * and reapply it afterwards.
4535 */
4536 if (sna_output->backlight.iface && dpms != DPMSModeOn) {
4537 if (old_dpms == DPMSModeOn) {
4538 sna_output->backlight_active_level = sna_output_backlight_get(output);
4539 DBG(("%s(%s:%d): saving current backlight %d\n",
4540 __FUNCTION__, output->name, sna_output->id,
4541 sna_output->backlight_active_level));
4542 }
4543 sna_output->dpms_mode = dpms;
4544 sna_output_backlight_off(sna_output);
4545 }
4546
4547 if (output->crtc &&
4548 drmModeConnectorSetProperty(sna->kgem.fd,
4549 sna_output->id,
4550 sna_output->dpms_id,
4551 dpms)) {
4552 DBG(("%s(%s:%d): failed to set DPMS to %d (fixup? %d)\n",
4553 __FUNCTION__, output->name, sna_output->id, dpms, fixup));
4554 if (fixup && dpms != DPMSModeOn) {
4555 sna_crtc_disable(output->crtc, false);
4556 return;
4557 }
4558 }
4559
4560 if (sna_output->backlight.iface && dpms == DPMSModeOn) {
4561 DBG(("%s(%d:%d: restoring previous backlight %d\n",
4562 __FUNCTION__, output->name, sna_output->id,
4563 sna_output->backlight_active_level));
4564 sna_output_backlight_on(sna_output);
4565 }
4566
4567 sna_output->dpms_mode = dpms;
4568 }
4569
4570 static void
sna_output_dpms(xf86OutputPtr output,int dpms)4571 sna_output_dpms(xf86OutputPtr output, int dpms)
4572 {
4573 __sna_output_dpms(output, dpms, true);
4574 }
4575
4576 static bool
sna_property_ignore(drmModePropertyPtr prop)4577 sna_property_ignore(drmModePropertyPtr prop)
4578 {
4579 if (!prop)
4580 return true;
4581
4582 /* ignore blob prop */
4583 if (prop->flags & DRM_MODE_PROP_BLOB)
4584 return true;
4585
4586 /* ignore standard property */
4587 if (!strcmp(prop->name, "EDID") ||
4588 !strcmp(prop->name, "DPMS"))
4589 return true;
4590
4591 return false;
4592 }
4593
4594 static void
sna_output_create_ranged_atom(xf86OutputPtr output,Atom * atom,const char * name,INT32 min,INT32 max,uint64_t value,Bool immutable)4595 sna_output_create_ranged_atom(xf86OutputPtr output, Atom *atom,
4596 const char *name, INT32 min, INT32 max,
4597 uint64_t value, Bool immutable)
4598 {
4599 int err;
4600 INT32 atom_range[2];
4601
4602 atom_range[0] = min;
4603 atom_range[1] = max;
4604
4605 *atom = MakeAtom(name, strlen(name), TRUE);
4606
4607 err = RRConfigureOutputProperty(output->randr_output, *atom, FALSE,
4608 TRUE, immutable, 2, atom_range);
4609 if (err != 0)
4610 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4611 "RRConfigureOutputProperty error, %d\n", err);
4612
4613 err = RRChangeOutputProperty(output->randr_output, *atom, XA_INTEGER,
4614 32, PropModeReplace, 1, &value,
4615 FALSE, FALSE);
4616 if (err != 0)
4617 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4618 "RRChangeOutputProperty error, %d\n", err);
4619 }
4620
4621 static void
sna_output_create_resources(xf86OutputPtr output)4622 sna_output_create_resources(xf86OutputPtr output)
4623 {
4624 struct sna *sna = to_sna(output->scrn);
4625 struct sna_output *sna_output = output->driver_private;
4626 int i, j, err;
4627
4628 sna_output->props = calloc(sna_output->num_props,
4629 sizeof(struct sna_property));
4630 if (!sna_output->props)
4631 return;
4632
4633 for (i = 0; i < sna_output->num_props; i++) {
4634 struct sna_property *p = &sna_output->props[i];
4635
4636 p->kprop = drmModeGetProperty(sna->kgem.fd,
4637 sna_output->prop_ids[i]);
4638 if (sna_property_ignore(p->kprop)) {
4639 drmModeFreeProperty(p->kprop);
4640 p->kprop = NULL;
4641 continue;
4642 }
4643
4644 if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4645 p->num_atoms = 1;
4646 p->atoms = calloc(p->num_atoms, sizeof(Atom));
4647 if (!p->atoms)
4648 continue;
4649
4650 sna_output_create_ranged_atom(output, &p->atoms[0],
4651 p->kprop->name,
4652 p->kprop->values[0],
4653 p->kprop->values[1],
4654 sna_output->prop_values[i],
4655 p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE);
4656
4657 } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4658 p->num_atoms = p->kprop->count_enums + 1;
4659 p->atoms = calloc(p->num_atoms, sizeof(Atom));
4660 if (!p->atoms)
4661 continue;
4662
4663 p->atoms[0] = MakeAtom(p->kprop->name, strlen(p->kprop->name), TRUE);
4664 for (j = 1; j <= p->kprop->count_enums; j++) {
4665 struct drm_mode_property_enum *e = &p->kprop->enums[j-1];
4666 p->atoms[j] = MakeAtom(e->name, strlen(e->name), TRUE);
4667 }
4668
4669 err = RRConfigureOutputProperty(output->randr_output, p->atoms[0],
4670 FALSE, FALSE,
4671 p->kprop->flags & DRM_MODE_PROP_IMMUTABLE ? TRUE : FALSE,
4672 p->num_atoms - 1, (INT32 *)&p->atoms[1]);
4673 if (err != 0) {
4674 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4675 "RRConfigureOutputProperty error, %d\n", err);
4676 }
4677
4678 for (j = 0; j < p->kprop->count_enums; j++)
4679 if (p->kprop->enums[j].value == sna_output->prop_values[i])
4680 break;
4681 /* there's always a matching value */
4682 err = RRChangeOutputProperty(output->randr_output, p->atoms[0],
4683 XA_ATOM, 32, PropModeReplace, 1, &p->atoms[j+1],
4684 FALSE, FALSE);
4685 if (err != 0) {
4686 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4687 "RRChangeOutputProperty error, %d\n", err);
4688 }
4689 }
4690 }
4691
4692 if (sna_output->backlight.iface) {
4693 /* Set up the backlight property, which takes effect
4694 * immediately and accepts values only within the
4695 * backlight_range.
4696 */
4697 sna_output_create_ranged_atom(output, &backlight_atom,
4698 BACKLIGHT_NAME, 0,
4699 sna_output->backlight.max,
4700 sna_output->backlight_active_level,
4701 FALSE);
4702 sna_output_create_ranged_atom(output,
4703 &backlight_deprecated_atom,
4704 BACKLIGHT_DEPRECATED_NAME, 0,
4705 sna_output->backlight.max,
4706 sna_output->backlight_active_level,
4707 FALSE);
4708 }
4709 }
4710
4711 static Bool
sna_output_set_property(xf86OutputPtr output,Atom property,RRPropertyValuePtr value)4712 sna_output_set_property(xf86OutputPtr output, Atom property,
4713 RRPropertyValuePtr value)
4714 {
4715 struct sna *sna = to_sna(output->scrn);
4716 struct sna_output *sna_output = output->driver_private;
4717 int i;
4718
4719 if (property == backlight_atom || property == backlight_deprecated_atom) {
4720 INT32 val;
4721 int ret = 0;
4722
4723 if (value->type != XA_INTEGER || value->format != 32 ||
4724 value->size != 1)
4725 {
4726 return FALSE;
4727 }
4728
4729 val = *(INT32 *)value->data;
4730 DBG(("%s: setting backlight to %d (max=%d)\n",
4731 __FUNCTION__, (int)val, sna_output->backlight.max));
4732 if (val < 0 || val > sna_output->backlight.max)
4733 return FALSE;
4734
4735 sna_output->backlight_active_level = val;
4736 if (sna_output->dpms_mode == DPMSModeOn)
4737 ret = sna_output_backlight_set(sna_output, val);
4738 return ret == 0;
4739 }
4740
4741 if (!sna_output->id)
4742 return TRUE;
4743
4744 for (i = 0; i < sna_output->num_props; i++) {
4745 struct sna_property *p = &sna_output->props[i];
4746
4747 if (p->atoms == NULL || p->atoms[0] != property)
4748 continue;
4749
4750 if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4751 uint32_t val;
4752
4753 if (value->type != XA_INTEGER || value->format != 32 ||
4754 value->size != 1)
4755 return FALSE;
4756
4757 val = *(uint32_t *)value->data;
4758 drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
4759 p->kprop->prop_id, (uint64_t)val);
4760 return TRUE;
4761 } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4762 Atom atom;
4763 const char *name;
4764 int j;
4765
4766 if (value->type != XA_ATOM || value->format != 32 || value->size != 1)
4767 return FALSE;
4768
4769 memcpy(&atom, value->data, 4);
4770 name = NameForAtom(atom);
4771 if (name == NULL)
4772 return FALSE;
4773
4774 /* search for matching name string, then set its value down */
4775 for (j = 0; j < p->kprop->count_enums; j++) {
4776 if (!strcmp(p->kprop->enums[j].name, name)) {
4777 drmModeConnectorSetProperty(sna->kgem.fd, sna_output->id,
4778 p->kprop->prop_id, p->kprop->enums[j].value);
4779 return TRUE;
4780 }
4781 }
4782 return FALSE;
4783 }
4784 }
4785
4786 /* We didn't recognise this property, just report success in order
4787 * to allow the set to continue, otherwise we break setting of
4788 * common properties like EDID.
4789 */
4790 return TRUE;
4791 }
4792
4793 static Bool
sna_output_get_property(xf86OutputPtr output,Atom property)4794 sna_output_get_property(xf86OutputPtr output, Atom property)
4795 {
4796 struct sna_output *sna_output = output->driver_private;
4797 int err, i, j;
4798
4799 if (property == backlight_atom || property == backlight_deprecated_atom) {
4800 INT32 val;
4801
4802 if (!sna_output->backlight.iface)
4803 return FALSE;
4804
4805 if (sna_output->dpms_mode == DPMSModeOn) {
4806 val = sna_output_backlight_get(output);
4807 if (val < 0)
4808 return FALSE;
4809 DBG(("%s(%s): output on, reporting actual backlight value [%d]\n",
4810 __FUNCTION__, output->name, val));
4811 } else {
4812 val = sna_output->backlight_active_level;
4813 DBG(("%s(%s): output off, reporting cached backlight value [%d]\n",
4814 __FUNCTION__, output->name, val));
4815 }
4816
4817 err = RRChangeOutputProperty(output->randr_output, property,
4818 XA_INTEGER, 32, PropModeReplace, 1, &val,
4819 FALSE, FALSE);
4820 if (err != 0) {
4821 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4822 "RRChangeOutputProperty error, %d\n", err);
4823 return FALSE;
4824 }
4825
4826 return TRUE;
4827 }
4828
4829 for (i = 0; i < sna_output->num_props; i++) {
4830 struct sna_property *p = &sna_output->props[i];
4831
4832 if (p->atoms == NULL || p->atoms[0] != property)
4833 continue;
4834
4835 if (sna_output->update_properties && output->scrn->vtSema)
4836 update_properties(to_sna(output->scrn), sna_output);
4837
4838 err = 0;
4839 if (p->kprop->flags & DRM_MODE_PROP_RANGE) {
4840 err = RRChangeOutputProperty(output->randr_output,
4841 property, XA_INTEGER, 32,
4842 PropModeReplace, 1,
4843 &sna_output->prop_values[i],
4844 FALSE, FALSE);
4845 } else if (p->kprop->flags & DRM_MODE_PROP_ENUM) {
4846 for (j = 0; j < p->kprop->count_enums; j++) {
4847 if (p->kprop->enums[j].value == sna_output->prop_values[i])
4848 break;
4849 }
4850 err = RRChangeOutputProperty(output->randr_output,
4851 property, XA_ATOM, 32,
4852 PropModeReplace, 1,
4853 &p->atoms[j+1],
4854 FALSE, FALSE);
4855 }
4856
4857 if (err != 0)
4858 xf86DrvMsg(output->scrn->scrnIndex, X_WARNING,
4859 "RRChangeOutputProperty error, %d\n", err);
4860 return TRUE;
4861 }
4862
4863 return FALSE;
4864 }
4865
4866 static const xf86OutputFuncsRec sna_output_funcs = {
4867 .create_resources = sna_output_create_resources,
4868 #ifdef RANDR_12_INTERFACE
4869 .set_property = sna_output_set_property,
4870 .get_property = sna_output_get_property,
4871 #endif
4872 .dpms = sna_output_dpms,
4873 .detect = sna_output_detect,
4874 .mode_valid = sna_output_mode_valid,
4875
4876 .get_modes = sna_output_get_modes,
4877 .destroy = sna_output_destroy
4878 };
4879
4880 static const int subpixel_conv_table[] = {
4881 SubPixelUnknown,
4882 SubPixelHorizontalRGB,
4883 SubPixelHorizontalBGR,
4884 SubPixelVerticalRGB,
4885 SubPixelVerticalBGR,
4886 SubPixelNone
4887 };
4888
4889 static const char * const output_names[] = {
4890 /* DRM_MODE_CONNECTOR_Unknown */ "None",
4891 /* DRM_MODE_CONNECTOR_VGA */ "VGA",
4892 /* DRM_MODE_CONNECTOR_DVII */ "DVI",
4893 /* DRM_MODE_CONNECTOR_DVID */ "DVI",
4894 /* DRM_MODE_CONNECTOR_DVIA */ "DVI",
4895 /* DRM_MODE_CONNECTOR_Composite */ "Composite",
4896 /* DRM_MODE_CONNECTOR_SVIDEO */ "TV",
4897 /* DRM_MODE_CONNECTOR_LVDS */ "LVDS",
4898 /* DRM_MODE_CONNECTOR_Component */ "CTV",
4899 /* DRM_MODE_CONNECTOR_9PinDIN */ "DIN",
4900 /* DRM_MODE_CONNECTOR_DisplayPort */ "DP",
4901 /* DRM_MODE_CONNECTOR_HDMIA */ "HDMI",
4902 /* DRM_MODE_CONNECTOR_HDMIB */ "HDMI",
4903 /* DRM_MODE_CONNECTOR_TV */ "TV",
4904 /* DRM_MODE_CONNECTOR_eDP */ "eDP",
4905 /* DRM_MODE_CONNECTOR_VIRTUAL */ "Virtual",
4906 /* DRM_MODE_CONNECTOR_DSI */ "DSI",
4907 /* DRM_MODE_CONNECTOR_DPI */ "DPI"
4908 };
4909
4910 static bool
output_ignored(ScrnInfoPtr scrn,const char * name)4911 output_ignored(ScrnInfoPtr scrn, const char *name)
4912 {
4913 char monitor_name[64];
4914 const char *monitor;
4915 XF86ConfMonitorPtr conf;
4916
4917 snprintf(monitor_name, sizeof(monitor_name), "monitor-%s", name);
4918 monitor = xf86findOptionValue(scrn->options, monitor_name);
4919 if (!monitor)
4920 monitor = name;
4921
4922 conf = xf86findMonitor(monitor,
4923 xf86configptr->conf_monitor_lst);
4924 if (conf == NULL && XF86_CRTC_CONFIG_PTR(scrn)->num_output == 0)
4925 conf = xf86findMonitor(scrn->monitor->id,
4926 xf86configptr->conf_monitor_lst);
4927 if (conf == NULL)
4928 return false;
4929
4930 return xf86CheckBoolOption(conf->mon_option_lst, "Ignore", 0);
4931 }
4932
4933 static bool
gather_encoders(struct sna * sna,uint32_t id,int count,struct drm_mode_get_encoder * out)4934 gather_encoders(struct sna *sna, uint32_t id, int count,
4935 struct drm_mode_get_encoder *out)
4936 {
4937 union compat_mode_get_connector compat_conn;
4938 struct drm_mode_modeinfo dummy;
4939 struct drm_mode_get_encoder enc;
4940 uint32_t *ids = NULL;
4941
4942 DBG(("%s(%d): expected count=%d\n", __FUNCTION__, id, count));
4943
4944 VG_CLEAR(compat_conn);
4945 VG_CLEAR(enc);
4946 memset(out, 0, sizeof(*out));
4947
4948 do {
4949 uint32_t *nids;
4950
4951 nids = realloc(ids, sizeof(*ids) * count);
4952 if (nids == NULL) {
4953 free(ids);
4954 return false;
4955 }
4956 ids = nids;
4957
4958 compat_conn.conn.connector_id = id;
4959 compat_conn.conn.count_props = 0;
4960 compat_conn.conn.count_modes = 1; /* skip detect */
4961 compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
4962 compat_conn.conn.count_encoders = count;
4963 compat_conn.conn.encoders_ptr = (uintptr_t)ids;
4964
4965 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
4966 DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
4967 compat_conn.conn.count_encoders = count = 0;
4968 }
4969
4970 VG(VALGRIND_MAKE_MEM_DEFINED(ids, sizeof(uint32_t)*compat_conn.conn.count_encoders));
4971 if (count == compat_conn.conn.count_encoders)
4972 break;
4973
4974 count = compat_conn.conn.count_encoders;
4975 } while (1);
4976
4977 DBG(("%s(%d): gathering %d encoders\n", __FUNCTION__, id, count));
4978 for (count = 0; count < compat_conn.conn.count_encoders; count++) {
4979 enc.encoder_id = ids[count];
4980 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
4981 DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, ids[count], errno));
4982 count = 0;
4983 break;
4984 }
4985 DBG(("%s(%d): encoder=%d, possible_crtcs=%x, possible_clones=%x\n",
4986 __FUNCTION__, id, enc.encoder_id, enc.possible_crtcs, enc.possible_clones));
4987 out->possible_crtcs |= enc.possible_crtcs;
4988 out->possible_clones |= enc.possible_clones;
4989
4990 for (id = 0; id < sna->mode.num_real_encoder; id++) {
4991 if (enc.encoder_id == sna->mode.encoders[id]) {
4992 out->crtc_id |= 1 << id;
4993 break;
4994 }
4995 }
4996 }
4997
4998 free(ids);
4999 return count > 0;
5000 }
5001
5002 /* We need to map from kms encoder based possible_clones mask to X output based
5003 * possible clones masking. Note that for SDVO and on Haswell with DP/HDMI we
5004 * can have more than one output hanging off the same encoder.
5005 */
5006 static void
sna_mode_compute_possible_outputs(struct sna * sna)5007 sna_mode_compute_possible_outputs(struct sna *sna)
5008 {
5009 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5010 int encoder_mask[32];
5011 int i, j;
5012
5013 assert(sna->mode.num_real_output < 32);
5014 assert(sna->mode.num_real_crtc < 32);
5015
5016 for (i = 0; i < sna->mode.num_real_output; i++) {
5017 xf86OutputPtr output = config->output[i];
5018 struct sna_output *sna_output = to_sna_output(output);
5019
5020 assert(sna_output);
5021
5022 if (sna_output->id) {
5023 output->possible_clones = sna_output->possible_encoders;
5024 encoder_mask[i] = sna_output->attached_encoders;
5025 } else {
5026 output->possible_clones = 0;
5027 encoder_mask[i] = 0;
5028 }
5029 }
5030
5031 /* Convert from encoder numbering to output numbering */
5032 for (i = 0; i < sna->mode.num_real_output; i++) {
5033 xf86OutputPtr output = config->output[i];
5034 unsigned clones;
5035
5036 if (output->possible_clones == 0)
5037 continue;
5038
5039 clones = 0;
5040 for (j = 0; j < sna->mode.num_real_output; j++)
5041 if (i != j && output->possible_clones & encoder_mask[j])
5042 clones |= 1 << j;
5043 output->possible_clones = clones;
5044
5045 DBG(("%s: updated output '%s' %d [%d] (possible crtc:%x, possible clones:%x)\n",
5046 __FUNCTION__, output->name, i, to_connector_id(output),
5047 (uint32_t)output->possible_crtcs,
5048 (uint32_t)output->possible_clones));
5049 }
5050 }
5051
name_from_path(struct sna * sna,struct sna_output * sna_output,char * name)5052 static int name_from_path(struct sna *sna,
5053 struct sna_output *sna_output,
5054 char *name)
5055 {
5056 struct drm_mode_get_blob blob;
5057 char *path;
5058 int id;
5059
5060 id = find_property(sna, sna_output, "PATH");
5061 DBG(("%s: found? PATH=%d\n", __FUNCTION__, id));
5062 if (id == -1)
5063 return 0;
5064
5065 VG_CLEAR(blob);
5066 blob.blob_id = sna_output->prop_values[id];
5067 blob.length = 0;
5068 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5069 return 0;
5070
5071 do {
5072 id = blob.length;
5073 path = alloca(id + 1);
5074 blob.data = (uintptr_t)path;
5075 VG(memset(path, 0, id));
5076 DBG(("%s: reading %d bytes for path blob\n", __FUNCTION__, id));
5077 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5078 return 0;
5079 } while (id != blob.length);
5080
5081 path[blob.length] = '\0'; /* paranoia */
5082 DBG(("%s: PATH='%s'\n", __FUNCTION__, path));
5083
5084 /* we only handle MST paths for now */
5085 if (strncmp(path, "mst:", 4) == 0) {
5086 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5087 char tmp[5], *c;
5088 int n;
5089
5090 c = strchr(path + 4, '-');
5091 if (c == NULL)
5092 return 0;
5093
5094 id = c - (path + 4);
5095 if (id + 1> 5)
5096 return 0;
5097
5098 memcpy(tmp, path + 4, id);
5099 tmp[id] = '\0';
5100 id = strtoul(tmp, NULL, 0);
5101
5102 for (n = 0; n < sna->mode.num_real_output; n++) {
5103 if (to_sna_output(config->output[n])->id == id)
5104 return snprintf(name, 32, "%s-%s",
5105 config->output[n]->name, c + 1);
5106 }
5107 }
5108
5109 return 0;
5110 }
5111
fake_edid_name(xf86OutputPtr output)5112 static char *fake_edid_name(xf86OutputPtr output)
5113 {
5114 struct sna *sna = to_sna(output->scrn);
5115 const char *str, *colon;
5116
5117 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,7,99,901,0)
5118 str = xf86GetOptValString(sna->Options, OPTION_EDID);
5119 #else
5120 str = NULL;
5121 #endif
5122 if (str == NULL)
5123 return NULL;
5124
5125 do {
5126 colon = strchr(str, ':');
5127 if (colon == NULL)
5128 return NULL;
5129
5130 if (strncmp(str, output->name, colon-str) == 0 &&
5131 output->name[colon-str] == '\0') {
5132 char *path;
5133 int len;
5134
5135 str = colon + 1;
5136 colon = strchr(str, ',');
5137 if (colon)
5138 len = colon - str;
5139 else
5140 len = strlen(str);
5141
5142 path = malloc(len + 1);
5143 if (path == NULL)
5144 return NULL;
5145
5146 memcpy(path, str, len);
5147 path[len] = '\0';
5148 return path;
5149 }
5150
5151 str = strchr(colon + 1, ',');
5152 if (str == NULL)
5153 return NULL;
5154
5155 str++;
5156 } while (1);
5157 }
5158
5159 static void
sna_output_load_fake_edid(xf86OutputPtr output)5160 sna_output_load_fake_edid(xf86OutputPtr output)
5161 {
5162 struct sna_output *sna_output = output->driver_private;
5163 const char *filename;
5164 FILE *file;
5165 void *raw;
5166 int size;
5167
5168 filename = fake_edid_name(output);
5169 if (filename == NULL)
5170 return;
5171
5172 file = fopen(filename, "rb");
5173 if (file == NULL)
5174 goto err;
5175
5176 fseek(file, 0, SEEK_END);
5177 size = ftell(file);
5178 if (size % 128) {
5179 fclose(file);
5180 goto err;
5181 }
5182
5183 raw = malloc(size);
5184 if (raw == NULL) {
5185 fclose(file);
5186 free(raw);
5187 goto err;
5188 }
5189
5190 fseek(file, 0, SEEK_SET);
5191 if (fread(raw, size, 1, file) != 1) {
5192 fclose(file);
5193 free(raw);
5194 goto err;
5195 }
5196 fclose(file);
5197
5198 sna_output->fake_edid_raw = raw;
5199
5200 xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG,
5201 "Loading EDID from \"%s\" for output %s\n",
5202 filename, output->name);
5203 return;
5204
5205 err:
5206 xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
5207 "Could not read EDID file \"%s\" for output %s\n",
5208 filename, output->name);
5209 }
5210
5211 static int
sna_output_add(struct sna * sna,unsigned id,unsigned serial)5212 sna_output_add(struct sna *sna, unsigned id, unsigned serial)
5213 {
5214 ScrnInfoPtr scrn = sna->scrn;
5215 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5216 union compat_mode_get_connector compat_conn;
5217 struct drm_mode_get_encoder enc;
5218 struct drm_mode_modeinfo dummy;
5219 struct sna_output *sna_output;
5220 xf86OutputPtr *outputs, output;
5221 unsigned possible_encoders, attached_encoders, possible_crtcs;
5222 const char *output_name;
5223 char name[32];
5224 int path, len, i;
5225
5226 DBG(("%s(%d): serial=%d\n", __FUNCTION__, id, serial));
5227
5228 COMPILE_TIME_ASSERT(sizeof(struct drm_mode_get_connector) <= sizeof(compat_conn.pad));
5229
5230 VG_CLEAR(compat_conn);
5231 memset(&enc, 0, sizeof(enc));
5232
5233 compat_conn.conn.connector_id = id;
5234 compat_conn.conn.count_props = 0;
5235 compat_conn.conn.count_modes = 1; /* skip detect */
5236 compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5237 compat_conn.conn.count_encoders = 1;
5238 compat_conn.conn.encoders_ptr = (uintptr_t)&enc.encoder_id;
5239
5240 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
5241 DBG(("%s: GETCONNECTOR[%d] failed, ret=%d\n", __FUNCTION__, id, errno));
5242 return -1;
5243 }
5244 assert(compat_conn.conn.connector_id == id);
5245 DBG(("%s(%d): has %d associated encoders\n", __FUNCTION__, id, compat_conn.conn.count_encoders));
5246
5247 if (compat_conn.conn.connector_type < ARRAY_SIZE(output_names))
5248 output_name = output_names[compat_conn.conn.connector_type];
5249 else
5250 output_name = "UNKNOWN";
5251 len = snprintf(name, 32, "%s-%d", output_name, compat_conn.conn.connector_type_id);
5252 if (output_ignored(scrn, name))
5253 return 0;
5254
5255 if (enc.encoder_id) {
5256 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc)) {
5257 DBG(("%s: GETENCODER[%d] failed, ret=%d\n", __FUNCTION__, enc.encoder_id, errno));
5258 return 0;
5259 }
5260
5261 possible_encoders = enc.possible_clones;
5262 attached_encoders = 0;
5263 for (i = 0; i < sna->mode.num_real_encoder; i++) {
5264 if (enc.encoder_id == sna->mode.encoders[i]) {
5265 attached_encoders = 1 << i;
5266 break;
5267 }
5268 }
5269
5270 if (attached_encoders == 0) {
5271 DBG(("%s: failed to find attached encoder\n", __FUNCTION__));
5272 return 0;
5273 }
5274
5275 possible_crtcs = enc.possible_crtcs;
5276 assert(enc.encoder_id == compat_conn.conn.encoder_id || compat_conn.conn.encoder_id == 0);
5277 } else {
5278 DBG(("%s: unexpected number [%d] of encoders attached\n",
5279 __FUNCTION__, compat_conn.conn.count_encoders));
5280 if (!gather_encoders(sna, id, compat_conn.conn.count_encoders, &enc)) {
5281 DBG(("%s: gather encoders failed\n", __FUNCTION__));
5282 return 0;
5283 }
5284 possible_encoders = enc.possible_clones;
5285 attached_encoders = enc.crtc_id;
5286 possible_crtcs = enc.possible_crtcs;
5287
5288 memset(&enc, 0, sizeof(enc));
5289 enc.encoder_id = compat_conn.conn.encoder_id;
5290 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETENCODER, &enc);
5291 }
5292
5293 if (is_zaphod(scrn)) {
5294 unsigned zaphod_crtcs;
5295
5296 if (!sna_zaphod_match(sna, name)) {
5297 DBG(("%s: zaphod mismatch, want %s, have %s\n",
5298 __FUNCTION__,
5299 xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???",
5300 name));
5301 return 0;
5302 }
5303
5304 zaphod_crtcs = get_zaphod_crtcs(sna);
5305 possible_crtcs &= zaphod_crtcs;
5306 if (possible_crtcs == 0) {
5307 xf86DrvMsg(scrn->scrnIndex, X_ERROR,
5308 "%s is an invalid output for screen %d\n",
5309 name, scrn->confScreen->device->screen);
5310 return -1;
5311 }
5312
5313 possible_crtcs >>= ffs(zaphod_crtcs) - 1;
5314 }
5315
5316 sna_output = calloc(sizeof(struct sna_output), 1);
5317 if (!sna_output)
5318 return -1;
5319
5320 sna_output->connector_type = compat_conn.conn.connector_type;
5321 sna_output->connector_type_id = compat_conn.conn.connector_type_id;
5322 sna_output->num_props = compat_conn.conn.count_props;
5323 sna_output->prop_ids = malloc(sizeof(uint32_t)*compat_conn.conn.count_props);
5324 sna_output->prop_values = malloc(sizeof(uint64_t)*compat_conn.conn.count_props);
5325 if (sna_output->prop_ids == NULL || sna_output->prop_values == NULL) {
5326 free(sna_output->prop_ids);
5327 free(sna_output->prop_values);
5328 free(sna_output);
5329 return -1;
5330 }
5331
5332 compat_conn.conn.count_encoders = 0;
5333
5334 compat_conn.conn.count_modes = 1;
5335 compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5336
5337 compat_conn.conn.count_props = sna_output->num_props;
5338 compat_conn.conn.props_ptr = (uintptr_t)sna_output->prop_ids;
5339 compat_conn.conn.prop_values_ptr = (uintptr_t)sna_output->prop_values;
5340
5341 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCONNECTOR, &compat_conn.conn)) {
5342 DBG(("%s: second! GETCONNECTOR failed, ret=%d\n", __FUNCTION__, errno));
5343 goto cleanup;
5344 }
5345 assert(compat_conn.conn.connector_id == id);
5346
5347 /* statically constructed property list */
5348 assert(sna_output->num_props == compat_conn.conn.count_props);
5349 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_ids, sizeof(uint32_t)*sna_output->num_props));
5350 VG(VALGRIND_MAKE_MEM_DEFINED(sna_output->prop_values, sizeof(uint64_t)*sna_output->num_props));
5351
5352 /* Construct name from topology, and recheck if output is acceptable */
5353 path = name_from_path(sna, sna_output, name);
5354 if (path) {
5355 if (output_ignored(scrn, name)) {
5356 len = 0;
5357 goto skip;
5358 }
5359
5360 if (is_zaphod(scrn) && !sna_zaphod_match(sna, name)) {
5361 DBG(("%s: zaphod mismatch, want %s, have %s\n",
5362 __FUNCTION__,
5363 xf86GetOptValString(sna->Options, OPTION_ZAPHOD) ?: "???",
5364 name));
5365 len = 0;
5366 goto skip;
5367 }
5368
5369 len = path;
5370 }
5371
5372 /* Check if we are dynamically reattaching an old connector */
5373 if (serial) {
5374 for (i = 0; i < sna->mode.num_real_output; i++) {
5375 output = config->output[i];
5376 if (strcmp(output->name, name) == 0) {
5377 assert(output->scrn == scrn);
5378 assert(output->funcs == &sna_output_funcs);
5379
5380 /*
5381 * If the old output is still in use, tell
5382 * the kernel to switch it off so we can
5383 * move its resources over to the new id.
5384 */
5385 if (output->crtc) {
5386 struct drm_mode_crtc arg = {
5387 .crtc_id = __sna_crtc_id(to_sna_crtc(output->crtc)),
5388 };
5389 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg);
5390 output->crtc = NULL;
5391 }
5392
5393 sna_output_destroy(output);
5394 goto reset;
5395 }
5396 }
5397 }
5398
5399 output = calloc(1, sizeof(*output) + len + 1);
5400 if (!output)
5401 goto cleanup;
5402
5403 outputs = realloc(config->output, (config->num_output + 1) * sizeof(output));
5404 if (outputs == NULL) {
5405 free(output);
5406 goto cleanup;
5407 }
5408
5409 output->scrn = scrn;
5410 output->funcs = &sna_output_funcs;
5411 output->name = (char *)(output + 1);
5412 memcpy(output->name, name, len + 1);
5413
5414 output->use_screen_monitor = config->num_output != 0;
5415 xf86OutputUseScreenMonitor(output, !output->use_screen_monitor);
5416 assert(output->options);
5417
5418 DBG(("%s: inserting output #%d of %d\n", __FUNCTION__, sna->mode.num_real_output, config->num_output));
5419 for (i = config->num_output; i > sna->mode.num_real_output; i--) {
5420 outputs[i] = outputs[i-1];
5421 assert(outputs[i]->driver_private == NULL);
5422 outputs[i]->possible_clones <<= 1;
5423 }
5424
5425 if (xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE)) {
5426 memmove(outputs + 1, outputs, sizeof(output)*config->num_output);
5427 outputs[0] = output;
5428 } else
5429 outputs[i] = output;
5430 sna->mode.num_real_output++;
5431 config->num_output++;
5432 config->output = outputs;
5433
5434 reset:
5435 sna_output->id = compat_conn.conn.connector_id;
5436 sna_output->is_panel = is_panel(compat_conn.conn.connector_type);
5437 sna_output->edid_idx = find_property(sna, sna_output, "EDID");
5438 sna_output->link_status_idx =
5439 find_property(sna, sna_output, "link-status");
5440 if (find_property(sna, sna_output, "scaling mode") != -1)
5441 sna_output->add_default_modes =
5442 xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
5443
5444 i = find_property(sna, sna_output, "DPMS");
5445 if (i != -1) {
5446 sna_output->dpms_id = sna_output->prop_ids[i];
5447 sna_output->dpms_mode = sna_output->prop_values[i];
5448 DBG(("%s: found 'DPMS' (idx=%d, id=%d), initial value=%d\n",
5449 __FUNCTION__, i, sna_output->dpms_id, sna_output->dpms_mode));
5450 } else
5451 sna_output->dpms_mode = DPMSModeOff;
5452
5453 sna_output->possible_encoders = possible_encoders;
5454 sna_output->attached_encoders = attached_encoders;
5455
5456 output->mm_width = compat_conn.conn.mm_width;
5457 output->mm_height = compat_conn.conn.mm_height;
5458
5459 if (compat_conn.conn.subpixel >= ARRAY_SIZE(subpixel_conv_table))
5460 compat_conn.conn.subpixel = 0;
5461 output->subpixel_order = subpixel_conv_table[compat_conn.conn.subpixel];
5462 output->driver_private = sna_output;
5463 sna_output->base = output;
5464
5465 backlight_init(&sna_output->backlight);
5466 sna_output_backlight_init(output);
5467
5468 output->possible_crtcs = possible_crtcs & count_to_mask(sna->mode.num_real_crtc);
5469 output->interlaceAllowed = TRUE;
5470
5471 sna_output_load_fake_edid(output);
5472
5473 if (serial) {
5474 if (output->randr_output == NULL) {
5475 output->randr_output = RROutputCreate(xf86ScrnToScreen(scrn), name, len, output);
5476 if (output->randr_output == NULL)
5477 goto cleanup;
5478 }
5479
5480 RROutputChanged(output->randr_output, TRUE);
5481 sna_output_create_resources(output);
5482 RRPostPendingProperties(output->randr_output);
5483
5484 sna_output->serial = serial;
5485 } else {
5486 /* stash the active CRTC id for our probe function */
5487 if (compat_conn.conn.connection != DRM_MODE_DISCONNECTED)
5488 output->crtc = (void *)(uintptr_t)enc.crtc_id;
5489 }
5490
5491 DBG(("%s: created output '%s' %d, encoder=%d (possible crtc:%x, attached encoders:%x, possible clones:%x), serial=%d, edid=%d, dpms=%d, crtc=%lu\n",
5492 __FUNCTION__, name, id, enc.encoder_id,
5493 (uint32_t)output->possible_crtcs,
5494 sna_output->attached_encoders,
5495 sna_output->possible_encoders,
5496 serial, sna_output->edid_idx, sna_output->dpms_id,
5497 (unsigned long)(uintptr_t)output->crtc));
5498 assert(sna_output->id == id);
5499
5500 xf86DrvMsg(scrn->scrnIndex, X_INFO,
5501 "Enabled output %s\n",
5502 output->name);
5503 return 1;
5504
5505 cleanup:
5506 len = -1;
5507 skip:
5508 free(sna_output->prop_ids);
5509 free(sna_output->prop_values);
5510 free(sna_output);
5511 return len;
5512 }
5513
output_rank(const void * A,const void * B)5514 static int output_rank(const void *A, const void *B)
5515 {
5516 const xf86OutputPtr *a = A;
5517 const xf86OutputPtr *b = B;
5518 struct sna_output *sa = to_sna_output(*a);
5519 struct sna_output *sb = to_sna_output(*b);
5520
5521 if (sa->is_panel != sb->is_panel)
5522 return sb->is_panel - sa->is_panel;
5523
5524 return strcmp((*a)->name, (*b)->name);
5525 }
5526
sort_config_outputs(struct sna * sna)5527 static void sort_config_outputs(struct sna *sna)
5528 {
5529 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5530 qsort(config->output, sna->mode.num_real_output, sizeof(*config->output), output_rank);
5531 config->compat_output = 0; /* make sure it is a sane value */
5532 sna_mode_compute_possible_outputs(sna);
5533 }
5534
sort_randr_outputs(struct sna * sna,ScreenPtr screen)5535 static void sort_randr_outputs(struct sna *sna, ScreenPtr screen)
5536 {
5537 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5538 rrScrPriv(screen);
5539 int i;
5540
5541 assert(pScrPriv->numOutputs == config->num_output);
5542 for (i = 0; i < config->num_output; i++) {
5543 assert(config->output[i]->randr_output);
5544 pScrPriv->outputs[i] = config->output[i]->randr_output;
5545 }
5546 }
5547
disable_unused_crtc(struct sna * sna)5548 static bool disable_unused_crtc(struct sna *sna)
5549 {
5550 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5551 bool update = false;
5552 int o, c;
5553
5554 DBG(("%s\n", __FUNCTION__));
5555
5556 for (c = 0; c < sna->mode.num_real_crtc; c++) {
5557 xf86CrtcPtr crtc = config->crtc[c];
5558
5559 if (!crtc->enabled) {
5560 sna_crtc_disable(crtc, false);
5561 continue;
5562 }
5563
5564 for (o = 0; o < sna->mode.num_real_output; o++) {
5565 xf86OutputPtr output = config->output[o];
5566 if (output->crtc == crtc)
5567 break;
5568 }
5569
5570 if (o == sna->mode.num_real_output) {
5571 DBG(("%s: CRTC:%d was enabled with no outputs\n",
5572 __FUNCTION__, sna_crtc_id(crtc)));
5573 crtc->enabled = false;
5574 update = true;
5575 }
5576 }
5577
5578 if (update) {
5579 DBG(("%s: disabling unused functions\n", __FUNCTION__));
5580 xf86DisableUnusedFunctions(sna->scrn);
5581 }
5582
5583 return update;
5584 }
5585
sna_mode_find_hotplug_connector(struct sna * sna,unsigned id)5586 bool sna_mode_find_hotplug_connector(struct sna *sna, unsigned id)
5587 {
5588 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5589 int i;
5590
5591 for (i = 0; i < sna->mode.num_real_output; i++) {
5592 struct sna_output *output = to_sna_output(config->output[i]);
5593 if (output->id == id) {
5594 output->reprobe = true;
5595 return true;
5596 }
5597 }
5598
5599 return false;
5600 }
5601
5602 static bool
output_retrain_link(struct sna * sna,struct sna_output * output)5603 output_retrain_link(struct sna *sna, struct sna_output *output)
5604 {
5605 struct sna_crtc *crtc = to_sna_crtc(output->base->crtc);
5606 int crtc_x = crtc->offset & 0xffff;
5607 int crtc_y = crtc->offset >> 16;
5608
5609 if (!crtc->bo)
5610 return false;
5611
5612 return sna_crtc_flip(sna, crtc, crtc->bo, crtc_x, crtc_y);
5613 }
5614
5615 static bool
output_check_link(struct sna * sna,struct sna_output * output)5616 output_check_link(struct sna *sna, struct sna_output *output)
5617 {
5618 uint64_t link_status;
5619
5620 if (!output->base->crtc)
5621 return true;
5622
5623 if (output->link_status_idx == -1)
5624 return true;
5625
5626 #define LINK_STATUS_GOOD 0
5627 link_status = output->prop_values[output->link_status_idx];
5628 DBG(("%s: link_status=%d\n", __FUNCTION__, link_status));
5629 if (link_status == LINK_STATUS_GOOD)
5630 return true;
5631
5632 /* Perform a modeset as required for "link-status" = BAD */
5633 if (!output_retrain_link(sna, output))
5634 return false;
5635
5636 /* Query the "link-status" again to confirm the modeset */
5637 update_properties(sna, output);
5638
5639 link_status = output->prop_values[output->link_status_idx];
5640 DBG(("%s: link_status=%d after modeset\n", __FUNCTION__, link_status));
5641 return link_status == LINK_STATUS_GOOD;
5642 }
5643
5644 static bool
output_check_status(struct sna * sna,struct sna_output * output)5645 output_check_status(struct sna *sna, struct sna_output *output)
5646 {
5647 union compat_mode_get_connector compat_conn;
5648 struct drm_mode_modeinfo dummy;
5649 struct drm_mode_get_blob blob;
5650 xf86OutputStatus status;
5651 char *edid;
5652
5653 VG_CLEAR(compat_conn);
5654
5655 compat_conn.conn.connection = -1;
5656 compat_conn.conn.connector_id = output->id;
5657 compat_conn.conn.count_modes = 1; /* skip detect */
5658 compat_conn.conn.modes_ptr = (uintptr_t)&dummy;
5659 compat_conn.conn.count_encoders = 0;
5660 compat_conn.conn.props_ptr = (uintptr_t)output->prop_ids;
5661 compat_conn.conn.prop_values_ptr = (uintptr_t)output->prop_values;
5662 compat_conn.conn.count_props = output->num_props;
5663
5664 if (drmIoctl(sna->kgem.fd,
5665 DRM_IOCTL_MODE_GETCONNECTOR,
5666 &compat_conn.conn) == 0)
5667 output->update_properties = false;
5668
5669 if (!output_check_link(sna, output))
5670 return false;
5671
5672 if (output->reprobe)
5673 return false;
5674
5675 switch (compat_conn.conn.connection) {
5676 case DRM_MODE_CONNECTED:
5677 status = XF86OutputStatusConnected;
5678 break;
5679 case DRM_MODE_DISCONNECTED:
5680 status = XF86OutputStatusDisconnected;
5681 break;
5682 default:
5683 case DRM_MODE_UNKNOWNCONNECTION:
5684 status = XF86OutputStatusUnknown;
5685 break;
5686 }
5687 if (output->status != status)
5688 return false;
5689
5690 if (status != XF86OutputStatusConnected)
5691 return true;
5692
5693 if (output->num_modes != compat_conn.conn.count_modes)
5694 return false;
5695
5696 if (output->edid_len == 0)
5697 return false;
5698
5699 edid = alloca(output->edid_len);
5700
5701 VG_CLEAR(blob);
5702 blob.blob_id = output->prop_values[output->edid_idx];
5703 blob.length = output->edid_len;
5704 blob.data = (uintptr_t)edid;
5705 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
5706 return false;
5707
5708 if (blob.length != output->edid_len)
5709 return false;
5710
5711 return memcmp(edid, output->edid_raw, output->edid_len) == 0;
5712 }
5713
sna_mode_discover(struct sna * sna,bool tell)5714 void sna_mode_discover(struct sna *sna, bool tell)
5715 {
5716 ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
5717 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5718 bool force = sna->flags & SNA_REPROBE;
5719 struct drm_mode_card_res res;
5720 uint32_t connectors[32], now;
5721 unsigned changed = 0;
5722 unsigned serial;
5723 int i, j;
5724
5725 DBG(("%s()\n", __FUNCTION__));
5726 sna->flags &= ~SNA_REPROBE;
5727
5728 VG_CLEAR(connectors);
5729
5730 memset(&res, 0, sizeof(res));
5731 res.count_connectors = 32;
5732 res.connector_id_ptr = (uintptr_t)connectors;
5733
5734 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
5735 return;
5736
5737 DBG(("%s: now %d (was %d) connectors, %d encoders, %d crtc\n", __FUNCTION__,
5738 res.count_connectors, sna->mode.num_real_output,
5739 res.count_encoders, res.count_crtcs));
5740 if (res.count_connectors > 32)
5741 res.count_connectors = 32;
5742
5743 assert(sna->mode.num_real_crtc == res.count_crtcs || is_zaphod(sna->scrn));
5744 assert(sna->mode.max_crtc_width == res.max_width);
5745 assert(sna->mode.max_crtc_height == res.max_height);
5746 assert(sna->mode.num_real_encoder == res.count_encoders);
5747
5748 serial = ++sna->mode.serial;
5749 if (serial == 0)
5750 serial = ++sna->mode.serial;
5751
5752 if (force) {
5753 changed = 4;
5754 now = 0;
5755 } else
5756 now = GetTimeInMillis();
5757 for (i = 0; i < res.count_connectors; i++) {
5758 DBG(("%s: connector[%d] = %d\n", __FUNCTION__, i, connectors[i]));
5759 for (j = 0; j < sna->mode.num_real_output; j++) {
5760 xf86OutputPtr output = config->output[j];
5761 if (to_sna_output(output)->id == connectors[i]) {
5762 DBG(("%s: found %s (id=%d)\n", __FUNCTION__, output->name, connectors[i]));
5763 assert(to_sna_output(output)->id);
5764 to_sna_output(output)->serial = serial;
5765 break;
5766 }
5767 }
5768 if (j == sna->mode.num_real_output) {
5769 DBG(("%s: adding id=%d\n", __FUNCTION__, connectors[i]));
5770 changed |= sna_output_add(sna, connectors[i], serial) > 0;
5771 }
5772 }
5773
5774 for (i = 0; i < sna->mode.num_real_output; i++) {
5775 xf86OutputPtr output = config->output[i];
5776 struct sna_output *sna_output = to_sna_output(output);
5777
5778 if (sna_output->id == 0)
5779 continue;
5780
5781 if (sna_output->serial == serial) {
5782 if (output_check_status(sna, sna_output)) {
5783 DBG(("%s: output %s (id=%d), retained state\n",
5784 __FUNCTION__, output->name, sna_output->id));
5785 sna_output->last_detect = now;
5786 } else {
5787 DBG(("%s: output %s (id=%d), changed state, reprobing\n",
5788 __FUNCTION__, output->name, sna_output->id));
5789 sna_output->hotplug_count++;
5790 sna_output->last_detect = 0;
5791 changed |= 4;
5792 }
5793 continue;
5794 }
5795
5796 DBG(("%s: removing output %s (id=%d), serial=%u [now %u]\n",
5797 __FUNCTION__, output->name, sna_output->id,
5798 sna_output->serial, serial));
5799
5800 xf86DrvMsg(sna->scrn->scrnIndex, X_INFO,
5801 "Disabled output %s\n",
5802 output->name);
5803 sna_output->id = 0;
5804 sna_output->last_detect = 0;
5805 output->crtc = NULL;
5806 RROutputChanged(output->randr_output, TRUE);
5807 changed |= 2;
5808 }
5809
5810 /* Have the list of available outputs been updated? */
5811 if (changed & 3) {
5812 DBG(("%s: outputs changed, broadcasting\n", __FUNCTION__));
5813
5814 sna_mode_set_primary(sna);
5815
5816 /* Reorder user visible listing */
5817 sort_config_outputs(sna);
5818 sort_randr_outputs(sna, screen);
5819
5820 if (changed & 2)
5821 disable_unused_crtc(sna);
5822
5823 xf86RandR12TellChanged(screen);
5824 }
5825
5826 /* If anything has changed, refresh the RandR information.
5827 * Note this could recurse once from udevless RRGetInfo() probes,
5828 * but only once.
5829 */
5830 if (changed && tell)
5831 RRGetInfo(screen, TRUE);
5832 }
5833
5834 /* Since we only probe the current mode on startup, we may not have the full
5835 * list of modes available until the user explicitly requests them. Fake a
5836 * hotplug event after a second after starting to fill in any missing modes.
5837 */
sna_mode_coldplug(OsTimerPtr timer,CARD32 now,void * data)5838 CARD32 sna_mode_coldplug(OsTimerPtr timer, CARD32 now, void *data)
5839 {
5840 struct sna *sna = data;
5841 ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
5842 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
5843 bool reprobe = false;
5844 int i;
5845
5846 DBG(("%s()\n", __FUNCTION__));
5847
5848 for (i = 0; i < sna->mode.num_real_output; i++) {
5849 xf86OutputPtr output = config->output[i];
5850 struct sna_output *sna_output = to_sna_output(output);
5851
5852 if (sna_output->id == 0)
5853 continue;
5854 if (sna_output->last_detect)
5855 continue;
5856 if (output->status == XF86OutputStatusDisconnected)
5857 continue;
5858
5859 DBG(("%s: output %s connected, needs reprobe\n",
5860 __FUNCTION__, output->name));
5861 reprobe = true;
5862 }
5863
5864 if (reprobe) {
5865 RRGetInfo(screen, TRUE);
5866 RRTellChanged(screen);
5867 }
5868 free(timer);
5869 return 0;
5870 }
5871
copy_front(struct sna * sna,PixmapPtr old,PixmapPtr new)5872 static void copy_front(struct sna *sna, PixmapPtr old, PixmapPtr new)
5873 {
5874 struct sna_pixmap *old_priv, *new_priv;
5875
5876 DBG(("%s\n", __FUNCTION__));
5877
5878 if (wedged(sna) || isGPU(sna->scrn))
5879 return;
5880
5881 old_priv = sna_pixmap_force_to_gpu(old, MOVE_READ);
5882 if (!old_priv)
5883 return;
5884
5885 new_priv = sna_pixmap_force_to_gpu(new, MOVE_WRITE | __MOVE_SCANOUT);
5886 if (!new_priv)
5887 return;
5888
5889 if (old_priv->clear) {
5890 bool ok = false;
5891 if (!wedged(sna))
5892 ok = sna->render.fill_one(sna, new, new_priv->gpu_bo,
5893 old_priv->clear_color,
5894 0, 0,
5895 new->drawable.width,
5896 new->drawable.height,
5897 GXcopy);
5898 if (!ok) {
5899 void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
5900 if (ptr)
5901 memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
5902 }
5903 new_priv->clear = true;
5904 new_priv->clear_color = old_priv->clear_color;
5905 } else {
5906 BoxRec box;
5907 int16_t sx, sy, dx, dy;
5908
5909 if (new->drawable.width >= old->drawable.width &&
5910 new->drawable.height >= old->drawable.height)
5911 {
5912 int nx = (new->drawable.width + old->drawable.width - 1) / old->drawable.width;
5913 int ny = (new->drawable.height + old->drawable.height - 1) / old->drawable.height;
5914
5915 box.x1 = box.y1 = 0;
5916
5917 dy = 0;
5918 for (sy = 0; sy < ny; sy++) {
5919 box.y2 = old->drawable.height;
5920 if (box.y2 + dy > new->drawable.height)
5921 box.y2 = new->drawable.height - dy;
5922
5923 dx = 0;
5924 for (sx = 0; sx < nx; sx++) {
5925 box.x2 = old->drawable.width;
5926 if (box.x2 + dx > new->drawable.width)
5927 box.x2 = new->drawable.width - dx;
5928
5929 (void)sna->render.copy_boxes(sna, GXcopy,
5930 &old->drawable, old_priv->gpu_bo, 0, 0,
5931 &new->drawable, new_priv->gpu_bo, dx, dy,
5932 &box, 1, 0);
5933 dx += old->drawable.width;
5934 }
5935 dy += old->drawable.height;
5936 }
5937 } else {
5938 box.x1 = box.y1 = 0;
5939 box.x2 = min(old->drawable.width, new->drawable.width);
5940 box.y2 = min(old->drawable.height, new->drawable.height);
5941
5942 sx = dx = 0;
5943 if (box.x2 < old->drawable.width)
5944 sx = (old->drawable.width - box.x2) / 2;
5945 if (box.x2 < new->drawable.width)
5946 dx = (new->drawable.width - box.x2) / 2;
5947
5948 sy = dy = 0;
5949 if (box.y2 < old->drawable.height)
5950 sy = (old->drawable.height - box.y2) / 2;
5951 if (box.y2 < new->drawable.height)
5952 dy = (new->drawable.height - box.y2) / 2;
5953
5954 DBG(("%s: copying box (%dx%d) from (%d, %d) to (%d, %d)\n",
5955 __FUNCTION__, box.x2, box.y2, sx, sy, dx, dy));
5956
5957 if (box.x2 != new->drawable.width || box.y2 != new->drawable.height) {
5958 bool ok = false;
5959 if (!wedged(sna))
5960 ok = sna->render.fill_one(sna, new, new_priv->gpu_bo, 0,
5961 0, 0,
5962 new->drawable.width,
5963 new->drawable.height,
5964 GXclear);
5965 if (!ok) {
5966 void *ptr = kgem_bo_map__gtt(&sna->kgem, new_priv->gpu_bo);
5967 if (ptr)
5968 memset(ptr, 0, new_priv->gpu_bo->pitch*new->drawable.height);
5969 }
5970 }
5971 (void)sna->render.copy_boxes(sna, GXcopy,
5972 &old->drawable, old_priv->gpu_bo, sx, sy,
5973 &new->drawable, new_priv->gpu_bo, dx, dy,
5974 &box, 1, 0);
5975 }
5976 }
5977
5978 sna_damage_all(&new_priv->gpu_damage, new);
5979 }
5980
5981 static Bool
sna_mode_resize(ScrnInfoPtr scrn,int width,int height)5982 sna_mode_resize(ScrnInfoPtr scrn, int width, int height)
5983 {
5984 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
5985 struct sna *sna = to_sna(scrn);
5986 ScreenPtr screen = xf86ScrnToScreen(scrn);
5987 PixmapPtr new_front;
5988 int i;
5989
5990 DBG(("%s (%d, %d) -> (%d, %d)\n", __FUNCTION__,
5991 scrn->virtualX, scrn->virtualY,
5992 width, height));
5993 assert((sna->flags & SNA_IS_HOSTED) == 0);
5994
5995 if (scrn->virtualX == width && scrn->virtualY == height)
5996 return TRUE;
5997
5998 /* Paranoid defense against rogue internal calls by Xorg */
5999 if (width == 0 || height == 0)
6000 return FALSE;
6001
6002 assert(sna->front);
6003 assert(screen->GetScreenPixmap(screen) == sna->front);
6004
6005 DBG(("%s: creating new framebuffer %dx%d\n",
6006 __FUNCTION__, width, height));
6007
6008 new_front = screen->CreatePixmap(screen,
6009 width, height, scrn->depth,
6010 SNA_CREATE_FB);
6011 if (!new_front)
6012 return FALSE;
6013
6014 xf86DrvMsg(scrn->scrnIndex, X_INFO,
6015 "resizing framebuffer to %dx%d\n",
6016 width, height);
6017
6018 for (i = 0; i < sna->mode.num_real_crtc; i++)
6019 sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i]));
6020 assert(sna->mode.shadow_active == 0);
6021 assert(!sna->mode.shadow_enabled);
6022 assert(sna->mode.shadow_damage == NULL);
6023 assert(sna->mode.shadow == NULL);
6024
6025 /* Flush pending shadow updates */
6026 if (sna->mode.flip_active) {
6027 DBG(("%s: waiting for %d outstanding TearFree flips\n",
6028 __FUNCTION__, sna->mode.flip_active));
6029 while (sna->mode.flip_active && sna_mode_wait_for_event(sna))
6030 sna_mode_wakeup(sna);
6031 }
6032
6033 /* Cancel a pending [un]flip (as the pixmaps no longer match) */
6034 sna_present_cancel_flip(sna);
6035 copy_front(sna, sna->front, new_front);
6036
6037 screen->SetScreenPixmap(new_front);
6038 assert(screen->GetScreenPixmap(screen) == new_front);
6039 assert(sna->front == new_front);
6040 screen->DestroyPixmap(new_front); /* owned by screen now */
6041
6042 scrn->virtualX = width;
6043 scrn->virtualY = height;
6044 scrn->displayWidth = width;
6045
6046 /* Only update the CRTCs if we are in control */
6047 if (!scrn->vtSema)
6048 return TRUE;
6049
6050 for (i = 0; i < sna->mode.num_real_crtc; i++) {
6051 xf86CrtcPtr crtc = config->crtc[i];
6052
6053 assert(to_sna_crtc(crtc) != NULL);
6054 if (to_sna_crtc(crtc)->bo == NULL)
6055 continue;
6056
6057 if (!__sna_crtc_set_mode(crtc))
6058 sna_crtc_disable(crtc, false);
6059 }
6060
6061 sna_mode_wakeup(sna);
6062 kgem_clean_scanout_cache(&sna->kgem);
6063
6064 return TRUE;
6065 }
6066
6067 /* cursor handling */
6068 static void
rotate_coord(Rotation rotation,int size,int x_dst,int y_dst,int * x_src,int * y_src)6069 rotate_coord(Rotation rotation, int size,
6070 int x_dst, int y_dst,
6071 int *x_src, int *y_src)
6072 {
6073 int t;
6074
6075 switch (rotation & 0xf) {
6076 case RR_Rotate_0:
6077 break;
6078 case RR_Rotate_90:
6079 t = x_dst;
6080 x_dst = size - y_dst - 1;
6081 y_dst = t;
6082 break;
6083 case RR_Rotate_180:
6084 x_dst = size - x_dst - 1;
6085 y_dst = size - y_dst - 1;
6086 break;
6087 case RR_Rotate_270:
6088 t = x_dst;
6089 x_dst = y_dst;
6090 y_dst = size - t - 1;
6091 break;
6092 }
6093
6094 if (rotation & RR_Reflect_X)
6095 x_dst = size - x_dst - 1;
6096 if (rotation & RR_Reflect_Y)
6097 y_dst = size - y_dst - 1;
6098
6099 *x_src = x_dst;
6100 *y_src = y_dst;
6101 }
6102
__sna_create_cursor(struct sna * sna,int size)6103 static struct sna_cursor *__sna_create_cursor(struct sna *sna, int size)
6104 {
6105 struct sna_cursor *c;
6106
6107 for (c = sna->cursor.cursors; c; c = c->next) {
6108 if (c->ref == 0 && c->alloc >= size) {
6109 __DBG(("%s: stealing handle=%d, serial=%d, rotation=%d, alloc=%d\n",
6110 __FUNCTION__, c->handle, c->serial, c->rotation, c->alloc));
6111 return c;
6112 }
6113 }
6114
6115 __DBG(("%s(size=%d, num_stash=%d)\n", __FUNCTION__, size, sna->cursor.num_stash));
6116
6117 c = sna->cursor.stash;
6118 assert(c);
6119
6120 c->alloc = ALIGN(size, 4096);
6121 c->handle = gem_create(sna->kgem.fd, c->alloc);
6122 if (c->handle == 0)
6123 return NULL;
6124
6125 /* Old hardware uses physical addresses, which the kernel
6126 * implements in an incoherent fashion requiring a pwrite.
6127 */
6128 if (sna->cursor.use_gtt) {
6129 c->image = gem_mmap(sna->kgem.fd, c->handle, c->alloc);
6130 if (c->image == NULL) {
6131 gem_close(sna->kgem.fd, c->handle);
6132 return NULL;
6133 }
6134 } else
6135 c->image = NULL;
6136
6137 __DBG(("%s: handle=%d, allocated %d\n", __FUNCTION__, c->handle, size));
6138
6139 c->ref = 0;
6140 c->serial = 0;
6141 c->rotation = 0;
6142 c->last_width = c->last_height = 0; /* all clear */
6143 c->size = size;
6144
6145 sna->cursor.num_stash--;
6146 sna->cursor.stash = c->next;
6147
6148 c->next = sna->cursor.cursors;
6149 sna->cursor.cursors = c;
6150
6151 return c;
6152 }
6153
get_cursor_argb(CursorPtr c)6154 static uint32_t *get_cursor_argb(CursorPtr c)
6155 {
6156 #ifdef ARGB_CURSOR
6157 return (uint32_t *)c->bits->argb;
6158 #else
6159 return NULL;
6160 #endif
6161 }
6162
__cursor_size(int width,int height)6163 static int __cursor_size(int width, int height)
6164 {
6165 int i, size;
6166
6167 i = MAX(width, height);
6168 for (size = 64; size < i; size <<= 1)
6169 ;
6170
6171 return size;
6172 }
6173
__sna_get_cursor(struct sna * sna,xf86CrtcPtr crtc)6174 static struct sna_cursor *__sna_get_cursor(struct sna *sna, xf86CrtcPtr crtc)
6175 {
6176 struct sna_cursor *cursor;
6177 const uint8_t *source, *mask;
6178 const uint32_t *argb;
6179 uint32_t *image;
6180 int width, height, pitch, size, x, y;
6181 bool transformed;
6182 Rotation rotation;
6183
6184 assert(sna->cursor.ref);
6185
6186 cursor = to_sna_crtc(crtc)->cursor;
6187 __DBG(("%s: current cursor handle=%d, serial=%d [expected %d]\n",
6188 __FUNCTION__,
6189 cursor ? cursor->handle : 0,
6190 cursor ? cursor->serial : 0,
6191 sna->cursor.serial));
6192 if (cursor && cursor->serial == sna->cursor.serial) {
6193 assert(cursor->size == sna->cursor.size || cursor->transformed);
6194 assert(cursor->rotation == (!to_sna_crtc(crtc)->cursor_transform && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0);
6195 assert(cursor->ref);
6196 return cursor;
6197 }
6198
6199 __DBG(("%s: cursor=%dx%d, pitch=%d, serial=%d, argb?=%d\n", __FUNCTION__,
6200 sna->cursor.ref->bits->width,
6201 sna->cursor.ref->bits->height,
6202 get_cursor_argb(sna->cursor.ref) ? 4*sna->cursor.ref->bits->width : BitmapBytePad(sna->cursor.ref->bits->width),
6203 sna->cursor.serial,
6204 get_cursor_argb(sna->cursor.ref) != NULL));
6205
6206 transformed = to_sna_crtc(crtc)->cursor_transform;
6207 rotation = (!transformed && crtc->transform_in_use) ? crtc->rotation : RR_Rotate_0;
6208
6209 if (transformed) {
6210 struct pixman_box16 box;
6211
6212 box.x1 = box.y1 = 0;
6213 box.x2 = sna->cursor.ref->bits->width;
6214 box.y2 = sna->cursor.ref->bits->height;
6215
6216 pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer, &box);
6217 size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
6218 __DBG(("%s: transformed cursor %dx%d -> %dx%d\n",
6219 __FUNCTION__ ,
6220 sna->cursor.ref->bits->width,
6221 sna->cursor.ref->bits->height,
6222 box.x2 - box.x1, box.y2 - box.y1));
6223 } else
6224 size = sna->cursor.size;
6225
6226 if (crtc->transform_in_use) {
6227 RRTransformPtr T = NULL;
6228 struct pixman_vector v;
6229
6230 if (crtc->transformPresent) {
6231 T = &crtc->transform;
6232
6233 /* Cancel any translation from this affine
6234 * transformation. We just want to rotate and scale
6235 * the cursor image.
6236 */
6237 v.vector[0] = 0;
6238 v.vector[1] = 0;
6239 v.vector[2] = pixman_fixed_1;
6240 pixman_transform_point(&crtc->transform.transform, &v);
6241 }
6242
6243 RRTransformCompute(0, 0, size, size, crtc->rotation, T, NULL,
6244 &to_sna_crtc(crtc)->cursor_to_fb,
6245 &to_sna_crtc(crtc)->fb_to_cursor);
6246 if (T)
6247 pixman_f_transform_translate(
6248 &to_sna_crtc(crtc)->cursor_to_fb,
6249 &to_sna_crtc(crtc)->fb_to_cursor,
6250 -pixman_fixed_to_double(v.vector[0]),
6251 -pixman_fixed_to_double(v.vector[1]));
6252
6253 __DBG(("%s: cursor_to_fb [%f %f %f, %f %f %f, %f %f %f]\n",
6254 __FUNCTION__,
6255 to_sna_crtc(crtc)->cursor_to_fb.m[0][0],
6256 to_sna_crtc(crtc)->cursor_to_fb.m[0][1],
6257 to_sna_crtc(crtc)->cursor_to_fb.m[0][2],
6258 to_sna_crtc(crtc)->cursor_to_fb.m[1][0],
6259 to_sna_crtc(crtc)->cursor_to_fb.m[1][1],
6260 to_sna_crtc(crtc)->cursor_to_fb.m[1][2],
6261 to_sna_crtc(crtc)->cursor_to_fb.m[2][0],
6262 to_sna_crtc(crtc)->cursor_to_fb.m[2][1],
6263 to_sna_crtc(crtc)->cursor_to_fb.m[2][2]));
6264 }
6265
6266 /* Don't allow phys cursor sharing */
6267 if (sna->cursor.use_gtt && !transformed) {
6268 for (cursor = sna->cursor.cursors; cursor; cursor = cursor->next) {
6269 if (cursor->serial == sna->cursor.serial &&
6270 cursor->rotation == rotation &&
6271 !cursor->transformed) {
6272 __DBG(("%s: reusing handle=%d, serial=%d, rotation=%d, size=%d\n",
6273 __FUNCTION__, cursor->handle, cursor->serial, cursor->rotation, cursor->size));
6274 assert(cursor->size == sna->cursor.size);
6275 return cursor;
6276 }
6277 }
6278 }
6279
6280 cursor = to_sna_crtc(crtc)->cursor;
6281 if (cursor && cursor->alloc < 4*size*size)
6282 cursor = NULL;
6283
6284 if (cursor == NULL) {
6285 cursor = __sna_create_cursor(sna, 4*size*size);
6286 if (cursor == NULL) {
6287 DBG(("%s: failed to allocate cursor\n", __FUNCTION__));
6288 return NULL;
6289 }
6290 }
6291
6292 width = sna->cursor.ref->bits->width;
6293 height = sna->cursor.ref->bits->height;
6294 source = sna->cursor.ref->bits->source;
6295 mask = sna->cursor.ref->bits->mask;
6296 argb = get_cursor_argb(sna->cursor.ref);
6297 pitch = BitmapBytePad(width);
6298
6299 image = cursor->image;
6300 if (image == NULL || transformed) {
6301 image = sna->cursor.scratch;
6302 cursor->last_width = cursor->last_height = size;
6303 }
6304 if (size > cursor->size ||
6305 width < cursor->last_width ||
6306 height < cursor->last_height ||
6307 rotation != cursor->rotation)
6308 memset(image, 0, 4*size*size);
6309 if (rotation == RR_Rotate_0) {
6310 if (argb == NULL) {
6311 for (y = 0; y < height; y++) {
6312 uint32_t *p = image + y*size;
6313 for (x = 0; x < width; x++) {
6314 int byte = x / 8;
6315 uint8_t bit = 1 << (x & 7);
6316 uint32_t pixel;
6317
6318 if (mask[byte] & bit) {
6319 if (source[byte] & bit)
6320 pixel = sna->cursor.fg;
6321 else
6322 pixel = sna->cursor.bg;
6323 } else
6324 pixel = 0;
6325
6326 *p++ = pixel;
6327 }
6328 mask += pitch;
6329 source += pitch;
6330 }
6331 if (transformed) {
6332 __DBG(("%s: Applying affine BLT to bitmap\n", __FUNCTION__));
6333 affine_blt(image, cursor->image, 32,
6334 0, 0, width, height, size * 4,
6335 0, 0, size, size, size * 4,
6336 &to_sna_crtc(crtc)->cursor_to_fb);
6337 image = cursor->image;
6338 }
6339 } else if (transformed) {
6340 __DBG(("%s: Applying affine BLT to ARGB\n", __FUNCTION__));
6341 affine_blt(argb, cursor->image, 32,
6342 0, 0, width, height, width * 4,
6343 0, 0, size, size, size * 4,
6344 &to_sna_crtc(crtc)->cursor_to_fb);
6345 image = cursor->image;
6346 } else
6347 memcpy_blt(argb, image, 32,
6348 width * 4, size * 4,
6349 0, 0,
6350 0, 0,
6351 width, height);
6352 } else {
6353 for (y = 0; y < size; y++)
6354 for (x = 0; x < size; x++) {
6355 uint32_t pixel;
6356 int xin, yin;
6357
6358 rotate_coord(rotation, size, x, y, &xin, &yin);
6359 if (xin < width && yin < height)
6360 if (argb == NULL) {
6361 int byte = xin / 8;
6362 int bit = xin & 7;
6363 if (mask[yin*pitch + byte] & (1 << bit)) {
6364 if (source[yin*pitch + byte] & (1 << bit))
6365 pixel = sna->cursor.fg;
6366 else
6367 pixel = sna->cursor.bg;
6368 } else
6369 pixel = 0;
6370 } else
6371 pixel = argb[yin * width + xin];
6372 else
6373 pixel = 0;
6374 image[y * size + x] = pixel;
6375 }
6376 }
6377
6378 if (image != cursor->image) {
6379 struct drm_i915_gem_pwrite pwrite;
6380
6381 VG_CLEAR(pwrite);
6382 pwrite.handle = cursor->handle;
6383 pwrite.offset = 0;
6384 pwrite.size = 4*size*size;
6385 pwrite.data_ptr = (uintptr_t)image;
6386 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite))
6387 __DBG(("%s: cursor update (pwrite) failed: %d\n", __FUNCTION__, errno));
6388 }
6389
6390 cursor->size = size;
6391 cursor->rotation = rotation;
6392 cursor->transformed = transformed;
6393 cursor->serial = sna->cursor.serial;
6394 if (transformed) {
6395 /* mark the transformed rectangle as dirty, not input */
6396 cursor->last_width = size;
6397 cursor->last_height = size;
6398 } else {
6399 cursor->last_width = width;
6400 cursor->last_height = height;
6401 }
6402 return cursor;
6403 }
6404
6405 static unsigned char *
sna_realize_cursor(xf86CursorInfoPtr info,CursorPtr cursor)6406 sna_realize_cursor(xf86CursorInfoPtr info, CursorPtr cursor)
6407 {
6408 return NULL;
6409 }
6410
__restore_swcursor(ScrnInfoPtr scrn)6411 static void __restore_swcursor(ScrnInfoPtr scrn)
6412 {
6413 struct sna *sna = to_sna(scrn);
6414
6415 DBG(("%s: attempting to restore SW cursor\n", __FUNCTION__));
6416 xf86CursorResetCursor(scrn->pScreen);
6417
6418 /* Try to switch back to the HW cursor on the next cursor update */
6419 sna->cursor.disable = false;
6420
6421 RemoveBlockAndWakeupHandlers((void *)__restore_swcursor,
6422 (void *)NoopDDA,
6423 scrn);
6424 }
6425
restore_swcursor(struct sna * sna)6426 static void restore_swcursor(struct sna *sna)
6427 {
6428 sna->cursor.info->HideCursor(sna->scrn);
6429
6430 /* XXX Force the cursor to be restored (avoiding recursion) */
6431 FreeCursor(sna->cursor.ref, None);
6432 sna->cursor.ref = NULL;
6433
6434 RegisterBlockAndWakeupHandlers((void *)__restore_swcursor,
6435 (void *)NoopDDA,
6436 sna->scrn);
6437 }
6438
6439 static void
sna_show_cursors(ScrnInfoPtr scrn)6440 sna_show_cursors(ScrnInfoPtr scrn)
6441 {
6442 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6443 struct sna *sna = to_sna(scrn);
6444 struct kmsg kmsg;
6445 int sigio, c;
6446
6447 DBG(("%s: cursor?=%d\n", __FUNCTION__, sna->cursor.ref != NULL));
6448 if (sna->cursor.ref == NULL)
6449 return;
6450
6451 kmsg_open(&kmsg);
6452 sigio = sigio_block();
6453 for (c = 0; c < sna->mode.num_real_crtc; c++) {
6454 xf86CrtcPtr crtc = xf86_config->crtc[c];
6455 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6456 struct drm_mode_cursor arg;
6457 struct sna_cursor *cursor;
6458
6459 assert(sna_crtc != NULL);
6460 if (sna_crtc->bo == NULL)
6461 continue;
6462
6463 if (!crtc->cursor_in_range) {
6464 DBG(("%s: skipping cursor outside CRTC (pipe=%d)\n",
6465 __FUNCTION__, sna_crtc_pipe(crtc)));
6466 continue;
6467 }
6468
6469 cursor = __sna_get_cursor(sna, crtc);
6470 if (cursor == NULL ||
6471 (sna_crtc->cursor == cursor && sna_crtc->last_cursor_size == cursor->size)) {
6472 DBG(("%s: skipping cursor already show on CRTC (pipe=%d)\n",
6473 __FUNCTION__, sna_crtc_pipe(crtc)));
6474 continue;
6475 }
6476
6477 DBG(("%s: CRTC pipe=%d, handle->%d\n", __FUNCTION__,
6478 sna_crtc_pipe(crtc), cursor->handle));
6479
6480 VG_CLEAR(arg);
6481 arg.flags = DRM_MODE_CURSOR_BO;
6482 arg.crtc_id = __sna_crtc_id(sna_crtc);
6483 arg.width = arg.height = cursor->size;
6484 arg.handle = cursor->handle;
6485
6486 if (!FAIL_CURSOR_IOCTL &&
6487 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
6488 if (sna_crtc->cursor) {
6489 assert(sna_crtc->cursor->ref > 0);
6490 sna_crtc->cursor->ref--;
6491 }
6492 cursor->ref++;
6493 sna_crtc->cursor = cursor;
6494 sna_crtc->last_cursor_size = cursor->size;
6495 } else {
6496 ERR(("%s: failed to show cursor on CRTC:%d [pipe=%d], disabling hwcursor: errno=%d\n",
6497 __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), errno));
6498 sna->cursor.disable = true;
6499 }
6500 }
6501 sigio_unblock(sigio);
6502 sna->cursor.active = true;
6503 kmsg_close(&kmsg, sna->cursor.disable);
6504
6505 if (unlikely(sna->cursor.disable))
6506 restore_swcursor(sna);
6507 }
6508
6509 static void
sna_set_cursor_colors(ScrnInfoPtr scrn,int _bg,int _fg)6510 sna_set_cursor_colors(ScrnInfoPtr scrn, int _bg, int _fg)
6511 {
6512 struct sna *sna = to_sna(scrn);
6513 uint32_t fg = _fg, bg = _bg;
6514
6515 __DBG(("%s(bg=%08x, fg=%08x)\n", __FUNCTION__, bg, fg));
6516
6517 /* Save ARGB versions of these colors */
6518 fg |= 0xff000000;
6519 bg |= 0xff000000;
6520 if (fg == sna->cursor.fg && bg == sna->cursor.bg)
6521 return;
6522
6523 sna->cursor.fg = fg;
6524 sna->cursor.bg = bg;
6525
6526 if (sna->cursor.ref == NULL)
6527 return;
6528
6529 if (get_cursor_argb(sna->cursor.ref))
6530 return;
6531
6532 sna->cursor.serial++;
6533 __DBG(("%s: serial->%d\n", __FUNCTION__, sna->cursor.serial));
6534
6535 sna_show_cursors(scrn);
6536 }
6537
6538 static void
sna_crtc_disable_cursor(struct sna * sna,struct sna_crtc * crtc)6539 sna_crtc_disable_cursor(struct sna *sna, struct sna_crtc *crtc)
6540 {
6541 struct drm_mode_cursor arg;
6542 int sigio;
6543
6544 if (!crtc->cursor)
6545 return;
6546
6547 sigio = sigio_block();
6548 if (crtc->cursor) {
6549 DBG(("%s: CRTC:%d, handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), crtc->cursor->handle));
6550 assert(crtc->cursor->ref > 0);
6551 crtc->cursor->ref--;
6552 crtc->cursor = NULL;
6553 crtc->last_cursor_size = 0;
6554
6555 VG_CLEAR(arg);
6556 arg.flags = DRM_MODE_CURSOR_BO;
6557 arg.crtc_id = __sna_crtc_id(crtc);
6558 arg.width = arg.height = 0;
6559 arg.handle = 0;
6560
6561 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg);
6562 }
6563 sigio_unblock(sigio);
6564 }
6565
6566 static void
sna_disable_cursors(ScrnInfoPtr scrn)6567 sna_disable_cursors(ScrnInfoPtr scrn)
6568 {
6569 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6570 struct sna *sna = to_sna(scrn);
6571 int sigio, c;
6572
6573 DBG(("%s\n", __FUNCTION__));
6574
6575 sigio = sigio_block();
6576 for (c = 0; c < sna->mode.num_real_crtc; c++) {
6577 assert(to_sna_crtc(xf86_config->crtc[c]));
6578 sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c]));
6579 }
6580 sigio_unblock(sigio);
6581 }
6582
6583 static void
sna_hide_cursors(ScrnInfoPtr scrn)6584 sna_hide_cursors(ScrnInfoPtr scrn)
6585 {
6586 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6587 struct sna *sna = to_sna(scrn);
6588 struct sna_cursor *cursor, **prev;
6589 int sigio, c;
6590
6591 DBG(("%s\n", __FUNCTION__));
6592 sna->cursor.active = false;
6593
6594 sigio = sigio_block();
6595 for (c = 0; c < sna->mode.num_real_crtc; c++) {
6596 assert(to_sna_crtc(xf86_config->crtc[c]));
6597 sna_crtc_disable_cursor(sna, to_sna_crtc(xf86_config->crtc[c]));
6598 }
6599
6600 for (prev = &sna->cursor.cursors; (cursor = *prev) != NULL; ) {
6601 assert(cursor->ref == 0);
6602
6603 if (cursor->serial == sna->cursor.serial) {
6604 prev = &cursor->next;
6605 continue;
6606 }
6607
6608 *prev = cursor->next;
6609 if (cursor->image)
6610 munmap(cursor->image, cursor->alloc);
6611 gem_close(sna->kgem.fd, cursor->handle);
6612
6613 cursor->next = sna->cursor.stash;
6614 sna->cursor.stash = cursor;
6615 sna->cursor.num_stash++;
6616 }
6617
6618 sigio_unblock(sigio);
6619 }
6620
6621 static void
sna_set_cursor_position(ScrnInfoPtr scrn,int x,int y)6622 sna_set_cursor_position(ScrnInfoPtr scrn, int x, int y)
6623 {
6624 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
6625 struct sna *sna = to_sna(scrn);
6626 struct kmsg kmsg;
6627 int sigio, c;
6628
6629 __DBG(("%s(%d, %d), cursor? %d\n", __FUNCTION__,
6630 x, y, sna->cursor.ref!=NULL));
6631 if (sna->cursor.ref == NULL)
6632 return;
6633
6634 kmsg_open(&kmsg);
6635 sigio = sigio_block();
6636 sna->cursor.last_x = x;
6637 sna->cursor.last_y = y;
6638
6639 /* undo what xf86HWCurs did to the coordinates */
6640 x += scrn->frameX0;
6641 y += scrn->frameY0;
6642 for (c = 0; c < sna->mode.num_real_crtc; c++) {
6643 xf86CrtcPtr crtc = xf86_config->crtc[c];
6644 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
6645 struct sna_cursor *cursor = NULL;
6646 struct drm_mode_cursor arg;
6647
6648 assert(sna_crtc != NULL);
6649
6650 VG_CLEAR(arg);
6651 arg.flags = 0;
6652 arg.crtc_id = __sna_crtc_id(sna_crtc);
6653 arg.handle = 0;
6654
6655 if (sna_crtc->bo == NULL)
6656 goto disable;
6657
6658 cursor = __sna_get_cursor(sna, crtc);
6659 if (cursor == NULL)
6660 cursor = sna_crtc->cursor;
6661 if (cursor == NULL) {
6662 __DBG(("%s: failed to grab cursor, disabling\n", __FUNCTION__));
6663 goto disable;
6664 }
6665
6666 if (crtc->transform_in_use) {
6667 int xhot = sna->cursor.ref->bits->xhot;
6668 int yhot = sna->cursor.ref->bits->yhot;
6669 struct pict_f_vector v, hot;
6670
6671 v.v[0] = x + xhot + .5;
6672 v.v[1] = y + yhot + .5;
6673 v.v[2] = 1.;
6674 pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &v);
6675
6676 hot.v[0] = xhot;
6677 hot.v[1] = yhot;
6678 hot.v[2] = 1.;
6679 pixman_f_transform_point(&sna_crtc->fb_to_cursor, &hot);
6680
6681 arg.x = floor(v.v[0] - hot.v[0]);
6682 arg.y = floor(v.v[1] - hot.v[1]);
6683 } else {
6684 arg.x = x - crtc->x;
6685 arg.y = y - crtc->y;
6686 }
6687
6688 if (arg.x < crtc->mode.HDisplay && arg.x > -sna->cursor.size &&
6689 arg.y < crtc->mode.VDisplay && arg.y > -sna->cursor.size) {
6690 if (sna_crtc->cursor != cursor || sna_crtc->last_cursor_size != cursor->size) {
6691 arg.flags |= DRM_MODE_CURSOR_BO;
6692 arg.handle = cursor->handle;
6693 }
6694
6695 arg.width = arg.height = cursor->size;
6696 arg.flags |= DRM_MODE_CURSOR_MOVE;
6697 crtc->cursor_in_range = true;
6698 } else {
6699 crtc->cursor_in_range = false;
6700 disable:
6701 if (sna_crtc->cursor) {
6702 arg.flags = DRM_MODE_CURSOR_BO;
6703 arg.width = arg.height = 0;
6704 }
6705 cursor = NULL;
6706 }
6707
6708 __DBG(("%s: CRTC:%d (%d, %d), handle=%d, flags=%x (old cursor handle=%d), move? %d, update handle? %d\n",
6709 __FUNCTION__, __sna_crtc_id(sna_crtc), arg.x, arg.y, arg.handle, arg.flags, sna_crtc->cursor ? sna_crtc->cursor->handle : 0,
6710 arg.flags & DRM_MODE_CURSOR_MOVE, arg.flags & DRM_MODE_CURSOR_BO));
6711
6712 if (arg.flags == 0)
6713 continue;
6714
6715 if (!FAIL_CURSOR_IOCTL &&
6716 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_CURSOR, &arg) == 0) {
6717 if (arg.flags & DRM_MODE_CURSOR_BO) {
6718 if (sna_crtc->cursor) {
6719 assert(sna_crtc->cursor->ref > 0);
6720 sna_crtc->cursor->ref--;
6721 }
6722 sna_crtc->cursor = cursor;
6723 if (cursor) {
6724 sna_crtc->last_cursor_size = cursor->size;
6725 cursor->ref++;
6726 } else
6727 sna_crtc->last_cursor_size = 0;
6728 }
6729 } else {
6730 ERR(("%s: failed to update cursor on CRTC:%d [pipe=%d], disabling hwcursor: errno=%d\n",
6731 __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), errno));
6732 /* XXX How to force switch back to SW cursor?
6733 * Right now we just want until the next cursor image
6734 * change, which is fairly frequent.
6735 */
6736 sna->cursor.disable = true;
6737 }
6738 }
6739 sigio_unblock(sigio);
6740 kmsg_close(&kmsg, sna->cursor.disable);
6741
6742 if (unlikely(sna->cursor.disable))
6743 restore_swcursor(sna);
6744 }
6745
6746 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,2)
6747 static Bool
sna_load_cursor_argb2(ScrnInfoPtr scrn,CursorPtr cursor)6748 sna_load_cursor_argb2(ScrnInfoPtr scrn, CursorPtr cursor)
6749 {
6750 return TRUE;
6751 }
6752
6753 static Bool
sna_load_cursor_image2(ScrnInfoPtr scrn,unsigned char * src)6754 sna_load_cursor_image2(ScrnInfoPtr scrn, unsigned char *src)
6755 {
6756 return TRUE;
6757 }
6758 #endif
6759
6760 static void
sna_load_cursor_argb(ScrnInfoPtr scrn,CursorPtr cursor)6761 sna_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor)
6762 {
6763 }
6764
6765 static void
sna_load_cursor_image(ScrnInfoPtr scrn,unsigned char * src)6766 sna_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src)
6767 {
6768 }
6769
6770 static bool
sna_cursor_preallocate(struct sna * sna)6771 sna_cursor_preallocate(struct sna *sna)
6772 {
6773 while (sna->cursor.num_stash < 0) {
6774 struct sna_cursor *cursor = malloc(sizeof(*cursor));
6775 if (!cursor)
6776 return false;
6777
6778 cursor->next = sna->cursor.stash;
6779 sna->cursor.stash = cursor;
6780
6781 sna->cursor.num_stash++;
6782 }
6783
6784 return true;
6785 }
6786
6787 static bool
transformable_cursor(struct sna * sna,CursorPtr cursor)6788 transformable_cursor(struct sna *sna, CursorPtr cursor)
6789 {
6790 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
6791 int i;
6792
6793 for (i = 0; i < sna->mode.num_real_crtc; i++) {
6794 xf86CrtcPtr crtc = config->crtc[i];
6795 struct pixman_box16 box;
6796 int size;
6797
6798 if (!to_sna_crtc(crtc)->hwcursor) {
6799 DBG(("%s: hwcursor disabled on CRTC:%d [pipe=%d]\n",
6800 __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc)));
6801 return false;
6802 }
6803
6804 if (!sna->cursor.use_gtt || !sna->cursor.scratch) {
6805 DBG(("%s: unable to use GTT curosor access [%d] or no scratch [%d]\n",
6806 __FUNCTION__, sna->cursor.use_gtt, sna->cursor.scratch));
6807 return false;
6808 }
6809
6810 box.x1 = box.y1 = 0;
6811 box.x2 = cursor->bits->width;
6812 box.y2 = cursor->bits->height;
6813
6814 if (!pixman_f_transform_bounds(&crtc->f_crtc_to_framebuffer,
6815 &box)) {
6816 DBG(("%s: unable to transform bounds\n", __FUNCTION__));
6817 return false;
6818 }
6819
6820 size = __cursor_size(box.x2 - box.x1, box.y2 - box.y1);
6821 if (size > sna->cursor.max_size) {
6822 DBG(("%s: transformed cursor size=%d too large, max=%d\n",
6823 __FUNCTION__, size, sna->cursor.max_size));
6824 return false;
6825 }
6826 }
6827
6828 return true;
6829 }
6830
6831 static Bool
sna_use_hw_cursor(ScreenPtr screen,CursorPtr cursor)6832 sna_use_hw_cursor(ScreenPtr screen, CursorPtr cursor)
6833 {
6834 struct sna *sna = to_sna_from_screen(screen);
6835
6836 DBG(("%s (%dx%d)?\n", __FUNCTION__,
6837 cursor->bits->width, cursor->bits->height));
6838
6839 if (sna->cursor.disable)
6840 return FALSE;
6841
6842 /* cursors are invariant */
6843 if (cursor == sna->cursor.ref)
6844 return TRUE;
6845
6846 if (sna->cursor.ref) {
6847 FreeCursor(sna->cursor.ref, None);
6848 sna->cursor.ref = NULL;
6849 }
6850
6851 sna->cursor.size =
6852 __cursor_size(cursor->bits->width, cursor->bits->height);
6853 if (sna->cursor.size > sna->cursor.max_size) {
6854 DBG(("%s: cursor size=%d too large, max %d: using sw cursor\n",
6855 __FUNCTION__, sna->cursor.size, sna->cursor.max_size));
6856 return FALSE;
6857 }
6858
6859 if (sna->mode.rr_active && !transformable_cursor(sna, cursor)) {
6860 DBG(("%s: RandR active [%d] and non-transformable cursor: using sw cursor\n",
6861 __FUNCTION__, sna->mode.rr_active));
6862 return FALSE;
6863 }
6864
6865 if (!sna_cursor_preallocate(sna)) {
6866 DBG(("%s: cursor preallocation failed: using sw cursor\n", __FUNCTION__));
6867 return FALSE;
6868 }
6869
6870 sna->cursor.ref = cursor;
6871 cursor->refcnt++;
6872 sna->cursor.serial++;
6873
6874 DBG(("%s(%dx%d): ARGB?=%d, serial->%d, size->%d\n", __FUNCTION__,
6875 cursor->bits->width,
6876 cursor->bits->height,
6877 get_cursor_argb(cursor) != NULL,
6878 sna->cursor.serial,
6879 sna->cursor.size));
6880 return TRUE;
6881 }
6882
6883 static void
sna_cursor_pre_init(struct sna * sna)6884 sna_cursor_pre_init(struct sna *sna)
6885 {
6886 struct local_get_cap {
6887 uint64_t name;
6888 uint64_t value;
6889 } cap;
6890 int v;
6891
6892 if (sna->mode.num_real_crtc == 0)
6893 return;
6894
6895 #define LOCAL_IOCTL_GET_CAP DRM_IOWR(0x0c, struct local_get_cap)
6896 #ifndef DRM_CAP_CURSOR_WIDTH
6897 #define DRM_CAP_CURSOR_WIDTH 0x8
6898 #endif
6899 #ifndef DRM_CAP_CURSOR_HEIGHT
6900 #define DRM_CAP_CURSOR_HEIGHT 0x9
6901 #endif
6902
6903 #define I915_PARAM_HAS_COHERENT_PHYS_GTT 29
6904
6905 sna->cursor.max_size = 64;
6906
6907 cap.value = 0;
6908 cap.name = DRM_CAP_CURSOR_WIDTH;
6909 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
6910 sna->cursor.max_size = cap.value;
6911
6912 cap.name = DRM_CAP_CURSOR_HEIGHT;
6913 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0 &&
6914 cap.value < sna->cursor.max_size)
6915 sna->cursor.max_size = cap.value;
6916
6917 v = -1; /* No param uses the sign bit, reserve it for errors */
6918 if (sna->kgem.gen >= 033) {
6919 v = 1;
6920 } else {
6921 drm_i915_getparam_t gp = {
6922 I915_PARAM_HAS_COHERENT_PHYS_GTT,
6923 &v,
6924 };
6925 (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp);
6926 }
6927 sna->cursor.use_gtt = v > 0;
6928 DBG(("%s: cursor updates use_gtt?=%d\n",
6929 __FUNCTION__, sna->cursor.use_gtt));
6930
6931 sna->cursor.scratch = malloc(sna->cursor.max_size * sna->cursor.max_size * 4);
6932 if (!sna->cursor.scratch && !sna->cursor.use_gtt)
6933 sna->cursor.max_size = 0;
6934
6935 sna->cursor.num_stash = -sna->mode.num_real_crtc;
6936
6937 xf86DrvMsg(sna->scrn->scrnIndex, X_PROBED,
6938 "Using a maximum size of %dx%d for hardware cursors\n",
6939 sna->cursor.max_size, sna->cursor.max_size);
6940 }
6941
6942 static void
sna_cursor_close(struct sna * sna)6943 sna_cursor_close(struct sna *sna)
6944 {
6945 sna->cursor.serial = 0;
6946 sna_hide_cursors(sna->scrn);
6947
6948 while (sna->cursor.stash) {
6949 struct sna_cursor *cursor = sna->cursor.stash;
6950 sna->cursor.stash = cursor->next;
6951 free(cursor);
6952 }
6953
6954 sna->cursor.num_stash = -sna->mode.num_real_crtc;
6955 }
6956
6957 bool
sna_cursors_init(ScreenPtr screen,struct sna * sna)6958 sna_cursors_init(ScreenPtr screen, struct sna *sna)
6959 {
6960 xf86CursorInfoPtr cursor_info;
6961
6962 if (sna->cursor.max_size == 0)
6963 return false;
6964
6965 cursor_info = xf86CreateCursorInfoRec();
6966 if (cursor_info == NULL)
6967 return false;
6968
6969 cursor_info->MaxWidth = sna->cursor.max_size;
6970 cursor_info->MaxHeight = sna->cursor.max_size;
6971 cursor_info->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
6972 HARDWARE_CURSOR_UPDATE_UNHIDDEN |
6973 HARDWARE_CURSOR_ARGB);
6974
6975 cursor_info->RealizeCursor = sna_realize_cursor;
6976 cursor_info->SetCursorColors = sna_set_cursor_colors;
6977 cursor_info->SetCursorPosition = sna_set_cursor_position;
6978 cursor_info->LoadCursorImage = sna_load_cursor_image;
6979 cursor_info->HideCursor = sna_hide_cursors;
6980 cursor_info->ShowCursor = sna_show_cursors;
6981 cursor_info->UseHWCursor = sna_use_hw_cursor;
6982 #ifdef ARGB_CURSOR
6983 cursor_info->UseHWCursorARGB = sna_use_hw_cursor;
6984 cursor_info->LoadCursorARGB = sna_load_cursor_argb;
6985 #endif
6986 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,3)
6987 cursor_info->LoadCursorImageCheck = sna_load_cursor_image2;
6988 #ifdef ARGB_CURSOR
6989 cursor_info->LoadCursorARGBCheck = sna_load_cursor_argb2;
6990 #endif
6991 #endif
6992
6993 if (!xf86InitCursor(screen, cursor_info)) {
6994 xf86DestroyCursorInfoRec(cursor_info);
6995 return false;
6996 }
6997
6998 sna->cursor.info = cursor_info;
6999 return true;
7000 }
7001
7002 static void
sna_cursors_reload(struct sna * sna)7003 sna_cursors_reload(struct sna *sna)
7004 {
7005 DBG(("%s: active?=%d\n", __FUNCTION__, sna->cursor.active));
7006 if (sna->cursor.active)
7007 sna_set_cursor_position(sna->scrn,
7008 sna->cursor.last_x,
7009 sna->cursor.last_y);
7010 }
7011
7012 static void
sna_cursors_fini(struct sna * sna)7013 sna_cursors_fini(struct sna *sna)
7014 {
7015 if (sna->cursor.info) {
7016 xf86DestroyCursorInfoRec(sna->cursor.info);
7017 sna->cursor.info = NULL;
7018 }
7019
7020 if (sna->cursor.ref) {
7021 FreeCursor(sna->cursor.ref, None);
7022 sna->cursor.ref = NULL;
7023 }
7024 }
7025
7026 static bool
sna_crtc_flip(struct sna * sna,struct sna_crtc * crtc,struct kgem_bo * bo,int x,int y)7027 sna_crtc_flip(struct sna *sna, struct sna_crtc *crtc, struct kgem_bo *bo, int x, int y)
7028 {
7029 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7030 struct drm_mode_crtc arg;
7031 uint32_t output_ids[32];
7032 int output_count = 0;
7033 int i;
7034
7035 DBG(("%s CRTC:%d [pipe=%d], handle=%d\n", __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), bo->handle));
7036
7037 assert(sna->mode.num_real_output < ARRAY_SIZE(output_ids));
7038 assert(crtc->bo);
7039 assert(crtc->kmode.clock);
7040
7041 for (i = 0; i < sna->mode.num_real_output; i++) {
7042 xf86OutputPtr output = config->output[i];
7043
7044 if (output->crtc != crtc->base)
7045 continue;
7046
7047 DBG(("%s: attaching output '%s' %d [%d] to crtc:%d (pipe %d) (possible crtc:%x, possible clones:%x)\n",
7048 __FUNCTION__, output->name, i, to_connector_id(output),
7049 __sna_crtc_id(crtc), __sna_crtc_pipe(crtc),
7050 (uint32_t)output->possible_crtcs,
7051 (uint32_t)output->possible_clones));
7052
7053 assert(output->possible_crtcs & (1 << __sna_crtc_pipe(crtc)) ||
7054 is_zaphod(sna->scrn));
7055
7056 output_ids[output_count] = to_connector_id(output);
7057 if (++output_count == ARRAY_SIZE(output_ids))
7058 return false;
7059 }
7060 assert(output_count);
7061
7062 VG_CLEAR(arg);
7063 arg.crtc_id = __sna_crtc_id(crtc);
7064 arg.fb_id = fb_id(bo);
7065 assert(arg.fb_id);
7066 arg.x = x;
7067 arg.y = y;
7068 arg.set_connectors_ptr = (uintptr_t)output_ids;
7069 arg.count_connectors = output_count;
7070 arg.mode = crtc->kmode;
7071 arg.mode_valid = 1;
7072
7073 DBG(("%s: applying crtc [%d, pipe=%d] mode=%dx%d+%d+%d@%d, fb=%d across %d outputs [%d...]\n",
7074 __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc),
7075 arg.mode.hdisplay,
7076 arg.mode.vdisplay,
7077 arg.x, arg.y,
7078 arg.mode.clock,
7079 arg.fb_id,
7080 output_count, output_count ? output_ids[0] : 0));
7081
7082 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETCRTC, &arg))
7083 return false;
7084
7085 crtc->offset = y << 16 | x;
7086 __kgem_bo_clear_dirty(bo);
7087 return true;
7088 }
7089
sna_mode_restore(struct sna * sna)7090 static void sna_mode_restore(struct sna *sna)
7091 {
7092 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7093 int error = 0;
7094 int i;
7095
7096 assert(!sna->mode.hidden);
7097
7098 for (i = 0; i < sna->mode.num_real_crtc; i++) {
7099 xf86CrtcPtr crtc = config->crtc[i];
7100
7101 assert(to_sna_crtc(crtc) != NULL);
7102 if (to_sna_crtc(crtc)->bo == NULL)
7103 continue;
7104
7105 assert(crtc->enabled);
7106 if (!__sna_crtc_set_mode(crtc)) {
7107 sna_crtc_disable(crtc, false);
7108 error++;
7109 }
7110 }
7111 sna_mode_wakeup(sna);
7112 while (sna->mode.flip_active && sna_mode_wakeup(sna))
7113 ;
7114 update_flush_interval(sna);
7115 sna_cursors_reload(sna);
7116 sna->mode.dirty = false;
7117
7118 if (error)
7119 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7120 "Failed to restore display configuration\n");
7121 }
7122
sna_needs_page_flip(struct sna * sna,struct kgem_bo * bo)7123 bool sna_needs_page_flip(struct sna *sna, struct kgem_bo *bo)
7124 {
7125 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7126 int i;
7127
7128 for (i = 0; i < sna->mode.num_real_crtc; i++) {
7129 struct sna_crtc *crtc = config->crtc[i]->driver_private;
7130
7131 if (crtc->bo == NULL)
7132 continue;
7133
7134 if (crtc->bo == bo)
7135 continue;
7136
7137 return true;
7138 }
7139
7140 return false;
7141 }
7142
7143 int
sna_page_flip(struct sna * sna,struct kgem_bo * bo,sna_flip_handler_t handler,void * data)7144 sna_page_flip(struct sna *sna,
7145 struct kgem_bo *bo,
7146 sna_flip_handler_t handler,
7147 void *data)
7148 {
7149 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7150 const int width = sna->scrn->virtualX;
7151 const int height = sna->scrn->virtualY;
7152 int sigio;
7153 int count = 0;
7154 int i;
7155
7156 DBG(("%s: handle %d attached\n", __FUNCTION__, bo->handle));
7157 assert(bo->refcnt);
7158
7159 assert((sna->flags & SNA_IS_HOSTED) == 0);
7160 assert(sna->mode.flip_active == 0);
7161 assert(sna->mode.front_active);
7162 assert(!sna->mode.hidden);
7163 assert(sna->scrn->vtSema);
7164
7165 if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0)
7166 return 0;
7167
7168 kgem_bo_submit(&sna->kgem, bo);
7169 __kgem_bo_clear_dirty(bo);
7170
7171 sigio = sigio_block();
7172 for (i = 0; i < sna->mode.num_real_crtc; i++) {
7173 struct sna_crtc *crtc = config->crtc[i]->driver_private;
7174 struct drm_mode_crtc_page_flip arg;
7175 uint32_t crtc_offset;
7176 int fixup;
7177
7178 DBG(("%s: crtc %d id=%d, pipe=%d active? %d\n",
7179 __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo != NULL));
7180 if (crtc->bo == NULL)
7181 continue;
7182 assert(!crtc->transform);
7183 assert(!crtc->slave_pixmap);
7184 assert(crtc->bo->active_scanout);
7185 assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7186 assert(crtc->flip_bo == NULL);
7187
7188 assert_crtc_fb(sna, crtc);
7189 if (data == NULL && crtc->bo == bo)
7190 goto next_crtc;
7191
7192 arg.crtc_id = __sna_crtc_id(crtc);
7193 arg.fb_id = get_fb(sna, bo, width, height);
7194 if (arg.fb_id == 0) {
7195 assert(count == 0);
7196 break;
7197 }
7198
7199 fixup = 0;
7200 crtc_offset = crtc->base->y << 16 | crtc->base->x;
7201
7202 if (bo->pitch != crtc->bo->pitch || crtc_offset != crtc->offset) {
7203 DBG(("%s: changing pitch (%d == %d) or offset (%x == %x)\n",
7204 __FUNCTION__,
7205 bo->pitch, crtc->bo->pitch,
7206 crtc_offset, crtc->offset));
7207 fixup_flip:
7208 fixup = 1;
7209 if (crtc->bo != bo && sna_crtc_flip(sna, crtc, bo, crtc->base->x, crtc->base->y)) {
7210 update_scanout:
7211 DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
7212 __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout,
7213 bo->handle, bo->active_scanout));
7214 assert(crtc->bo->active_scanout);
7215 assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
7216 crtc->bo->active_scanout--;
7217 kgem_bo_destroy(&sna->kgem, crtc->bo);
7218
7219 if (crtc->shadow_bo) {
7220 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
7221 crtc->shadow_bo = NULL;
7222 }
7223
7224 crtc->bo = kgem_bo_reference(bo);
7225 crtc->bo->active_scanout++;
7226
7227 if (data == NULL)
7228 goto next_crtc;
7229
7230 /* queue a flip in order to send the event */
7231 } else
7232 goto error;
7233 }
7234
7235 /* Only the reference crtc will finally deliver its page flip
7236 * completion event. All other crtc's events will be discarded.
7237 */
7238 if (data) {
7239 arg.user_data = (uintptr_t)crtc;
7240 arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
7241 } else {
7242 arg.user_data = 0;
7243 arg.flags = DRM_MODE_PAGE_FLIP_ASYNC;
7244 }
7245 arg.reserved = 0;
7246
7247 retry_flip:
7248 DBG(("%s: crtc %d id=%d, pipe=%d --> fb %d\n",
7249 __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), arg.fb_id));
7250 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
7251 ERR(("%s: pageflip failed with err=%d\n", __FUNCTION__, errno));
7252
7253 if (errno == EBUSY) {
7254 struct drm_mode_crtc mode;
7255
7256 memset(&mode, 0, sizeof(mode));
7257 mode.crtc_id = __sna_crtc_id(crtc);
7258 drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode);
7259
7260 DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=%d\n",
7261 __FUNCTION__,
7262 mode.crtc_id, mode.mode_valid,
7263 mode.fb_id, fb_id(crtc->bo)));
7264
7265 if (mode.fb_id != fb_id(crtc->bo))
7266 goto fixup_flip;
7267
7268 if (count == 0)
7269 break;
7270
7271 DBG(("%s: throttling on busy flip / waiting for kernel to catch up\n", __FUNCTION__));
7272 drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_THROTTLE, 0);
7273 sna->kgem.need_throttle = false;
7274
7275 goto retry_flip;
7276 }
7277
7278 if (!fixup)
7279 goto fixup_flip;
7280
7281 error:
7282 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
7283 "page flipping failed, on CRTC:%d (pipe=%d), disabling %s page flips\n",
7284 __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), data ? "synchronous": "asynchronous");
7285
7286 if (count || crtc->bo == bo)
7287 sna_mode_restore(sna);
7288
7289 sna->flags &= ~(data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP);
7290 count = 0;
7291 break;
7292 }
7293
7294 if (data) {
7295 assert(crtc->flip_bo == NULL);
7296 assert(handler);
7297 crtc->flip_handler = handler;
7298 crtc->flip_data = data;
7299 crtc->flip_bo = kgem_bo_reference(bo);
7300 crtc->flip_bo->active_scanout++;
7301 crtc->flip_serial = crtc->mode_serial;
7302 crtc->flip_pending = true;
7303 sna->mode.flip_active++;
7304
7305 DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
7306 __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial));
7307 } else
7308 goto update_scanout;
7309 next_crtc:
7310 count++;
7311 }
7312 sigio_unblock(sigio);
7313
7314 DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count));
7315 return count;
7316 }
7317
7318 static const xf86CrtcConfigFuncsRec sna_mode_funcs = {
7319 .resize = sna_mode_resize,
7320 };
7321
set_size_range(struct sna * sna)7322 static void set_size_range(struct sna *sna)
7323 {
7324 /* We lie slightly as we expect no single monitor to exceed the
7325 * crtc limits, so if the mode exceeds the scanout restrictions,
7326 * we will quietly convert that to per-crtc pixmaps.
7327 */
7328 xf86CrtcSetSizeRange(sna->scrn, 8, 8, INT16_MAX, INT16_MAX);
7329 }
7330
7331 #if HAS_GAMMA
set_gamma(uint16_t * curve,int size,double value)7332 static void set_gamma(uint16_t *curve, int size, double value)
7333 {
7334 int i;
7335
7336 value = 1/value;
7337 for (i = 0; i < size; i++)
7338 curve[i] = 256*(size-1)*pow(i/(double)(size-1), value);
7339 }
7340
output_set_gamma(xf86OutputPtr output,xf86CrtcPtr crtc)7341 static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc)
7342 {
7343 XF86ConfMonitorPtr mon = output->conf_monitor;
7344
7345 if (!mon)
7346 return;
7347
7348 DBG(("%s: red=%f\n", __FUNCTION__, mon->mon_gamma_red));
7349 if (mon->mon_gamma_red >= GAMMA_MIN &&
7350 mon->mon_gamma_red <= GAMMA_MAX &&
7351 mon->mon_gamma_red != 1.0)
7352 set_gamma(crtc->gamma_red, crtc->gamma_size,
7353 mon->mon_gamma_red);
7354
7355 DBG(("%s: green=%f\n", __FUNCTION__, mon->mon_gamma_green));
7356 if (mon->mon_gamma_green >= GAMMA_MIN &&
7357 mon->mon_gamma_green <= GAMMA_MAX &&
7358 mon->mon_gamma_green != 1.0)
7359 set_gamma(crtc->gamma_green, crtc->gamma_size,
7360 mon->mon_gamma_green);
7361
7362 DBG(("%s: blue=%f\n", __FUNCTION__, mon->mon_gamma_blue));
7363 if (mon->mon_gamma_blue >= GAMMA_MIN &&
7364 mon->mon_gamma_blue <= GAMMA_MAX &&
7365 mon->mon_gamma_blue != 1.0)
7366 set_gamma(crtc->gamma_blue, crtc->gamma_size,
7367 mon->mon_gamma_blue);
7368 }
7369
7370 static bool
crtc_get_gamma_lut(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)7371 crtc_get_gamma_lut(xf86CrtcPtr crtc,
7372 CARD16 *red, CARD16 *green, CARD16 *blue, int size)
7373 {
7374
7375 struct sna *sna = to_sna(crtc->scrn);
7376 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7377 struct drm_color_lut *lut = sna_crtc->gamma_lut;
7378 struct drm_mode_get_blob blob;
7379 int lut_size, i;
7380
7381 DBG(("%s: gamma_size %d\n", __FUNCTION__, size));
7382
7383 memset(&blob, 0, sizeof(blob));
7384 blob.blob_id = sna_crtc->gamma_lut_blob;
7385
7386 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
7387 return false;
7388
7389 lut_size = blob.length / sizeof(lut[0]);
7390
7391 if (lut_size == 0 ||
7392 lut_size > max(sna_crtc->gamma_lut_size, 256))
7393 return false;
7394
7395 blob.data = (uintptr_t)lut;
7396
7397 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
7398 return false;
7399
7400 for (i = 0; i < size; i++) {
7401 struct drm_color_lut *entry =
7402 &lut[i * (lut_size - 1) / (size - 1)];
7403
7404 red[i] = entry->red;
7405 green[i] = entry->green;
7406 blue[i] = entry->blue;
7407 }
7408
7409 return red[size - 1] &&
7410 green[size - 1] &&
7411 blue[size - 1];
7412 }
7413
crtc_get_gamma_legacy(xf86CrtcPtr crtc,CARD16 * red,CARD16 * green,CARD16 * blue,int size)7414 static bool crtc_get_gamma_legacy(xf86CrtcPtr crtc,
7415 CARD16 *red,
7416 CARD16 *green,
7417 CARD16 *blue,
7418 int size)
7419 {
7420 struct sna *sna = to_sna(crtc->scrn);
7421 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7422 struct drm_mode_crtc_lut lut = {
7423 .crtc_id = __sna_crtc_id(sna_crtc),
7424 .gamma_size = size,
7425 .red = (uintptr_t)red,
7426 .green = (uintptr_t)green,
7427 .blue = (uintptr_t)blue,
7428 };
7429
7430 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETGAMMA, &lut) != 0)
7431 return false;
7432
7433 VG(VALGRIND_MAKE_MEM_DEFINED(red, size*sizeof(red[0])));
7434 VG(VALGRIND_MAKE_MEM_DEFINED(green, size*sizeof(green[0])));
7435 VG(VALGRIND_MAKE_MEM_DEFINED(blue, size*sizeof(blue[0])));
7436
7437 return red[size - 1] &&
7438 green[size - 1] &&
7439 blue[size - 1];
7440 }
7441
crtc_init_gamma(xf86CrtcPtr crtc)7442 static void crtc_init_gamma(xf86CrtcPtr crtc)
7443 {
7444 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7445 uint16_t *gamma;
7446 int size;
7447
7448 assert(sna_crtc);
7449
7450 size = sna_crtc->gamma_lut_size;
7451 if (!size)
7452 size = 256;
7453
7454 /* Initialize the gamma ramps */
7455 gamma = NULL;
7456 if (crtc->gamma_size == size)
7457 gamma = crtc->gamma_red;
7458 if (gamma == NULL)
7459 gamma = malloc(3 * size * sizeof(uint16_t));
7460 if (gamma) {
7461 uint16_t *red = gamma;
7462 uint16_t *green = gamma + size;
7463 uint16_t *blue = gamma + 2 * size;
7464 bool gamma_set;
7465
7466 if (sna_crtc->gamma_lut_size)
7467 gamma_set = crtc_get_gamma_lut(crtc, red,
7468 green, blue, size);
7469 else
7470 gamma_set = crtc_get_gamma_legacy(crtc, red,
7471 green, blue, size);
7472
7473 DBG(("%s: CRTC:%d, pipe=%d: gamma set?=%d\n",
7474 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
7475 gamma_set));
7476 if (!gamma_set) {
7477 int i;
7478
7479 for (i = 0; i < size; i++) {
7480 uint16_t val = i * 0xffff / (size - 1);
7481
7482 red[i] = val;
7483 green[i] = val;
7484 blue[i] = val;
7485 }
7486 }
7487
7488 if (red != crtc->gamma_red) {
7489 free(crtc->gamma_red);
7490 crtc->gamma_red = red;
7491 crtc->gamma_green = green;
7492 crtc->gamma_blue = blue;
7493 crtc->gamma_size = size;
7494 }
7495 }
7496 }
7497 #else
output_set_gamma(xf86OutputPtr output,xf86CrtcPtr crtc)7498 static void output_set_gamma(xf86OutputPtr output, xf86CrtcPtr crtc) { }
crtc_init_gamma(xf86CrtcPtr crtc)7499 static void crtc_init_gamma(xf86CrtcPtr crtc) { }
7500 #endif
7501
preferred_mode(xf86OutputPtr output)7502 static const char *preferred_mode(xf86OutputPtr output)
7503 {
7504 const char *mode;
7505
7506 mode = xf86GetOptValString(output->options, OPTION_PREFERRED_MODE);
7507 if (mode)
7508 return mode;
7509
7510 if (output->scrn->display->modes && *output->scrn->display->modes)
7511 return *output->scrn->display->modes;
7512
7513 return NULL;
7514 }
7515
sna_probe_initial_configuration(struct sna * sna)7516 static bool sna_probe_initial_configuration(struct sna *sna)
7517 {
7518 ScrnInfoPtr scrn = sna->scrn;
7519 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
7520 int crtc_active, crtc_enabled;
7521 int width, height;
7522 int i, j;
7523
7524 assert((sna->flags & SNA_IS_HOSTED) == 0);
7525
7526 if ((sna->flags & SNA_IS_SLAVED) == 0) {
7527 const int user_overrides[] = {
7528 OPTION_POSITION,
7529 OPTION_BELOW,
7530 OPTION_RIGHT_OF,
7531 OPTION_ABOVE,
7532 OPTION_LEFT_OF,
7533 OPTION_ROTATE,
7534 OPTION_PANNING,
7535 };
7536 if (xf86ReturnOptValBool(sna->Options, OPTION_REPROBE, FALSE)) {
7537 DBG(("%s: user requests reprobing\n", __FUNCTION__));
7538 return false;
7539 }
7540
7541 /* First scan through all outputs and look for user overrides */
7542 for (i = 0; i < sna->mode.num_real_output; i++) {
7543 xf86OutputPtr output = config->output[i];
7544
7545 for (j = 0; j < ARRAY_SIZE(user_overrides); j++) {
7546 if (xf86GetOptValString(output->options, user_overrides[j])) {
7547 DBG(("%s: user placement [%d] for %s\n",
7548 __FUNCTION__,
7549 user_overrides[j],
7550 output->name));
7551 return false;
7552 }
7553 }
7554 }
7555 }
7556
7557 /* Copy the existing modes on each CRTCs */
7558 crtc_active = crtc_enabled = 0;
7559 for (i = 0; i < sna->mode.num_real_crtc; i++) {
7560 xf86CrtcPtr crtc = config->crtc[i];
7561 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
7562 struct drm_mode_crtc mode;
7563
7564 crtc->enabled = FALSE;
7565 crtc->desiredMode.status = MODE_NOMODE;
7566
7567 crtc_init_gamma(crtc);
7568
7569 /* Retrieve the current mode */
7570 VG_CLEAR(mode);
7571 mode.crtc_id = __sna_crtc_id(sna_crtc);
7572 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
7573 continue;
7574
7575 DBG(("%s: CRTC:%d, pipe=%d: has mode?=%d\n", __FUNCTION__,
7576 __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc),
7577 mode.mode_valid && mode.mode.clock));
7578
7579 if (!mode.mode_valid || mode.mode.clock == 0)
7580 continue;
7581
7582 mode_from_kmode(scrn, &mode.mode, &crtc->desiredMode);
7583 crtc->desiredRotation = sna_crtc->primary.rotation.current;
7584 crtc->desiredX = mode.x;
7585 crtc->desiredY = mode.y;
7586 crtc->desiredTransformPresent = FALSE;
7587 crtc_active++;
7588 }
7589
7590 /* Reconstruct outputs pointing to active CRTC */
7591 for (i = 0; i < sna->mode.num_real_output; i++) {
7592 xf86OutputPtr output = config->output[i];
7593 uint32_t crtc_id;
7594
7595 assert(to_sna_output(output));
7596
7597 crtc_id = (uintptr_t)output->crtc;
7598 output->crtc = NULL;
7599 output->status = XF86OutputStatusUnknown;
7600 if (sna->flags & SNA_IS_SLAVED)
7601 continue;
7602
7603 if (crtc_id == 0) {
7604 DBG(("%s: not using output %s, disconnected\n",
7605 __FUNCTION__, output->name));
7606 continue;
7607 }
7608
7609 if (xf86ReturnOptValBool(output->options, OPTION_DISABLE, 0)) {
7610 DBG(("%s: not using output %s, manually disabled\n",
7611 __FUNCTION__, output->name));
7612 continue;
7613 }
7614
7615 for (j = 0; j < sna->mode.num_real_crtc; j++) {
7616 xf86CrtcPtr crtc = config->crtc[j];
7617
7618 assert(to_sna_crtc(crtc));
7619 if (sna_crtc_id(crtc) != crtc_id)
7620 continue;
7621
7622 if (crtc->desiredMode.status == MODE_OK) {
7623 DisplayModePtr M;
7624 const char *pref;
7625
7626 pref = preferred_mode(output);
7627 if (pref && strcmp(pref, crtc->desiredMode.name)) {
7628 DBG(("%s: output %s user requests a different preferred mode %s, found %s\n",
7629 __FUNCTION__, output->name, pref, crtc->desiredMode.name));
7630 return false;
7631 }
7632
7633 xf86DrvMsg(scrn->scrnIndex, X_PROBED,
7634 "Output %s using initial mode %s on pipe %d\n",
7635 output->name,
7636 crtc->desiredMode.name,
7637 sna_crtc_pipe(crtc));
7638
7639 output->crtc = crtc;
7640 output->status = XF86OutputStatusConnected;
7641 crtc->enabled = TRUE;
7642 crtc_enabled++;
7643
7644 output_set_gamma(output, crtc);
7645
7646 if (output->conf_monitor) {
7647 output->mm_width = output->conf_monitor->mon_width;
7648 output->mm_height = output->conf_monitor->mon_height;
7649 }
7650
7651 #if 0
7652 sna_output_attach_edid(output);
7653 sna_output_attach_tile(output);
7654 #endif
7655
7656 if (output->mm_width == 0 || output->mm_height == 0) {
7657 output->mm_height = (crtc->desiredMode.VDisplay * 254) / (10*DEFAULT_DPI);
7658 output->mm_width = (crtc->desiredMode.HDisplay * 254) / (10*DEFAULT_DPI);
7659 }
7660
7661 M = calloc(1, sizeof(DisplayModeRec));
7662 if (M) {
7663 *M = crtc->desiredMode;
7664 M->name = strdup(M->name);
7665 output->probed_modes =
7666 xf86ModesAdd(output->probed_modes, M);
7667 }
7668 }
7669
7670 break;
7671 }
7672
7673 if (j == sna->mode.num_real_crtc) {
7674 /* Can not find the earlier associated CRTC, bail */
7675 DBG(("%s: existing setup conflicts with output assignment (Zaphod), reprobing\n",
7676 __FUNCTION__));
7677 return false;
7678 }
7679 }
7680
7681 if (crtc_active != crtc_enabled) {
7682 DBG(("%s: only enabled %d out of %d active CRTC, forcing a reconfigure\n",
7683 __FUNCTION__, crtc_enabled, crtc_active));
7684 return false;
7685 }
7686
7687 width = height = 0;
7688 for (i = 0; i < sna->mode.num_real_crtc; i++) {
7689 xf86CrtcPtr crtc = config->crtc[i];
7690 int w, h;
7691
7692 if (!crtc->enabled)
7693 continue;
7694
7695 w = crtc->desiredX + crtc->desiredMode.HDisplay;
7696 if (w > width)
7697 width = w;
7698 h = crtc->desiredY + crtc->desiredMode.VDisplay;
7699 if (h > height)
7700 height = h;
7701 }
7702
7703 /* Prefer the native panel size if any */
7704 if (!width || !height) {
7705 for (i = 0; i < sna->mode.num_real_output; i++) {
7706 xf86OutputPtr output = config->output[i];
7707 struct sna_output *sna_output = to_sna_output(output);
7708
7709 if (!sna_output->is_panel)
7710 continue;
7711
7712 DBG(("%s: querying panel '%s' for preferred unattached size\n",
7713 __FUNCTION__, output->name));
7714
7715 if (sna_output_detect(output) != XF86OutputStatusConnected)
7716 continue;
7717
7718 if (sna_output->num_modes == 0)
7719 continue;
7720
7721 width = sna_output->modes[0].hdisplay;
7722 height = sna_output->modes[0].vdisplay;
7723
7724 DBG(("%s: panel '%s' is %dx%d\n",
7725 __FUNCTION__, output->name, width, height));
7726 break;
7727 }
7728 }
7729
7730 if (!width || !height) {
7731 width = 1024;
7732 height = 768;
7733 }
7734
7735 scrn->display->frameX0 = 0;
7736 scrn->display->frameY0 = 0;
7737 scrn->display->virtualX = width;
7738 scrn->display->virtualY = height;
7739
7740 scrn->virtualX = width;
7741 scrn->virtualY = height;
7742
7743 xf86SetScrnInfoModes(sna->scrn);
7744 DBG(("%s: SetScrnInfoModes = %p\n", __FUNCTION__, scrn->modes));
7745 return scrn->modes != NULL;
7746 }
7747
7748 static void
sanitize_outputs(struct sna * sna)7749 sanitize_outputs(struct sna *sna)
7750 {
7751 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7752 int i;
7753
7754 for (i = 0; i < config->num_output; i++)
7755 config->output[i]->crtc = NULL;
7756 }
7757
has_flip(struct sna * sna)7758 static bool has_flip(struct sna *sna)
7759 {
7760 drm_i915_getparam_t gp;
7761 int v;
7762
7763 if (sna->flags & SNA_NO_FLIP)
7764 return false;
7765
7766 v = 0;
7767
7768 VG_CLEAR(gp);
7769 gp.param = I915_PARAM_HAS_PAGEFLIPPING;
7770 gp.value = &v;
7771
7772 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GETPARAM, &gp))
7773 return false;
7774
7775 VG(VALGRIND_MAKE_MEM_DEFINED(&v, sizeof(v)));
7776 return v > 0;
7777 }
7778
has_flip__async(struct sna * sna)7779 static bool has_flip__async(struct sna *sna)
7780 {
7781 #define DRM_CAP_ASYNC_PAGE_FLIP 0x7
7782 struct local_get_cap {
7783 uint64_t name;
7784 uint64_t value;
7785 } cap = { .name = DRM_CAP_ASYNC_PAGE_FLIP, };
7786
7787 if (sna->flags & SNA_NO_FLIP)
7788 return false;
7789
7790 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_GET_CAP, &cap) == 0)
7791 return cap.value > 0;
7792
7793 return false;
7794 }
7795
7796 static void
probe_capabilities(struct sna * sna)7797 probe_capabilities(struct sna *sna)
7798 {
7799 sna->flags &= ~(SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP);
7800 if (has_flip(sna))
7801 sna->flags |= SNA_HAS_FLIP;
7802 if (has_flip__async(sna) && (sna->flags & SNA_TEAR_FREE) == 0)
7803 sna->flags |= SNA_HAS_ASYNC_FLIP;
7804 DBG(("%s: page flips? %s, async? %s\n", __FUNCTION__,
7805 sna->flags & SNA_HAS_FLIP ? "enabled" : "disabled",
7806 sna->flags & SNA_HAS_ASYNC_FLIP ? "enabled" : "disabled"));
7807 }
7808
7809 void
sna_crtc_config_notify(ScreenPtr screen)7810 sna_crtc_config_notify(ScreenPtr screen)
7811 {
7812 struct sna *sna = to_sna_from_screen(screen);
7813
7814 DBG(("%s(dirty?=%d)\n", __FUNCTION__, sna->mode.dirty));
7815 if (!sna->mode.dirty)
7816 return;
7817
7818 if (disable_unused_crtc(sna)) {
7819 /* This will have recursed, so simply bail at this point */
7820 assert(sna->mode.dirty == false);
7821 #ifdef RANDR_12_INTERFACE
7822 xf86RandR12TellChanged(screen);
7823 #endif
7824 return;
7825 }
7826
7827 /* Flush any events completed by the modeset */
7828 sna_mode_wakeup(sna);
7829
7830 update_flush_interval(sna);
7831 sna->cursor.disable = false; /* Reset HW cursor until the next fail */
7832 sna_cursors_reload(sna);
7833
7834 probe_capabilities(sna);
7835 sna_present_update(sna);
7836
7837 /* Allow TearFree to come back on when everything is off */
7838 if (!sna->mode.front_active && sna->flags & SNA_WANT_TEAR_FREE) {
7839 if ((sna->flags & SNA_TEAR_FREE) == 0)
7840 DBG(("%s: enable TearFree next modeset\n",
7841 __FUNCTION__));
7842
7843 sna->flags |= SNA_TEAR_FREE;
7844 }
7845
7846 sna->mode.dirty = false;
7847 }
7848
7849 #if HAS_PIXMAP_SHARING
7850 #define sna_setup_provider(scrn) xf86ProviderSetup(scrn, NULL, "Intel")
7851 #else
7852 #define sna_setup_provider(scrn)
7853 #endif
7854
sna_mode_pre_init(ScrnInfoPtr scrn,struct sna * sna)7855 bool sna_mode_pre_init(ScrnInfoPtr scrn, struct sna *sna)
7856 {
7857 drmModeResPtr res;
7858 int num_fake = 0;
7859 int i;
7860
7861 if (sna->flags & SNA_IS_HOSTED) {
7862 sna_setup_provider(scrn);
7863 return true;
7864 }
7865
7866 probe_capabilities(sna);
7867 sna->mode.hidden = !isGPU(scrn); /* No DPMS passthrough */
7868
7869 if (!xf86GetOptValInteger(sna->Options, OPTION_VIRTUAL, &num_fake))
7870 num_fake = 1;
7871
7872 res = drmModeGetResources(sna->kgem.fd);
7873 if (res &&
7874 (res->count_crtcs == 0 ||
7875 res->count_encoders == 0 ||
7876 res->count_connectors == 0)) {
7877 drmModeFreeResources(res);
7878 res = NULL;
7879 }
7880 if (res) {
7881 xf86CrtcConfigPtr xf86_config;
7882
7883 DBG(("%s: found %d CRTC, %d encoders, %d connectors\n",
7884 __FUNCTION__, res->count_crtcs, res->count_encoders, res->count_connectors));
7885
7886 assert(res->count_crtcs);
7887 assert(res->count_connectors);
7888
7889 xf86CrtcConfigInit(scrn, &sna_mode_funcs);
7890
7891 xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
7892 xf86_config->xf86_crtc_notify = sna_crtc_config_notify;
7893 xf86_config->compat_output = 0;
7894
7895 for (i = 0; i < res->count_crtcs; i++)
7896 if (!sna_crtc_add(scrn, res->crtcs[i]))
7897 return false;
7898
7899 sna->mode.num_real_crtc = xf86_config->num_crtc;
7900
7901 sna->mode.num_real_encoder = res->count_encoders;
7902 sna->mode.encoders = res->encoders;
7903 res->encoders = NULL;
7904
7905 for (i = 0; i < res->count_connectors; i++)
7906 if (sna_output_add(sna, res->connectors[i], 0) < 0)
7907 return false;
7908
7909 sna->mode.num_real_output = xf86_config->num_output;
7910
7911 sna->mode.max_crtc_width = res->max_width;
7912 sna->mode.max_crtc_height = res->max_height;
7913
7914 RegionEmpty(&sna->mode.shadow_region);
7915 RegionEmpty(&sna->mode.shadow_cancel);
7916 list_init(&sna->mode.shadow_crtc);
7917
7918 drmModeFreeResources(res);
7919
7920 sna_cursor_pre_init(sna);
7921 sna_backlight_pre_init(sna);
7922
7923 set_size_range(sna);
7924 } else {
7925 if (num_fake == 0)
7926 num_fake = 1;
7927 }
7928
7929 if (!sna_mode_fake_init(sna, num_fake))
7930 return false;
7931
7932 sna->mode.shadow_size = 256;
7933 sna->mode.shadow_events = malloc(sna->mode.shadow_size * sizeof(struct drm_event_vblank));
7934 if (!sna->mode.shadow_events)
7935 return false;
7936
7937 if (!sna_probe_initial_configuration(sna)) {
7938 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
7939
7940 sanitize_outputs(sna);
7941 if (config->num_crtc && config->num_output) {
7942 if (!xf86ReturnOptValBool(config->output[0]->options,
7943 OPTION_PRIMARY, FALSE))
7944 sort_config_outputs(sna);
7945 xf86InitialConfiguration(scrn, TRUE);
7946 }
7947 }
7948 sort_config_outputs(sna);
7949
7950 sna_setup_provider(scrn);
7951 return scrn->modes != NULL;
7952 }
7953
7954 bool
sna_mode_wants_tear_free(struct sna * sna)7955 sna_mode_wants_tear_free(struct sna *sna)
7956 {
7957 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
7958 bool found = false;
7959 FILE *file;
7960 int i;
7961
7962 file = fopen("/sys/module/i915/parameters/enable_fbc", "r");
7963 if (file) {
7964 int fbc_enabled = 0;
7965 int value;
7966
7967 if (fscanf(file, "%d", &value) == 1)
7968 fbc_enabled = value > 0;
7969 fclose(file);
7970
7971 DBG(("%s: module parameter 'enable_fbc' enabled? %d\n",
7972 __FUNCTION__, fbc_enabled));
7973
7974 if (fbc_enabled)
7975 return true;
7976 }
7977
7978 for (i = 0; i < sna->mode.num_real_output; i++) {
7979 struct sna_output *output = to_sna_output(config->output[i]);
7980 int id = find_property(sna, output, "Panel Self-Refresh");
7981 if (id == -1)
7982 continue;
7983
7984 found = true;
7985 if (output->prop_values[id] != -1) {
7986 DBG(("%s: Panel Self-Refresh detected on %s\n",
7987 __FUNCTION__, config->output[i]->name));
7988 return true;
7989 }
7990 }
7991
7992 if (!found) {
7993 file = fopen("/sys/module/i915/parameters/enable_psr", "r");
7994 if (file) {
7995 int psr_enabled = 0;
7996 int value;
7997
7998 if (fscanf(file, "%d", &value) == 1)
7999 psr_enabled = value > 0;
8000 fclose(file);
8001
8002 DBG(("%s: module parameter 'enable_psr' enabled? %d\n",
8003 __FUNCTION__, psr_enabled));
8004
8005 if (psr_enabled)
8006 return true;
8007 }
8008 }
8009
8010 return false;
8011 }
8012
8013 void
sna_mode_set_primary(struct sna * sna)8014 sna_mode_set_primary(struct sna *sna)
8015 {
8016 #ifdef RANDR_12_INTERFACE
8017 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8018 rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
8019 int i;
8020
8021 if (rr == NULL || rr->primaryOutput)
8022 return;
8023
8024 for (i = 0; i < sna->mode.num_real_output; i++) {
8025 xf86OutputPtr output = config->output[i];
8026
8027 if (!xf86ReturnOptValBool(output->options, OPTION_PRIMARY, FALSE))
8028 continue;
8029
8030 DBG(("%s: setting PrimaryOutput %s\n", __FUNCTION__, output->name));
8031 rr->primaryOutput = output->randr_output;
8032 RROutputChanged(rr->primaryOutput, FALSE);
8033 rr->layoutChanged = TRUE;
8034 break;
8035 }
8036 #endif
8037 }
8038
8039 bool
sna_mode_disable(struct sna * sna)8040 sna_mode_disable(struct sna *sna)
8041 {
8042 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8043 int i;
8044
8045 if (sna->flags & SNA_IS_HOSTED)
8046 return false;
8047
8048 if (!sna->scrn->vtSema)
8049 return false;
8050
8051 sna_disable_cursors(sna->scrn);
8052 for (i = 0; i < sna->mode.num_real_crtc; i++)
8053 sna_crtc_disable(config->crtc[i], false);
8054 assert(sna->mode.front_active == 0);
8055
8056 sna_mode_wakeup(sna);
8057 kgem_clean_scanout_cache(&sna->kgem);
8058 return true;
8059 }
8060
8061 void
sna_mode_enable(struct sna * sna)8062 sna_mode_enable(struct sna *sna)
8063 {
8064 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8065 int i;
8066
8067 DBG(("%s\n", __FUNCTION__));
8068
8069 if (sna->flags & SNA_IS_HOSTED)
8070 return;
8071
8072 if (!sna->scrn->vtSema)
8073 return;
8074
8075 if (sna->mode.hidden) {
8076 DBG(("%s: hidden outputs\n", __FUNCTION__));
8077 return;
8078 }
8079
8080 for (i = 0; i < sna->mode.num_real_crtc; i++) {
8081 xf86CrtcPtr crtc = config->crtc[i];
8082
8083 DBG(("%s: crtc[%d].enabled?=%d\n", __FUNCTION__, i, crtc->enabled));
8084 assert(to_sna_crtc(crtc) != NULL);
8085 if (!crtc->enabled)
8086 continue;
8087
8088 if (crtc->mode.Clock == 0)
8089 continue;
8090
8091 __sna_crtc_set_mode(crtc);
8092 }
8093
8094 update_flush_interval(sna);
8095 sna_cursors_reload(sna);
8096 sna->mode.dirty = false;
8097 }
8098
sna_randr_close(struct sna * sna)8099 static void sna_randr_close(struct sna *sna)
8100 {
8101 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8102 int n;
8103
8104 /* The RR structs are freed early during CloseScreen as they
8105 * are tracked as Resources. However, we may be tempted to
8106 * access them during shutdown so decouple them now.
8107 */
8108 for (n = 0; n < config->num_output; n++)
8109 config->output[n]->randr_output = NULL;
8110
8111 for (n = 0; n < config->num_crtc; n++)
8112 config->crtc[n]->randr_crtc = NULL;
8113 }
8114
8115 void
sna_mode_close(struct sna * sna)8116 sna_mode_close(struct sna *sna)
8117 {
8118 sna_randr_close(sna);
8119 sna_mode_wakeup(sna);
8120
8121 if (sna->flags & SNA_IS_HOSTED)
8122 return;
8123
8124 sna_mode_reset(sna);
8125
8126 sna_cursor_close(sna);
8127 sna_cursors_fini(sna);
8128
8129 sna_backlight_close(sna);
8130 sna->mode.dirty = false;
8131 }
8132
8133 void
sna_mode_fini(struct sna * sna)8134 sna_mode_fini(struct sna *sna)
8135 {
8136 free(sna->mode.encoders);
8137 }
8138
sna_box_intersect(BoxPtr r,const BoxRec * a,const BoxRec * b)8139 static bool sna_box_intersect(BoxPtr r, const BoxRec *a, const BoxRec *b)
8140 {
8141 r->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
8142 r->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
8143 if (r->x1 >= r->x2)
8144 return false;
8145
8146 r->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
8147 r->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
8148 DBG(("%s: (%d, %d), (%d, %d) intersect (%d, %d), (%d, %d) = (%d, %d), (%d, %d)\n",
8149 __FUNCTION__,
8150 a->x1, a->y1, a->x2, a->y2,
8151 b->x1, b->y1, b->x2, b->y2,
8152 r->x1, r->y1, r->x2, r->y2));
8153 if (r->y1 >= r->y2)
8154 return false;
8155
8156 return true;
8157 }
8158
sna_box_area(const BoxRec * box)8159 static int sna_box_area(const BoxRec *box)
8160 {
8161 return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
8162 }
8163
8164 /*
8165 * Return the crtc covering 'box'. If two crtcs cover a portion of
8166 * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
8167 * with greater coverage
8168 */
8169 xf86CrtcPtr
sna_covering_crtc(struct sna * sna,const BoxRec * box,xf86CrtcPtr desired)8170 sna_covering_crtc(struct sna *sna, const BoxRec *box, xf86CrtcPtr desired)
8171 {
8172 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8173 xf86CrtcPtr best_crtc = NULL;
8174 int best_coverage = -1, c;
8175
8176 if (sna->flags & SNA_IS_HOSTED)
8177 return NULL;
8178
8179 /* If we do not own the VT, we do not own the CRTC either */
8180 if (!sna->scrn->vtSema) {
8181 DBG(("%s: none, VT switched\n", __FUNCTION__));
8182 return NULL;
8183 }
8184
8185 if (sna->mode.hidden) {
8186 DBG(("%s: none, hidden outputs\n", __FUNCTION__));
8187 return NULL;
8188 }
8189
8190 DBG(("%s for box=(%d, %d), (%d, %d)\n",
8191 __FUNCTION__, box->x1, box->y1, box->x2, box->y2));
8192
8193 if (desired == NULL) {
8194 ScreenPtr screen = xf86ScrnToScreen(sna->scrn);
8195 rrScrPrivPtr rr = rrGetScrPriv(screen);
8196 if (rr && rr->primaryOutput && rr->primaryOutput->pScreen == screen) {
8197 xf86OutputPtr output = rr->primaryOutput->devPrivate;
8198 DBG(("%s: have PrimaryOutput? %d marking as desired\n", __FUNCTION__, output->crtc != NULL));
8199 desired = output->crtc;
8200 }
8201 assert(!desired || desired->scrn == sna->scrn);
8202 }
8203 if (desired && to_sna_crtc(desired) && to_sna_crtc(desired)->bo) {
8204 BoxRec cover_box;
8205 if (sna_box_intersect(&cover_box, &desired->bounds, box)) {
8206 DBG(("%s: box overlaps desired crtc: (%d, %d), (%d, %d)\n",
8207 __FUNCTION__,
8208 cover_box.x1, cover_box.y1,
8209 cover_box.x2, cover_box.y2));
8210 return desired;
8211 }
8212 best_crtc = desired;
8213 best_coverage = 0;
8214 }
8215
8216 for (c = 0; c < sna->mode.num_real_crtc; c++) {
8217 xf86CrtcPtr crtc = config->crtc[c];
8218 BoxRec cover_box;
8219 int coverage;
8220
8221 assert(to_sna_crtc(crtc));
8222
8223 /* If the CRTC is off, treat it as not covering */
8224 if (to_sna_crtc(crtc)->bo == NULL) {
8225 DBG(("%s: crtc %d off, skipping\n", __FUNCTION__, c));
8226 continue;
8227 }
8228
8229 DBG(("%s: crtc %d: (%d, %d), (%d, %d)\n",
8230 __FUNCTION__, c,
8231 crtc->bounds.x1, crtc->bounds.y1,
8232 crtc->bounds.x2, crtc->bounds.y2));
8233 if (!memcmp(box, &crtc->bounds, sizeof(*box))) {
8234 DBG(("%s: box exactly matches crtc [%d]\n",
8235 __FUNCTION__, c));
8236 return crtc;
8237 }
8238
8239 coverage = 0;
8240 if (sna_box_intersect(&cover_box, &crtc->bounds, box))
8241 coverage = sna_box_area(&cover_box);
8242
8243 DBG(("%s: box instersects (%d, %d), (%d, %d) of crtc %d\n",
8244 __FUNCTION__,
8245 cover_box.x1, cover_box.y1,
8246 cover_box.x2, cover_box.y2,
8247 c));
8248
8249 DBG(("%s: box covers %d of crtc %d\n",
8250 __FUNCTION__, coverage, c));
8251 if (coverage > best_coverage) {
8252 best_crtc = crtc;
8253 best_coverage = coverage;
8254 }
8255 }
8256 DBG(("%s: best crtc = %p, coverage = %d\n",
8257 __FUNCTION__, best_crtc, best_coverage));
8258 return best_crtc;
8259 }
8260
first_active_crtc(struct sna * sna)8261 static xf86CrtcPtr first_active_crtc(struct sna *sna)
8262 {
8263 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8264 int n;
8265
8266 for (n = 0; n < sna->mode.num_real_crtc; n++) {
8267 xf86CrtcPtr crtc = config->crtc[n];
8268 if (to_sna_crtc(crtc)->bo)
8269 return crtc;
8270 }
8271
8272 /* No active, use the first as a placeholder */
8273 if (sna->mode.num_real_crtc)
8274 return config->crtc[0];
8275
8276 return NULL;
8277 }
8278
sna_primary_crtc(struct sna * sna)8279 xf86CrtcPtr sna_primary_crtc(struct sna *sna)
8280 {
8281 rrScrPrivPtr rr = rrGetScrPriv(xf86ScrnToScreen(sna->scrn));
8282 if (rr && rr->primaryOutput) {
8283 xf86OutputPtr output = rr->primaryOutput->devPrivate;
8284 if (output->crtc &&
8285 output->scrn == sna->scrn &&
8286 to_sna_crtc(output->crtc))
8287 return output->crtc;
8288 }
8289
8290 return first_active_crtc(sna);
8291 }
8292
8293 #define MI_LOAD_REGISTER_IMM (0x22<<23)
8294
sna_emit_wait_for_scanline_hsw(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8295 static bool sna_emit_wait_for_scanline_hsw(struct sna *sna,
8296 xf86CrtcPtr crtc,
8297 int pipe, int y1, int y2,
8298 bool full_height)
8299 {
8300 uint32_t event;
8301 uint32_t *b;
8302
8303 if (!sna->kgem.has_secure_batches)
8304 return false;
8305
8306 b = kgem_get_batch(&sna->kgem);
8307 sna->kgem.nbatch += 17;
8308
8309 switch (pipe) {
8310 default: assert(0); /* fall through */
8311 case 0: event = 1 << 0; break;
8312 case 1: event = 1 << 8; break;
8313 case 2: event = 1 << 14; break;
8314 }
8315
8316 b[0] = MI_LOAD_REGISTER_IMM | 1;
8317 b[1] = 0x44050; /* DERRMR */
8318 b[2] = ~event;
8319 b[3] = MI_LOAD_REGISTER_IMM | 1;
8320 b[4] = 0xa188; /* FORCEWAKE_MT */
8321 b[5] = 2 << 16 | 2;
8322
8323 /* The documentation says that the LOAD_SCAN_LINES command
8324 * always comes in pairs. Don't ask me why. */
8325 switch (pipe) {
8326 default: assert(0); /* fall through */
8327 case 0: event = 0 << 19; break;
8328 case 1: event = 1 << 19; break;
8329 case 2: event = 4 << 19; break;
8330 }
8331 b[8] = b[6] = MI_LOAD_SCAN_LINES_INCL | event;
8332 b[9] = b[7] = (y1 << 16) | (y2-1);
8333
8334 switch (pipe) {
8335 default: assert(0); /* fall through */
8336 case 0: event = 1 << 0; break;
8337 case 1: event = 1 << 8; break;
8338 case 2: event = 1 << 14; break;
8339 }
8340 b[10] = MI_WAIT_FOR_EVENT | event;
8341
8342 b[11] = MI_LOAD_REGISTER_IMM | 1;
8343 b[12] = 0xa188; /* FORCEWAKE_MT */
8344 b[13] = 2 << 16;
8345 b[14] = MI_LOAD_REGISTER_IMM | 1;
8346 b[15] = 0x44050; /* DERRMR */
8347 b[16] = ~0;
8348
8349 sna->kgem.batch_flags |= I915_EXEC_SECURE;
8350 return true;
8351 }
8352
sna_emit_wait_for_scanline_ivb(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8353 static bool sna_emit_wait_for_scanline_ivb(struct sna *sna,
8354 xf86CrtcPtr crtc,
8355 int pipe, int y1, int y2,
8356 bool full_height)
8357 {
8358 uint32_t event, *b;
8359
8360 if (!sna->kgem.has_secure_batches)
8361 return false;
8362
8363 assert(y1 >= 0);
8364 assert(y2 > y1);
8365 assert(sna->kgem.mode);
8366
8367 /* Always program one less than the desired value */
8368 if (--y1 < 0)
8369 y1 = crtc->bounds.y2;
8370 y2--;
8371
8372 switch (pipe) {
8373 default:
8374 assert(0);
8375 /* fall through */
8376 case 0:
8377 event = 1 << (full_height ? 3 : 0);
8378 break;
8379 case 1:
8380 event = 1 << (full_height ? 11 : 8);
8381 break;
8382 case 2:
8383 event = 1 << (full_height ? 21 : 14);
8384 break;
8385 }
8386
8387 b = kgem_get_batch(&sna->kgem);
8388
8389 /* Both the LRI and WAIT_FOR_EVENT must be in the same cacheline */
8390 if (((sna->kgem.nbatch + 6) >> 4) != (sna->kgem.nbatch + 10) >> 4) {
8391 int dw = sna->kgem.nbatch + 6;
8392 dw = ALIGN(dw, 16) - dw;
8393 while (dw--)
8394 *b++ = MI_NOOP;
8395 }
8396
8397 b[0] = MI_LOAD_REGISTER_IMM | 1;
8398 b[1] = 0x44050; /* DERRMR */
8399 b[2] = ~event;
8400 b[3] = MI_LOAD_REGISTER_IMM | 1;
8401 b[4] = 0xa188; /* FORCEWAKE_MT */
8402 b[5] = 2 << 16 | 2;
8403 b[6] = MI_LOAD_REGISTER_IMM | 1;
8404 b[7] = 0x70068 + 0x1000 * pipe;
8405 b[8] = (1 << 31) | (1 << 30) | (y1 << 16) | y2;
8406 b[9] = MI_WAIT_FOR_EVENT | event;
8407 b[10] = MI_LOAD_REGISTER_IMM | 1;
8408 b[11] = 0xa188; /* FORCEWAKE_MT */
8409 b[12] = 2 << 16;
8410 b[13] = MI_LOAD_REGISTER_IMM | 1;
8411 b[14] = 0x44050; /* DERRMR */
8412 b[15] = ~0;
8413
8414 sna->kgem.nbatch = b - sna->kgem.batch + 16;
8415
8416 sna->kgem.batch_flags |= I915_EXEC_SECURE;
8417 return true;
8418 }
8419
sna_emit_wait_for_scanline_gen6(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8420 static bool sna_emit_wait_for_scanline_gen6(struct sna *sna,
8421 xf86CrtcPtr crtc,
8422 int pipe, int y1, int y2,
8423 bool full_height)
8424 {
8425 uint32_t *b;
8426 uint32_t event;
8427
8428 if (!sna->kgem.has_secure_batches)
8429 return false;
8430
8431 assert(y1 >= 0);
8432 assert(y2 > y1);
8433 assert(sna->kgem.mode == KGEM_RENDER);
8434
8435 /* Always program one less than the desired value */
8436 if (--y1 < 0)
8437 y1 = crtc->bounds.y2;
8438 y2--;
8439
8440 /* The scanline granularity is 3 bits */
8441 y1 &= ~7;
8442 y2 &= ~7;
8443 if (y2 == y1)
8444 return false;
8445
8446 event = 1 << (3*full_height + pipe*8);
8447
8448 b = kgem_get_batch(&sna->kgem);
8449 sna->kgem.nbatch += 16;
8450
8451 b[0] = MI_LOAD_REGISTER_IMM | 1;
8452 b[1] = 0x44050; /* DERRMR */
8453 b[2] = ~event;
8454 b[3] = MI_LOAD_REGISTER_IMM | 1;
8455 b[4] = 0x4f100; /* magic */
8456 b[5] = (1 << 31) | (1 << 30) | pipe << 29 | (y1 << 16) | y2;
8457 b[6] = MI_LOAD_REGISTER_IMM | 1;
8458 b[7] = 0x2050; /* PSMI_CTL(rcs) */
8459 b[8] = 1 << 16 | 1;
8460 b[9] = MI_WAIT_FOR_EVENT | event;
8461 b[10] = MI_LOAD_REGISTER_IMM | 1;
8462 b[11] = 0x2050; /* PSMI_CTL(rcs) */
8463 b[12] = 1 << 16;
8464 b[13] = MI_LOAD_REGISTER_IMM | 1;
8465 b[14] = 0x44050; /* DERRMR */
8466 b[15] = ~0;
8467
8468 sna->kgem.batch_flags |= I915_EXEC_SECURE;
8469 return true;
8470 }
8471
sna_emit_wait_for_scanline_gen4(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8472 static bool sna_emit_wait_for_scanline_gen4(struct sna *sna,
8473 xf86CrtcPtr crtc,
8474 int pipe, int y1, int y2,
8475 bool full_height)
8476 {
8477 uint32_t event;
8478 uint32_t *b;
8479
8480 if (pipe == 0) {
8481 if (full_height)
8482 event = MI_WAIT_FOR_PIPEA_SVBLANK;
8483 else
8484 event = MI_WAIT_FOR_PIPEA_SCAN_LINE_WINDOW;
8485 } else {
8486 if (full_height)
8487 event = MI_WAIT_FOR_PIPEB_SVBLANK;
8488 else
8489 event = MI_WAIT_FOR_PIPEB_SCAN_LINE_WINDOW;
8490 }
8491
8492 b = kgem_get_batch(&sna->kgem);
8493 sna->kgem.nbatch += 5;
8494
8495 /* The documentation says that the LOAD_SCAN_LINES command
8496 * always comes in pairs. Don't ask me why. */
8497 b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
8498 b[3] = b[1] = (y1 << 16) | (y2-1);
8499 b[4] = MI_WAIT_FOR_EVENT | event;
8500
8501 return true;
8502 }
8503
sna_emit_wait_for_scanline_gen2(struct sna * sna,xf86CrtcPtr crtc,int pipe,int y1,int y2,bool full_height)8504 static bool sna_emit_wait_for_scanline_gen2(struct sna *sna,
8505 xf86CrtcPtr crtc,
8506 int pipe, int y1, int y2,
8507 bool full_height)
8508 {
8509 uint32_t *b;
8510
8511 /*
8512 * Pre-965 doesn't have SVBLANK, so we need a bit
8513 * of extra time for the blitter to start up and
8514 * do its job for a full height blit
8515 */
8516 if (full_height)
8517 y2 -= 2;
8518
8519 b = kgem_get_batch(&sna->kgem);
8520 sna->kgem.nbatch += 5;
8521
8522 /* The documentation says that the LOAD_SCAN_LINES command
8523 * always comes in pairs. Don't ask me why. */
8524 b[2] = b[0] = MI_LOAD_SCAN_LINES_INCL | pipe << 20;
8525 b[3] = b[1] = (y1 << 16) | (y2-1);
8526 b[4] = MI_WAIT_FOR_EVENT | 1 << (1 + 4*pipe);
8527
8528 return true;
8529 }
8530
8531 bool
sna_wait_for_scanline(struct sna * sna,PixmapPtr pixmap,xf86CrtcPtr crtc,const BoxRec * clip)8532 sna_wait_for_scanline(struct sna *sna,
8533 PixmapPtr pixmap,
8534 xf86CrtcPtr crtc,
8535 const BoxRec *clip)
8536 {
8537 bool full_height;
8538 int y1, y2, pipe;
8539 bool ret;
8540
8541 assert(crtc != NULL);
8542 assert(to_sna_crtc(crtc) != NULL);
8543 assert(to_sna_crtc(crtc)->bo != NULL);
8544 assert(pixmap == sna->front);
8545
8546 if (sna->flags & SNA_NO_VSYNC)
8547 return false;
8548
8549 /*
8550 * Make sure we don't wait for a scanline that will
8551 * never occur
8552 */
8553 y1 = clip->y1 - crtc->bounds.y1;
8554 if (y1 < 0)
8555 y1 = 0;
8556 y2 = clip->y2 - crtc->bounds.y1;
8557 if (y2 > crtc->bounds.y2 - crtc->bounds.y1)
8558 y2 = crtc->bounds.y2 - crtc->bounds.y1;
8559 DBG(("%s: clipped range = %d, %d\n", __FUNCTION__, y1, y2));
8560 if (y2 <= y1 + 4)
8561 return false;
8562
8563 full_height = y1 == 0 && y2 == crtc->bounds.y2 - crtc->bounds.y1;
8564
8565 if (crtc->mode.Flags & V_INTERLACE) {
8566 /* DSL count field lines */
8567 y1 /= 2;
8568 y2 /= 2;
8569 }
8570
8571 pipe = sna_crtc_pipe(crtc);
8572 DBG(("%s: pipe=%d, y1=%d, y2=%d, full_height?=%d\n",
8573 __FUNCTION__, pipe, y1, y2, full_height));
8574
8575 if (sna->kgem.gen >= 0110)
8576 ret = false;
8577 else if (sna->kgem.gen == 0101)
8578 ret = false; /* chv, vsync method unknown */
8579 else if (sna->kgem.gen >= 075)
8580 ret = sna_emit_wait_for_scanline_hsw(sna, crtc, pipe, y1, y2, full_height);
8581 else if (sna->kgem.gen == 071)
8582 ret = false; /* vlv, vsync method unknown */
8583 else if (sna->kgem.gen >= 070)
8584 ret = sna_emit_wait_for_scanline_ivb(sna, crtc, pipe, y1, y2, full_height);
8585 else if (sna->kgem.gen >= 060)
8586 ret =sna_emit_wait_for_scanline_gen6(sna, crtc, pipe, y1, y2, full_height);
8587 else if (sna->kgem.gen >= 040)
8588 ret = sna_emit_wait_for_scanline_gen4(sna, crtc, pipe, y1, y2, full_height);
8589 else
8590 ret = sna_emit_wait_for_scanline_gen2(sna, crtc, pipe, y1, y2, full_height);
8591
8592 return ret;
8593 }
8594
sna_mode_shutdown_crtc(xf86CrtcPtr crtc)8595 static bool sna_mode_shutdown_crtc(xf86CrtcPtr crtc)
8596 {
8597 struct sna *sna = to_sna(crtc->scrn);
8598 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
8599 bool disabled = false;
8600 int o;
8601
8602 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
8603 "%s: invalid state found on pipe %d, disabling CRTC:%d\n",
8604 __FUNCTION__,
8605 __sna_crtc_pipe(to_sna_crtc(crtc)),
8606 __sna_crtc_id(to_sna_crtc(crtc)));
8607 sna_crtc_disable(crtc, true);
8608 #if XF86_CRTC_VERSION >= 3
8609 crtc->active = FALSE;
8610 #endif
8611 if (crtc->enabled) {
8612 crtc->enabled = FALSE;
8613 disabled = true;
8614 }
8615
8616 for (o = 0; o < sna->mode.num_real_output; o++) {
8617 xf86OutputPtr output = config->output[o];
8618
8619 if (output->crtc != crtc)
8620 continue;
8621
8622 output->funcs->dpms(output, DPMSModeOff);
8623 output->crtc = NULL;
8624 }
8625
8626 return disabled;
8627 }
8628
8629 static bool
sna_mode_disable_secondary_planes(struct sna * sna)8630 sna_mode_disable_secondary_planes(struct sna *sna)
8631 {
8632 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8633 bool disabled = false;
8634 int c;
8635
8636 /* Disable all secondary planes on our CRTCs, just in case
8637 * other userspace left garbage in them.
8638 */
8639 for (c = 0; c < sna->mode.num_real_crtc; c++) {
8640 xf86CrtcPtr crtc = config->crtc[c];
8641 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8642 struct plane *plane;
8643
8644 list_for_each_entry(plane, &sna_crtc->sprites, link) {
8645 struct local_mode_get_plane p;
8646 struct local_mode_set_plane s;
8647
8648 VG_CLEAR(p);
8649 p.plane_id = plane->id;
8650 p.count_format_types = 0;
8651 if (drmIoctl(sna->kgem.fd,
8652 LOCAL_IOCTL_MODE_GETPLANE,
8653 &p))
8654 continue;
8655
8656 if (p.fb_id == 0 || p.crtc_id == 0)
8657 continue;
8658
8659 memset(&s, 0, sizeof(s));
8660 s.plane_id = p.plane_id;
8661 s.crtc_id = p.crtc_id;
8662 if (drmIoctl(sna->kgem.fd,
8663 LOCAL_IOCTL_MODE_SETPLANE,
8664 &s))
8665 disabled |= sna_mode_shutdown_crtc(crtc);
8666 }
8667 }
8668
8669 return disabled;
8670 }
8671
sna_mode_check(struct sna * sna)8672 void sna_mode_check(struct sna *sna)
8673 {
8674 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8675 bool disabled;
8676 int c, o;
8677
8678 if (sna->flags & SNA_IS_HOSTED)
8679 return;
8680
8681 DBG(("%s: hidden?=%d\n", __FUNCTION__, sna->mode.hidden));
8682 if (sna->mode.hidden)
8683 return;
8684
8685 disabled = sna_mode_disable_secondary_planes(sna);
8686
8687 /* Validate CRTC attachments and force consistency upon the kernel */
8688 for (c = 0; c < sna->mode.num_real_crtc; c++) {
8689 xf86CrtcPtr crtc = config->crtc[c];
8690 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8691 struct drm_mode_crtc mode;
8692 uint32_t expected[2];
8693
8694 assert(sna_crtc);
8695
8696 #if XF86_CRTC_VERSION >= 3
8697 assert(sna_crtc->bo == NULL || crtc->active);
8698 #endif
8699 expected[0] = sna_crtc->bo ? fb_id(sna_crtc->bo) : 0;
8700 expected[1] = sna_crtc->flip_bo ? fb_id(sna_crtc->flip_bo) : -1;
8701
8702 VG_CLEAR(mode);
8703 mode.crtc_id = __sna_crtc_id(sna_crtc);
8704 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETCRTC, &mode))
8705 continue;
8706
8707 DBG(("%s: crtc=%d, valid?=%d, fb attached?=%d, expected=(%d or %d)\n",
8708 __FUNCTION__,
8709 mode.crtc_id, mode.mode_valid,
8710 mode.fb_id, expected[0], expected[1]));
8711
8712 if (mode.fb_id != expected[0] && mode.fb_id != expected[1])
8713 disabled |= sna_mode_shutdown_crtc(crtc);
8714 }
8715
8716 for (o = 0; o < config->num_output; o++) {
8717 xf86OutputPtr output = config->output[o];
8718 struct sna_output *sna_output;
8719
8720 if (output->crtc)
8721 continue;
8722
8723 sna_output = to_sna_output(output);
8724 if (sna_output == NULL)
8725 continue;
8726
8727 sna_output->dpms_mode = DPMSModeOff;
8728 }
8729
8730 update_flush_interval(sna);
8731
8732 if (disabled)
8733 xf86RandR12TellChanged(xf86ScrnToScreen(sna->scrn));
8734 }
8735
8736 static bool
sna_crtc_hide_planes(struct sna * sna,struct sna_crtc * crtc)8737 sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc)
8738 {
8739 struct local_mode_set_plane s;
8740 struct plane *plane;
8741
8742 if (crtc->primary.id == 0)
8743 return false;
8744
8745 memset(&s, 0, sizeof(s));
8746 s.plane_id = crtc->primary.id;
8747 if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s))
8748 return false;
8749
8750 list_for_each_entry(plane, &crtc->sprites, link) {
8751 s.plane_id = plane->id;
8752 (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s);
8753 }
8754
8755 __sna_crtc_disable(sna, crtc);
8756 return true;
8757 }
8758
sna_mode_reset(struct sna * sna)8759 void sna_mode_reset(struct sna *sna)
8760 {
8761 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
8762 int i;
8763
8764 if (sna->flags & SNA_IS_HOSTED)
8765 return;
8766
8767 DBG(("%s\n", __FUNCTION__));
8768
8769 sna_disable_cursors(sna->scrn);
8770 for (i = 0; i < sna->mode.num_real_crtc; i++)
8771 if (!sna_crtc_hide_planes(sna, to_sna_crtc(config->crtc[i])))
8772 sna_crtc_disable(config->crtc[i], true);
8773 assert(sna->mode.front_active == 0);
8774
8775 for (i = 0; i < sna->mode.num_real_crtc; i++) {
8776 struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]);
8777 struct plane *plane;
8778
8779 assert(sna_crtc != NULL);
8780
8781 /* Force the rotation property to be reset on next use */
8782 rotation_reset(&sna_crtc->primary);
8783 list_for_each_entry(plane, &sna_crtc->sprites, link)
8784 rotation_reset(plane);
8785 }
8786
8787 /* VT switching, likely to be fbcon so make the backlight usable */
8788 for (i = 0; i < sna->mode.num_real_output; i++) {
8789 struct sna_output *sna_output = to_sna_output(config->output[i]);
8790
8791 assert(sna_output != NULL);
8792 if (sna_output->dpms_mode != DPMSModeOff)
8793 continue;
8794
8795 if (!sna_output->backlight.iface)
8796 continue;
8797
8798 sna_output_backlight_set(sna_output,
8799 sna_output->backlight_active_level);
8800 }
8801
8802 /* drain the event queue */
8803 sna_mode_wakeup(sna);
8804 }
8805
transformed_box(BoxRec * box,xf86CrtcPtr crtc)8806 static void transformed_box(BoxRec *box, xf86CrtcPtr crtc)
8807 {
8808 box->x1 -= crtc->filter_width >> 1;
8809 box->x2 += crtc->filter_width >> 1;
8810 box->y1 -= crtc->filter_height >> 1;
8811 box->y2 += crtc->filter_height >> 1;
8812
8813 pixman_f_transform_bounds(&crtc->f_framebuffer_to_crtc, box);
8814
8815 if (box->x1 < 0)
8816 box->x1 = 0;
8817 if (box->y1 < 0)
8818 box->y1 = 0;
8819 if (box->x2 > crtc->mode.HDisplay)
8820 box->x2 = crtc->mode.HDisplay;
8821 if (box->y2 > crtc->mode.VDisplay)
8822 box->y2 = crtc->mode.VDisplay;
8823 }
8824
crtc_source(xf86CrtcPtr crtc,int16_t * sx,int16_t * sy)8825 inline static DrawablePtr crtc_source(xf86CrtcPtr crtc, int16_t *sx, int16_t *sy)
8826 {
8827 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
8828 if (sna_crtc->slave_pixmap) {
8829 DBG(("%s: using slave pixmap=%ld, offset (%d, %d)\n",
8830 __FUNCTION__,
8831 sna_crtc->slave_pixmap->drawable.serialNumber,
8832 -crtc->x, -crtc->y));
8833 *sx = -crtc->x;
8834 *sy = -crtc->y;
8835 return &sna_crtc->slave_pixmap->drawable;
8836 } else {
8837 DBG(("%s: using Screen pixmap=%ld\n",
8838 __FUNCTION__,
8839 to_sna(crtc->scrn)->front->drawable.serialNumber));
8840 *sx = *sy = 0;
8841 return &to_sna(crtc->scrn)->front->drawable;
8842 }
8843 }
8844
8845 static void
sna_crtc_redisplay__fallback(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)8846 sna_crtc_redisplay__fallback(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
8847 {
8848 int16_t sx, sy;
8849 struct sna *sna = to_sna(crtc->scrn);
8850 ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
8851 DrawablePtr draw = crtc_source(crtc, &sx, &sy);
8852 PictFormatPtr format;
8853 PictTransform T;
8854 PicturePtr src, dst;
8855 PixmapPtr pixmap;
8856 int depth, error;
8857 void *ptr;
8858
8859 DBG(("%s: compositing transformed damage boxes, target handle=%d\n", __FUNCTION__, bo->handle));
8860
8861 error = sna_render_format_for_depth(draw->depth);
8862 depth = PIXMAN_FORMAT_DEPTH(error);
8863 format = PictureMatchFormat(screen, depth, error);
8864 if (format == NULL) {
8865 DBG(("%s: can't find format for depth=%d [%08x]\n",
8866 __FUNCTION__, depth, error));
8867 return;
8868 }
8869
8870 DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
8871 __FUNCTION__, format->format, depth, draw->bitsPerPixel,
8872 bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
8873
8874 if (sx | sy)
8875 RegionTranslate(region, sx, sy);
8876 error = !sna_drawable_move_region_to_cpu(draw, region, MOVE_READ);
8877 if (sx | sy)
8878 RegionTranslate(region, -sx, -sy);
8879 if (error)
8880 return;
8881
8882 ptr = kgem_bo_map__gtt(&sna->kgem, bo);
8883 if (ptr == NULL)
8884 return;
8885
8886 pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
8887 if (pixmap == NullPixmap)
8888 return;
8889
8890 if (!screen->ModifyPixmapHeader(pixmap,
8891 crtc->mode.HDisplay, crtc->mode.VDisplay,
8892 depth, draw->bitsPerPixel,
8893 bo->pitch, ptr))
8894 goto free_pixmap;
8895
8896 src = CreatePicture(None, draw, format,
8897 0, NULL, serverClient, &error);
8898 if (!src)
8899 goto free_pixmap;
8900
8901 pixman_transform_init_translate(&T, sx << 16, sy << 16);
8902 pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer);
8903 if (!sna_transform_is_integer_translation(&T, &sx, &sy)) {
8904 #define f2d(x) (((double)(x))/65536.)
8905 DBG(("%s: transform=[[%f %f %f], [%f %f %f], [%f %f %f]] (raw [[%x %x %x], [%x %x %x], [%x %x %x]])\n",
8906 __FUNCTION__,
8907 f2d(T.matrix[0][0]),
8908 f2d(T.matrix[0][1]),
8909 f2d(T.matrix[0][2]),
8910 f2d(T.matrix[1][0]),
8911 f2d(T.matrix[1][1]),
8912 f2d(T.matrix[1][2]),
8913 f2d(T.matrix[2][0]),
8914 f2d(T.matrix[2][1]),
8915 f2d(T.matrix[2][2]),
8916 T.matrix[0][0],
8917 T.matrix[0][1],
8918 T.matrix[0][2],
8919 T.matrix[1][0],
8920 T.matrix[1][1],
8921 T.matrix[1][2],
8922 T.matrix[2][0],
8923 T.matrix[2][1],
8924 T.matrix[2][2]));
8925 #undef f2d
8926
8927 error = SetPictureTransform(src, &T);
8928 if (error)
8929 goto free_src;
8930 sx = sy = 0;
8931 }
8932
8933 if (crtc->filter && crtc->transform_in_use)
8934 SetPicturePictFilter(src, crtc->filter,
8935 crtc->params, crtc->nparams);
8936
8937 dst = CreatePicture(None, &pixmap->drawable, format,
8938 0, NULL, serverClient, &error);
8939 if (!dst)
8940 goto free_src;
8941
8942 kgem_bo_sync__gtt(&sna->kgem, bo);
8943
8944 if (sigtrap_get() == 0) { /* paranoia */
8945 const BoxRec *b = region_rects(region);
8946 int n = region_num_rects(region);
8947 do {
8948 BoxRec box;
8949
8950 box = *b++;
8951 transformed_box(&box, crtc);
8952
8953 DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
8954 __FUNCTION__,
8955 b[-1].x1, b[-1].y1, b[-1].x2-b[-1].x1, b[-1].y2-b[-1].y1,
8956 box.x1, box.y1, box.x2, box.y2));
8957
8958 fbComposite(PictOpSrc, src, NULL, dst,
8959 box.x1 + sx, box.y1 + sy,
8960 0, 0,
8961 box.x1, box.y1,
8962 box.x2 - box.x1, box.y2 - box.y1);
8963 } while (--n);
8964 sigtrap_put();
8965 }
8966
8967 FreePicture(dst, None);
8968 free_src:
8969 FreePicture(src, None);
8970 free_pixmap:
8971 screen->DestroyPixmap(pixmap);
8972 }
8973
8974 static void
sna_crtc_redisplay__composite(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)8975 sna_crtc_redisplay__composite(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
8976 {
8977 int16_t sx, sy;
8978 struct sna *sna = to_sna(crtc->scrn);
8979 ScreenPtr screen = xf86ScrnToScreen(crtc->scrn);
8980 DrawablePtr draw = crtc_source(crtc, &sx, &sy);
8981 struct sna_composite_op tmp;
8982 PictFormatPtr format;
8983 PictTransform T;
8984 PicturePtr src, dst;
8985 PixmapPtr pixmap;
8986 const BoxRec *b;
8987 int n, depth, error;
8988
8989 DBG(("%s: compositing transformed damage boxes\n", __FUNCTION__));
8990
8991 error = sna_render_format_for_depth(draw->depth);
8992 depth = PIXMAN_FORMAT_DEPTH(error);
8993 format = PictureMatchFormat(screen, depth, error);
8994 if (format == NULL) {
8995 DBG(("%s: can't find format for depth=%d [%08x]\n",
8996 __FUNCTION__, depth, error));
8997 return;
8998 }
8999
9000 DBG(("%s: dst format=%08x, depth=%d, bpp=%d, pitch=%d, size=%dx%d\n",
9001 __FUNCTION__, format->format, depth, draw->bitsPerPixel,
9002 bo->pitch, crtc->mode.HDisplay, crtc->mode.VDisplay));
9003
9004 pixmap = sna_pixmap_create_unattached(screen, 0, 0, depth);
9005 if (pixmap == NullPixmap)
9006 return;
9007
9008 if (!screen->ModifyPixmapHeader(pixmap,
9009 crtc->mode.HDisplay, crtc->mode.VDisplay,
9010 depth, draw->bitsPerPixel,
9011 bo->pitch, NULL))
9012 goto free_pixmap;
9013
9014 if (!sna_pixmap_attach_to_bo(pixmap, kgem_bo_reference(bo))) {
9015 kgem_bo_destroy(&sna->kgem, bo);
9016 goto free_pixmap;
9017 }
9018
9019 src = CreatePicture(None, draw, format,
9020 0, NULL, serverClient, &error);
9021 if (!src)
9022 goto free_pixmap;
9023
9024 pixman_transform_init_translate(&T, sx << 16, sy << 16);
9025 pixman_transform_multiply(&T, &T, &crtc->crtc_to_framebuffer);
9026 if (!sna_transform_is_integer_translation(&T, &sx, &sy)) {
9027 error = SetPictureTransform(src, &T);
9028 if (error)
9029 goto free_src;
9030 sx = sy = 0;
9031 }
9032
9033 if (crtc->filter && crtc->transform_in_use)
9034 SetPicturePictFilter(src, crtc->filter,
9035 crtc->params, crtc->nparams);
9036
9037 dst = CreatePicture(None, &pixmap->drawable, format,
9038 0, NULL, serverClient, &error);
9039 if (!dst)
9040 goto free_src;
9041
9042 ValidatePicture(src);
9043 ValidatePicture(dst);
9044
9045 /* Composite each box individually as if we are dealing with a rotation
9046 * on a large display, we may have to perform intermediate copies. We
9047 * can then minimise the overdraw by looking at individual boxes rather
9048 * than the bbox.
9049 */
9050 n = region_num_rects(region);
9051 b = region_rects(region);
9052 do {
9053 BoxRec box = *b;
9054 transformed_box(&box, crtc);
9055
9056 DBG(("%s: (%d, %d)x(%d, %d) -> (%d, %d), (%d, %d)\n",
9057 __FUNCTION__,
9058 b->x1, b->y1, b->x2-b->x1, b->y2-b->y1,
9059 box.x1, box.y1, box.x2, box.y2));
9060
9061 if (!sna->render.composite(sna,
9062 PictOpSrc, src, NULL, dst,
9063 sx + box.x1, sy + box.y1,
9064 0, 0,
9065 box.x1, box.y1,
9066 box.x2 - box.x1, box.y2 - box.y1,
9067 0, memset(&tmp, 0, sizeof(tmp)))) {
9068 DBG(("%s: unsupported operation!\n", __FUNCTION__));
9069 sna_crtc_redisplay__fallback(crtc, region, bo);
9070 break;
9071 } else {
9072 tmp.box(sna, &tmp, &box);
9073 tmp.done(sna, &tmp);
9074 }
9075 } while (b++, --n);
9076
9077 FreePicture(dst, None);
9078 free_src:
9079 FreePicture(src, None);
9080 free_pixmap:
9081 screen->DestroyPixmap(pixmap);
9082 }
9083
9084 static void
sna_crtc_redisplay(xf86CrtcPtr crtc,RegionPtr region,struct kgem_bo * bo)9085 sna_crtc_redisplay(xf86CrtcPtr crtc, RegionPtr region, struct kgem_bo *bo)
9086 {
9087 int16_t tx, ty, sx, sy;
9088 struct sna *sna = to_sna(crtc->scrn);
9089 DrawablePtr draw = crtc_source(crtc, &sx, &sy);
9090 struct sna_pixmap *priv = sna_pixmap((PixmapPtr)draw);
9091
9092 DBG(("%s: crtc %d [pipe=%d], damage (%d, %d), (%d, %d) x %d\n",
9093 __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc),
9094 region->extents.x1, region->extents.y1,
9095 region->extents.x2, region->extents.y2,
9096 region_num_rects(region)));
9097
9098 if (wedged(sna))
9099 goto fallback;
9100
9101 if (priv->clear) {
9102 RegionRec whole;
9103
9104 DBG(("%s: clear damage boxes\n", __FUNCTION__));
9105
9106 if (sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
9107 &tx, &ty)) {
9108 RegionTranslate(region, -tx, -ty);
9109 } else {
9110 whole.extents = region->extents;
9111 whole.data = NULL;
9112 transformed_box(&whole.extents, crtc);
9113 region = &whole;
9114 }
9115 if (sna_blt_fill_boxes(sna, GXcopy,
9116 bo, draw->bitsPerPixel,
9117 priv->clear_color,
9118 region_rects(region),
9119 region_num_rects(region)))
9120 return;
9121 }
9122
9123 if (crtc->filter == NULL &&
9124 priv->gpu_bo &&
9125 priv->cpu_damage == NULL &&
9126 sna_transform_is_integer_translation(&crtc->crtc_to_framebuffer,
9127 &tx, &ty)) {
9128 DrawableRec tmp;
9129
9130 DBG(("%s: copy damage boxes\n", __FUNCTION__));
9131
9132 tmp.width = crtc->mode.HDisplay;
9133 tmp.height = crtc->mode.VDisplay;
9134 tmp.depth = sna->front->drawable.depth;
9135 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
9136
9137 if (sna->render.copy_boxes(sna, GXcopy,
9138 draw, priv->gpu_bo, sx, sy,
9139 &tmp, bo, -tx, -ty,
9140 region_rects(region), region_num_rects(region), 0))
9141 return;
9142 }
9143
9144 if (can_render(sna)) {
9145 sna_crtc_redisplay__composite(crtc, region, bo);
9146 return;
9147 }
9148
9149 fallback:
9150 sna_crtc_redisplay__fallback(crtc, region, bo);
9151 }
9152
shadow_flip_handler(struct drm_event_vblank * e,void * data)9153 static void shadow_flip_handler(struct drm_event_vblank *e,
9154 void *data)
9155 {
9156 struct sna *sna = data;
9157
9158 sna->timer_active |= 1 << FLUSH_TIMER;
9159 sna->timer_expire[FLUSH_TIMER] =
9160 e->tv_sec * 1000 + e->tv_usec / 1000 +
9161 sna->vblank_interval / 2;
9162 }
9163
sna_shadow_set_crtc(struct sna * sna,xf86CrtcPtr crtc,struct kgem_bo * bo)9164 void sna_shadow_set_crtc(struct sna *sna,
9165 xf86CrtcPtr crtc,
9166 struct kgem_bo *bo)
9167 {
9168 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9169 struct sna_pixmap *priv;
9170
9171 assert(sna_crtc);
9172 DBG(("%s: setting shadow override for CRTC:%d to handle=%d\n",
9173 __FUNCTION__, __sna_crtc_id(sna_crtc), bo->handle));
9174
9175 assert(sna->flags & SNA_TEAR_FREE);
9176 assert(!sna_crtc->transform);
9177
9178 if (sna_crtc->client_bo != bo) {
9179 if (sna_crtc->client_bo) {
9180 assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9181 sna_crtc->client_bo->active_scanout--;
9182 kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
9183 }
9184
9185 sna_crtc->client_bo = kgem_bo_reference(bo);
9186 sna_crtc->client_bo->active_scanout++;
9187 assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9188 sna_crtc_damage(crtc);
9189 }
9190
9191 list_move(&sna_crtc->shadow_link, &sna->mode.shadow_crtc);
9192 sna->mode.shadow_dirty = true;
9193
9194 priv = sna_pixmap(sna->front);
9195 assert(priv->gpu_bo);
9196 priv->move_to_gpu = wait_for_shadow;
9197 priv->move_to_gpu_data = sna;
9198 }
9199
sna_shadow_steal_crtcs(struct sna * sna,struct list * list)9200 void sna_shadow_steal_crtcs(struct sna *sna, struct list *list)
9201 {
9202 list_init(list);
9203 while (!list_is_empty(&sna->mode.shadow_crtc)) {
9204 RegionRec sub, *damage;
9205 struct sna_crtc *crtc =
9206 list_first_entry(&sna->mode.shadow_crtc,
9207 struct sna_crtc,
9208 shadow_link);
9209
9210 damage = DamageRegion(sna->mode.shadow_damage);
9211 sub.extents = crtc->base->bounds;
9212 sub.data = NULL;
9213 RegionSubtract(damage, damage, &sub);
9214
9215 list_move(&crtc->shadow_link, list);
9216 }
9217 }
9218
sna_shadow_unsteal_crtcs(struct sna * sna,struct list * list)9219 void sna_shadow_unsteal_crtcs(struct sna *sna, struct list *list)
9220 {
9221 while (!list_is_empty(list)) {
9222 struct sna_crtc *crtc =
9223 list_first_entry(list,
9224 struct sna_crtc,
9225 shadow_link);
9226 assert(crtc->client_bo);
9227 sna_shadow_set_crtc(sna, crtc->base, crtc->client_bo);
9228 }
9229 }
9230
sna_shadow_unset_crtc(struct sna * sna,xf86CrtcPtr crtc)9231 void sna_shadow_unset_crtc(struct sna *sna,
9232 xf86CrtcPtr crtc)
9233 {
9234 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9235
9236 DBG(("%s: clearin shadow override for CRTC:%d\n",
9237 __FUNCTION__, __sna_crtc_id(sna_crtc)));
9238
9239 if (sna_crtc->client_bo == NULL)
9240 return;
9241
9242 assert(sna_crtc->client_bo->refcnt >= sna_crtc->client_bo->active_scanout);
9243 sna_crtc->client_bo->active_scanout--;
9244 kgem_bo_destroy(&sna->kgem, sna_crtc->client_bo);
9245 sna_crtc->client_bo = NULL;
9246 list_del(&sna_crtc->shadow_link);
9247 sna->mode.shadow_dirty = true;
9248
9249 sna_crtc_damage(crtc);
9250 }
9251
move_crtc_to_gpu(struct sna * sna)9252 static bool move_crtc_to_gpu(struct sna *sna)
9253 {
9254 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
9255 int i;
9256
9257 for (i = 0; i < sna->mode.num_real_crtc; i++) {
9258 struct sna_crtc *crtc = to_sna_crtc(config->crtc[i]);
9259 unsigned hint;
9260
9261 assert(crtc);
9262
9263 if (crtc->bo == NULL)
9264 continue;
9265
9266 if (crtc->slave_pixmap)
9267 continue;
9268
9269 if (crtc->client_bo)
9270 continue;
9271
9272 if (crtc->shadow_bo)
9273 continue;
9274
9275 hint = MOVE_READ | MOVE_ASYNC_HINT | __MOVE_SCANOUT;
9276 if (sna->flags & SNA_TEAR_FREE)
9277 hint |= __MOVE_FORCE;
9278
9279 DBG(("%s: CRTC %d [pipe=%d] requires frontbuffer\n",
9280 __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc)));
9281 return sna_pixmap_move_to_gpu(sna->front, hint);
9282 }
9283
9284 return true;
9285 }
9286
sna_mode_redisplay(struct sna * sna)9287 void sna_mode_redisplay(struct sna *sna)
9288 {
9289 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
9290 RegionPtr region;
9291 int i;
9292
9293 if (sna->mode.hidden) {
9294 DBG(("%s: hidden outputs, skipping\n", __FUNCTION__));
9295 return;
9296 }
9297
9298 if (!sna->mode.shadow_enabled)
9299 return;
9300
9301 assert(sna->mode.shadow_damage);
9302
9303 DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n",
9304 __FUNCTION__,
9305 !RegionNil(DamageRegion(sna->mode.shadow_damage)),
9306 sna->mode.flip_active,
9307 sna->mode.dirty));
9308 assert((sna->flags & SNA_IS_HOSTED) == 0);
9309 assert(sna->mode.shadow_active);
9310
9311 if (sna->mode.dirty)
9312 return;
9313
9314 if (sna->mode.flip_active) {
9315 DBG(("%s: %d outstanding flips\n",
9316 __FUNCTION__, sna->mode.flip_active));
9317 return;
9318 }
9319
9320 region = DamageRegion(sna->mode.shadow_damage);
9321 if (RegionNil(region))
9322 return;
9323
9324 DBG(("%s: damage: %dx(%d, %d), (%d, %d)\n",
9325 __FUNCTION__, region_num_rects(region),
9326 region->extents.x1, region->extents.y1,
9327 region->extents.x2, region->extents.y2));
9328
9329 if (!move_crtc_to_gpu(sna)) {
9330 DBG(("%s: forcing scanout update using the CPU\n", __FUNCTION__));
9331 if (!sna_pixmap_move_to_cpu(sna->front, MOVE_READ))
9332 return;
9333
9334 for (i = 0; i < sna->mode.num_real_crtc; i++) {
9335 xf86CrtcPtr crtc = config->crtc[i];
9336 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9337 RegionRec damage;
9338
9339 assert(sna_crtc != NULL);
9340 if (!sna_crtc->shadow)
9341 continue;
9342
9343 assert(crtc->enabled);
9344 assert(sna_crtc->transform || sna->flags & SNA_TEAR_FREE);
9345
9346 damage.extents = crtc->bounds;
9347 damage.data = NULL;
9348 RegionIntersect(&damage, &damage, region);
9349 if (!box_empty(&damage.extents)) {
9350 DBG(("%s: fallback intersects pipe=%d [(%d, %d), (%d, %d)]\n",
9351 __FUNCTION__, __sna_crtc_pipe(sna_crtc),
9352 damage.extents.x1, damage.extents.y1,
9353 damage.extents.x2, damage.extents.y2));
9354
9355 sna_crtc_redisplay__fallback(crtc,
9356 &damage,
9357 sna_crtc->bo);
9358 }
9359 RegionUninit(&damage);
9360
9361 if (sna_crtc->slave_damage)
9362 DamageEmpty(sna_crtc->slave_damage);
9363 }
9364
9365 RegionEmpty(region);
9366 return;
9367 }
9368
9369 {
9370 struct sna_pixmap *priv;
9371
9372 priv = sna_pixmap(sna->front);
9373 assert(priv != NULL);
9374
9375 if (priv->move_to_gpu) {
9376 if (priv->move_to_gpu == wait_for_shadow &&
9377 !sna->mode.shadow_dirty) {
9378 /* No damage written to new scanout
9379 * (backbuffer), ignore redisplay request
9380 * and continue with the current intact
9381 * scanout (frontbuffer).
9382 */
9383 DBG(("%s: shadow idle, skipping update\n", __FUNCTION__));
9384 RegionEmpty(region);
9385 return;
9386 }
9387
9388 (void)priv->move_to_gpu(sna, priv, 0);
9389 }
9390
9391 assert(priv->move_to_gpu == NULL);
9392 }
9393
9394 for (i = 0; i < sna->mode.num_real_crtc; i++) {
9395 xf86CrtcPtr crtc = config->crtc[i];
9396 struct sna_crtc *sna_crtc = to_sna_crtc(crtc);
9397 RegionRec damage;
9398 int sigio;
9399
9400 assert(sna_crtc != NULL);
9401 DBG(("%s: crtc[%d] transformed? %d\n",
9402 __FUNCTION__, i, sna_crtc->transform));
9403
9404 if (!sna_crtc->transform)
9405 continue;
9406
9407 assert(crtc->enabled);
9408 assert(sna_crtc->bo);
9409
9410 damage.extents = crtc->bounds;
9411 damage.data = NULL;
9412
9413 RegionIntersect(&damage, &damage, region);
9414 DBG(("%s: crtc[%d] damage? %d[%d]: %dx[(%d, %d), (%d, %d)]\n",
9415 __FUNCTION__, i,
9416 !box_empty(&damage.extents), RegionNotEmpty(&damage),
9417 region_num_rects(&damage),
9418 damage.extents.x1, damage.extents.y1,
9419 damage.extents.x2, damage.extents.y2));
9420 sigio = sigio_block();
9421 if (!box_empty(&damage.extents)) {
9422 if (sna->flags & SNA_TEAR_FREE) {
9423 RegionRec new_damage;
9424 struct drm_mode_crtc_page_flip arg;
9425 struct kgem_bo *bo;
9426
9427 RegionNull(&new_damage);
9428 RegionCopy(&new_damage, &damage);
9429
9430 bo = sna_crtc->cache_bo;
9431 if (bo == NULL) {
9432 damage.extents = crtc->bounds;
9433 damage.data = NULL;
9434 bo = kgem_create_2d(&sna->kgem,
9435 crtc->mode.HDisplay,
9436 crtc->mode.VDisplay,
9437 crtc->scrn->bitsPerPixel,
9438 sna_crtc->bo->tiling,
9439 CREATE_SCANOUT);
9440 if (bo == NULL)
9441 continue;
9442 } else
9443 RegionUnion(&damage, &damage, &sna_crtc->crtc_damage);
9444 sna_crtc->crtc_damage = new_damage;
9445
9446 sna_crtc_redisplay(crtc, &damage, bo);
9447 kgem_bo_submit(&sna->kgem, bo);
9448 __kgem_bo_clear_dirty(bo);
9449
9450 assert_crtc_fb(sna, sna_crtc);
9451 arg.crtc_id = __sna_crtc_id(sna_crtc);
9452 arg.fb_id = get_fb(sna, bo,
9453 crtc->mode.HDisplay,
9454 crtc->mode.VDisplay);
9455 if (arg.fb_id == 0)
9456 goto disable1;
9457
9458 arg.user_data = (uintptr_t)sna_crtc;
9459 arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
9460 arg.reserved = 0;
9461
9462 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
9463 if (sna_crtc_flip(sna, sna_crtc, bo, 0, 0)) {
9464 DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9465 __FUNCTION__, sna_crtc->bo->handle, sna_crtc->bo->active_scanout - 1,
9466 bo->handle, bo->active_scanout));
9467 assert(sna_crtc->bo->active_scanout);
9468 assert(sna_crtc->bo->refcnt >= sna_crtc->bo->active_scanout);
9469 sna_crtc->bo->active_scanout--;
9470 kgem_bo_destroy(&sna->kgem, sna_crtc->bo);
9471
9472 sna_crtc->bo = kgem_bo_reference(bo);
9473 sna_crtc->bo->active_scanout++;
9474 } else {
9475 BoxRec box;
9476 DrawableRec tmp;
9477
9478 DBG(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
9479 __FUNCTION__, arg.fb_id, i, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc), errno));
9480 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9481 "Page flipping failed, disabling TearFree\n");
9482 sna->flags &= ~SNA_TEAR_FREE;
9483
9484 disable1:
9485 box.x1 = 0;
9486 box.y1 = 0;
9487 tmp.width = box.x2 = crtc->mode.HDisplay;
9488 tmp.height = box.y2 = crtc->mode.VDisplay;
9489 tmp.depth = sna->front->drawable.depth;
9490 tmp.bitsPerPixel = sna->front->drawable.bitsPerPixel;
9491
9492 if (!sna->render.copy_boxes(sna, GXcopy,
9493 &sna->front->drawable, bo, 0, 0,
9494 &tmp, sna_crtc->bo, 0, 0,
9495 &box, 1, COPY_LAST)) {
9496 xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
9497 "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
9498 __FUNCTION__, __sna_crtc_id(sna_crtc), __sna_crtc_pipe(sna_crtc));
9499 sna_crtc_disable(crtc, false);
9500 }
9501 }
9502
9503 kgem_bo_destroy(&sna->kgem, bo);
9504 sna_crtc->cache_bo = NULL;
9505 continue;
9506 }
9507 sna->mode.flip_active++;
9508
9509 assert(sna_crtc->flip_bo == NULL);
9510 sna_crtc->flip_handler = shadow_flip_handler;
9511 sna_crtc->flip_data = sna;
9512 sna_crtc->flip_bo = bo;
9513 sna_crtc->flip_bo->active_scanout++;
9514 sna_crtc->flip_serial = sna_crtc->mode_serial;
9515 sna_crtc->flip_pending = true;
9516
9517 if (sna_crtc->bo != sna->mode.shadow) {
9518 assert_scanout(&sna->kgem, sna_crtc->bo,
9519 crtc->mode.HDisplay, crtc->mode.VDisplay);
9520 sna_crtc->cache_bo = kgem_bo_reference(sna_crtc->bo);
9521 }
9522 DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
9523 __FUNCTION__, __sna_crtc_id(sna_crtc), sna_crtc->flip_bo->handle, sna_crtc->flip_bo->active_scanout, sna_crtc->flip_serial));
9524 } else {
9525 sna_crtc_redisplay(crtc, &damage, sna_crtc->bo);
9526 kgem_scanout_flush(&sna->kgem, sna_crtc->bo);
9527 }
9528 }
9529 RegionUninit(&damage);
9530 sigio_unblock(sigio);
9531
9532 if (sna_crtc->slave_damage)
9533 DamageEmpty(sna_crtc->slave_damage);
9534 }
9535
9536 if (sna->mode.shadow) {
9537 struct kgem_bo *new = __sna_pixmap_get_bo(sna->front);
9538 struct kgem_bo *old = sna->mode.shadow;
9539 struct drm_mode_crtc_page_flip arg;
9540 uint32_t fb = 0;
9541 int sigio;
9542
9543 DBG(("%s: flipping TearFree outputs, current scanout handle=%d [active?=%d], new handle=%d [active=%d]\n",
9544 __FUNCTION__, old->handle, old->active_scanout, new->handle, new->active_scanout));
9545
9546 assert(new != old);
9547 assert(new->refcnt);
9548
9549 arg.flags = DRM_MODE_PAGE_FLIP_EVENT;
9550 arg.reserved = 0;
9551
9552 kgem_bo_submit(&sna->kgem, new);
9553 __kgem_bo_clear_dirty(new);
9554
9555 sigio = sigio_block();
9556 for (i = 0; i < sna->mode.num_real_crtc; i++) {
9557 struct sna_crtc *crtc = config->crtc[i]->driver_private;
9558 struct kgem_bo *flip_bo;
9559 int x, y;
9560
9561 assert(crtc != NULL);
9562 DBG(("%s: crtc %d [%d, pipe=%d] active? %d, transformed? %d\n",
9563 __FUNCTION__, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->bo ? crtc->bo->handle : 0, crtc->transform));
9564 if (crtc->bo == NULL || crtc->transform)
9565 continue;
9566
9567 assert(config->crtc[i]->enabled);
9568 assert(crtc->flip_bo == NULL);
9569 assert_crtc_fb(sna, crtc);
9570
9571 arg.crtc_id = __sna_crtc_id(crtc);
9572 arg.user_data = (uintptr_t)crtc;
9573
9574 if (crtc->client_bo) {
9575 DBG(("%s: apply shadow override bo for CRTC:%d on pipe=%d, handle=%d\n",
9576 __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), crtc->client_bo->handle));
9577 arg.fb_id = get_fb(sna, crtc->client_bo,
9578 crtc->base->mode.HDisplay,
9579 crtc->base->mode.VDisplay);
9580 assert(arg.fb_id != fb);
9581 flip_bo = crtc->client_bo;
9582 x = y = 0;
9583 } else {
9584 if (fb == 0)
9585 fb = get_fb(sna, new, sna->scrn->virtualX, sna->scrn->virtualY);
9586 if (fb == 0) {
9587 fixup_shadow:
9588 if (sna_pixmap_move_to_gpu(sna->front, MOVE_READ | MOVE_ASYNC_HINT)) {
9589 BoxRec box;
9590
9591 box.x1 = 0;
9592 box.y1 = 0;
9593 box.x2 = sna->scrn->virtualX;
9594 box.y2 = sna->scrn->virtualY;
9595 if (sna->render.copy_boxes(sna, GXcopy,
9596 &sna->front->drawable, __sna_pixmap_get_bo(sna->front), 0, 0,
9597 &sna->front->drawable, old, 0, 0,
9598 &box, 1, COPY_LAST)) {
9599 kgem_submit(&sna->kgem);
9600 RegionEmpty(region);
9601 }
9602 }
9603
9604 sigio_unblock(sigio);
9605 return;
9606 }
9607
9608 arg.fb_id = fb;
9609 flip_bo = new;
9610 x = crtc->base->x;
9611 y = crtc->base->y;
9612 }
9613
9614 if (crtc->bo == flip_bo) {
9615 assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9616 DBG(("%s: flip handle=%d is already on the CRTC\n",
9617 __FUNCTION__, flip_bo->handle));
9618 continue;
9619 }
9620
9621 if (flip_bo->pitch != crtc->bo->pitch || (y << 16 | x) != crtc->offset) {
9622 DBG(("%s: changing pitch (new %d =?= old %d) or offset (new %x =?= old %x)\n",
9623 __FUNCTION__,
9624 flip_bo->pitch, crtc->bo->pitch,
9625 y << 16 | x, crtc->offset));
9626 fixup_flip:
9627 if (sna_crtc_flip(sna, crtc, flip_bo, x, y)) {
9628 DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9629 __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout-1,
9630 flip_bo->handle, flip_bo->active_scanout));
9631 assert(flip_bo != crtc->bo);
9632 assert(crtc->bo->active_scanout);
9633 assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9634 crtc->bo->active_scanout--;
9635 kgem_bo_destroy(&sna->kgem, crtc->bo);
9636
9637 if (crtc->shadow_bo) {
9638 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
9639 crtc->shadow_bo = NULL;
9640 }
9641
9642 crtc->bo = kgem_bo_reference(flip_bo);
9643 crtc->bo->active_scanout++;
9644 } else {
9645 if (sna->flags & SNA_TEAR_FREE) {
9646 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9647 "Failed to prepare CRTC for page flipping, disabling TearFree\n");
9648 sna->flags &= ~SNA_TEAR_FREE;
9649 }
9650
9651 if (sna->mode.flip_active == 0) {
9652 DBG(("%s: abandoning flip attempt\n", __FUNCTION__));
9653 goto fixup_shadow;
9654 }
9655
9656 xf86DrvMsg(sna->scrn->scrnIndex, X_ERROR,
9657 "%s: page flipping failed, disabling CRTC:%d (pipe=%d)\n",
9658 __FUNCTION__, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc));
9659 sna_crtc_disable(crtc->base, false);
9660 }
9661 continue;
9662 }
9663
9664 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_PAGE_FLIP, &arg)) {
9665 ERR(("%s: flip [fb=%d] on crtc %d [%d, pipe=%d] failed - %d\n",
9666 __FUNCTION__, arg.fb_id, i, __sna_crtc_id(crtc), __sna_crtc_pipe(crtc), errno));
9667 goto fixup_flip;
9668 }
9669 sna->mode.flip_active++;
9670
9671 assert(crtc->flip_bo == NULL);
9672 crtc->flip_handler = shadow_flip_handler;
9673 crtc->flip_data = sna;
9674 crtc->flip_bo = kgem_bo_reference(flip_bo);
9675 crtc->flip_bo->active_scanout++;
9676 crtc->flip_serial = crtc->mode_serial;
9677 crtc->flip_pending = true;
9678
9679 DBG(("%s: recording flip on CRTC:%d handle=%d, active_scanout=%d, serial=%d\n",
9680 __FUNCTION__, __sna_crtc_id(crtc), crtc->flip_bo->handle, crtc->flip_bo->active_scanout, crtc->flip_serial));
9681
9682 {
9683 struct drm_i915_gem_busy busy = { .handle = flip_bo->handle, };
9684 if (drmIoctl(sna->kgem.fd, DRM_IOCTL_I915_GEM_BUSY, &busy) == 0) {
9685 if (busy.busy) {
9686 int mode = KGEM_RENDER;
9687 if (busy.busy & (0xfffe << 16))
9688 mode = KGEM_BLT;
9689 DBG(("%s: marking flip bo as busy [%x -> mode=%d]\n", __FUNCTION__, busy.busy, mode));
9690 kgem_bo_mark_busy(&sna->kgem, flip_bo, mode);
9691 } else
9692 __kgem_bo_clear_busy(flip_bo);
9693 }
9694 }
9695 }
9696 sigio_unblock(sigio);
9697
9698 DBG(("%s: flipped %d outputs, shadow active? %d\n",
9699 __FUNCTION__,
9700 sna->mode.flip_active,
9701 sna->mode.shadow ? sna->mode.shadow->handle : 0));
9702
9703 if (sna->mode.flip_active) {
9704 assert(old == sna->mode.shadow);
9705 assert(old->refcnt >= 1);
9706 set_shadow(sna, region);
9707 }
9708 } else
9709 kgem_submit(&sna->kgem);
9710
9711 RegionEmpty(region);
9712 }
9713
sna_mode_wakeup(struct sna * sna)9714 int sna_mode_wakeup(struct sna *sna)
9715 {
9716 bool defer_vblanks = sna->mode.flip_active && sna->mode.shadow_enabled;
9717 char buffer[1024];
9718 int len, i;
9719 int ret = 0;
9720
9721 again:
9722 /* In order to workaround a kernel bug in not honouring O_NONBLOCK,
9723 * check that the fd is readable before attempting to read the next
9724 * event from drm.
9725 */
9726 if (!event_pending(sna->kgem.fd))
9727 goto done;
9728
9729 /* The DRM read semantics guarantees that we always get only
9730 * complete events.
9731 */
9732 len = read(sna->kgem.fd, buffer, sizeof (buffer));
9733 if (len < (int)sizeof(struct drm_event))
9734 goto done;
9735
9736 /* Note that we cannot rely on the passed in struct sna matching
9737 * the struct sna used for the vblank event (in case it was submitted
9738 * by a different ZaphodHead). When processing the event, we must
9739 * ensure that we only use the pointer passed along with the event.
9740 */
9741
9742 DBG(("%s: len=%d\n", __FUNCTION__, len));
9743
9744 i = 0;
9745 while (i < len) {
9746 struct drm_event *e = (struct drm_event *)&buffer[i];
9747 switch (e->type) {
9748 case DRM_EVENT_VBLANK:
9749 if (defer_vblanks)
9750 defer_event(sna, e);
9751 else if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2)
9752 sna_present_vblank_handler((struct drm_event_vblank *)e);
9753 else
9754 sna_dri2_vblank_handler((struct drm_event_vblank *)e);
9755 break;
9756 case DRM_EVENT_FLIP_COMPLETE:
9757 {
9758 struct drm_event_vblank *vbl = (struct drm_event_vblank *)e;
9759 struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data;
9760 uint64_t msc;
9761
9762 /* Beware Zaphod! */
9763 sna = to_sna(crtc->base->scrn);
9764
9765 if (msc64(crtc, vbl->sequence, &msc)) {
9766 DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n",
9767 __FUNCTION__, __sna_crtc_pipe(crtc), vbl->sequence, (long long)msc, vbl->tv_sec, vbl->tv_usec));
9768 crtc->swap.tv_sec = vbl->tv_sec;
9769 crtc->swap.tv_usec = vbl->tv_usec;
9770 crtc->swap.msc = msc;
9771 }
9772 assert(crtc->flip_pending);
9773 crtc->flip_pending = false;
9774
9775 assert(crtc->flip_bo);
9776 assert(crtc->flip_bo->active_scanout);
9777 assert(crtc->flip_bo->refcnt >= crtc->flip_bo->active_scanout);
9778
9779 if (crtc->flip_serial == crtc->mode_serial) {
9780 DBG(("%s: removing handle=%d [active_scanout=%d] from scanout, installing handle=%d [active_scanout=%d]\n",
9781 __FUNCTION__, crtc->bo->handle, crtc->bo->active_scanout - 1,
9782 crtc->flip_bo->handle, crtc->flip_bo->active_scanout));
9783 assert(crtc->bo->active_scanout);
9784 assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
9785
9786 crtc->bo->active_scanout--;
9787 kgem_bo_destroy(&sna->kgem, crtc->bo);
9788
9789 if (crtc->shadow_bo) {
9790 kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
9791 crtc->shadow_bo = NULL;
9792 }
9793
9794 crtc->bo = crtc->flip_bo;
9795 crtc->flip_bo = NULL;
9796
9797 assert_crtc_fb(sna, crtc);
9798 } else {
9799 crtc->flip_bo->active_scanout--;
9800 kgem_bo_destroy(&sna->kgem, crtc->flip_bo);
9801 crtc->flip_bo = NULL;
9802 }
9803
9804 DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active));
9805 assert(sna->mode.flip_active);
9806 if (--sna->mode.flip_active == 0) {
9807 assert(crtc->flip_handler);
9808 crtc->flip_handler(vbl, crtc->flip_data);
9809 }
9810 }
9811 break;
9812 default:
9813 break;
9814 }
9815 i += e->length;
9816 ret++;
9817 }
9818
9819 goto again;
9820
9821 done:
9822 flush_events(sna);
9823 return ret;
9824 }
9825