]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-terminal/grdev-drm.c
terminal/grdrm: force deep modeset on enter
[thirdparty/systemd.git] / src / libsystemd-terminal / grdev-drm.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <libudev.h>
25 #include <stdbool.h>
26 #include <stdlib.h>
27 #include <sys/ioctl.h>
28 #include <sys/mman.h>
29 #include <sys/types.h>
30 #include <systemd/sd-bus.h>
31 #include <systemd/sd-event.h>
32 #include <unistd.h>
33
34 /* Yuck! DRM headers need system headers included first.. but we have to
35 * include it before shared/missing.h to avoid redefining ioctl bits */
36 #include <drm.h>
37 #include <drm_fourcc.h>
38 #include <drm_mode.h>
39
40 #include "bus-util.h"
41 #include "hashmap.h"
42 #include "grdev.h"
43 #include "grdev-internal.h"
44 #include "macro.h"
45 #include "udev-util.h"
46 #include "util.h"
47
48 #define GRDRM_MAX_TRIES (16)
49
50 typedef struct grdrm_object grdrm_object;
51 typedef struct grdrm_plane grdrm_plane;
52 typedef struct grdrm_connector grdrm_connector;
53 typedef struct grdrm_encoder grdrm_encoder;
54 typedef struct grdrm_crtc grdrm_crtc;
55
56 typedef struct grdrm_fb grdrm_fb;
57 typedef struct grdrm_pipe grdrm_pipe;
58 typedef struct grdrm_card grdrm_card;
59 typedef struct unmanaged_card unmanaged_card;
60 typedef struct managed_card managed_card;
61
62 /*
63 * Objects
64 */
65
66 enum {
67 GRDRM_TYPE_CRTC,
68 GRDRM_TYPE_ENCODER,
69 GRDRM_TYPE_CONNECTOR,
70 GRDRM_TYPE_PLANE,
71 GRDRM_TYPE_CNT
72 };
73
74 struct grdrm_object {
75 grdrm_card *card;
76 uint32_t id;
77 uint32_t index;
78 unsigned int type;
79 void (*free_fn) (grdrm_object *object);
80
81 bool present : 1;
82 bool assigned : 1;
83 };
84
85 struct grdrm_plane {
86 grdrm_object object;
87
88 struct {
89 uint32_t used_crtc;
90 uint32_t used_fb;
91 uint32_t gamma_size;
92
93 uint32_t n_crtcs;
94 uint32_t max_crtcs;
95 uint32_t *crtcs;
96 uint32_t n_formats;
97 uint32_t max_formats;
98 uint32_t *formats;
99 } kern;
100 };
101
102 struct grdrm_connector {
103 grdrm_object object;
104
105 struct {
106 uint32_t type;
107 uint32_t type_id;
108 uint32_t used_encoder;
109 uint32_t connection;
110 uint32_t mm_width;
111 uint32_t mm_height;
112 uint32_t subpixel;
113
114 uint32_t n_encoders;
115 uint32_t max_encoders;
116 uint32_t *encoders;
117 uint32_t n_modes;
118 uint32_t max_modes;
119 struct drm_mode_modeinfo *modes;
120 uint32_t n_props;
121 uint32_t max_props;
122 uint32_t *prop_ids;
123 uint64_t *prop_values;
124 } kern;
125 };
126
127 struct grdrm_encoder {
128 grdrm_object object;
129
130 struct {
131 uint32_t type;
132 uint32_t used_crtc;
133
134 uint32_t n_crtcs;
135 uint32_t max_crtcs;
136 uint32_t *crtcs;
137 uint32_t n_clones;
138 uint32_t max_clones;
139 uint32_t *clones;
140 } kern;
141 };
142
143 struct grdrm_crtc {
144 grdrm_object object;
145
146 struct {
147 uint32_t used_fb;
148 uint32_t fb_offset_x;
149 uint32_t fb_offset_y;
150 uint32_t gamma_size;
151
152 uint32_t n_used_connectors;
153 uint32_t max_used_connectors;
154 uint32_t *used_connectors;
155
156 bool mode_set;
157 struct drm_mode_modeinfo mode;
158 } kern;
159
160 struct {
161 bool set;
162 uint32_t fb;
163 uint32_t fb_x;
164 uint32_t fb_y;
165 uint32_t gamma;
166
167 uint32_t n_connectors;
168 uint32_t *connectors;
169
170 bool mode_set;
171 struct drm_mode_modeinfo mode;
172 } old;
173
174 struct {
175 struct drm_mode_modeinfo mode;
176 uint32_t n_connectors;
177 uint32_t max_connectors;
178 uint32_t *connectors;
179 } set;
180
181 grdrm_pipe *pipe;
182
183 bool applied : 1;
184 };
185
186 #define GRDRM_OBJECT_INIT(_card, _id, _index, _type, _free_fn) ((grdrm_object){ \
187 .card = (_card), \
188 .id = (_id), \
189 .index = (_index), \
190 .type = (_type), \
191 .free_fn = (_free_fn), \
192 })
193
194 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id);
195 int grdrm_object_add(grdrm_object *object);
196 grdrm_object *grdrm_object_free(grdrm_object *object);
197
198 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_object*, grdrm_object_free);
199
200 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index);
201 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index);
202 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index);
203 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index);
204
205 #define plane_from_object(_obj) container_of((_obj), grdrm_plane, object)
206 #define connector_from_object(_obj) container_of((_obj), grdrm_connector, object)
207 #define encoder_from_object(_obj) container_of((_obj), grdrm_encoder, object)
208 #define crtc_from_object(_obj) container_of((_obj), grdrm_crtc, object)
209
210 /*
211 * Framebuffers
212 */
213
214 struct grdrm_fb {
215 grdev_fb base;
216 grdrm_card *card;
217 uint32_t id;
218 uint32_t handles[4];
219 uint32_t offsets[4];
220 uint32_t sizes[4];
221 uint32_t flipid;
222 };
223
224 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode);
225 grdrm_fb *grdrm_fb_free(grdrm_fb *fb);
226
227 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_fb*, grdrm_fb_free);
228
229 #define fb_from_base(_fb) container_of((_fb), grdrm_fb, base)
230
231 /*
232 * Pipes
233 */
234
235 struct grdrm_pipe {
236 grdev_pipe base;
237 grdrm_crtc *crtc;
238 uint32_t counter;
239 };
240
241 #define grdrm_pipe_from_base(_e) container_of((_e), grdrm_pipe, base)
242
243 #define GRDRM_PIPE_NAME_MAX (GRDRM_CARD_NAME_MAX + 1 + DECIMAL_STR_MAX(uint32_t))
244
245 static const grdev_pipe_vtable grdrm_pipe_vtable;
246
247 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs);
248
249 /*
250 * Cards
251 */
252
253 struct grdrm_card {
254 grdev_card base;
255
256 int fd;
257 sd_event_source *fd_src;
258
259 uint32_t n_crtcs;
260 uint32_t n_encoders;
261 uint32_t n_connectors;
262 uint32_t n_planes;
263 uint32_t max_ids;
264 Hashmap *object_map;
265
266 bool async_hotplug : 1;
267 bool hotplug : 1;
268 bool running : 1;
269 bool ready : 1;
270 bool cap_dumb : 1;
271 bool cap_monotonic : 1;
272 };
273
274 struct unmanaged_card {
275 grdrm_card card;
276 char *devnode;
277 };
278
279 struct managed_card {
280 grdrm_card card;
281 dev_t devnum;
282
283 sd_bus_slot *slot_pause_device;
284 sd_bus_slot *slot_resume_device;
285 sd_bus_slot *slot_take_device;
286
287 bool requested : 1; /* TakeDevice() was sent */
288 bool acquired : 1; /* TakeDevice() was successful */
289 bool master : 1; /* we are DRM-Master */
290 };
291
292 #define grdrm_card_from_base(_e) container_of((_e), grdrm_card, base)
293 #define unmanaged_card_from_base(_e) \
294 container_of(grdrm_card_from_base(_e), unmanaged_card, card)
295 #define managed_card_from_base(_e) \
296 container_of(grdrm_card_from_base(_e), managed_card, card)
297
298 #define GRDRM_CARD_INIT(_vtable, _session) ((grdrm_card){ \
299 .base = GRDEV_CARD_INIT((_vtable), (_session)), \
300 .fd = -1, \
301 .max_ids = 32, \
302 })
303
304 #define GRDRM_CARD_NAME_MAX (6 + DECIMAL_STR_MAX(unsigned) * 2)
305
306 static const grdev_card_vtable unmanaged_card_vtable;
307 static const grdev_card_vtable managed_card_vtable;
308
309 static int grdrm_card_open(grdrm_card *card, int dev_fd);
310 static void grdrm_card_close(grdrm_card *card);
311 static bool grdrm_card_async(grdrm_card *card, int r);
312
313 /*
314 * The page-flip event of the kernel provides 64bit of arbitrary user-data. As
315 * drivers tend to drop events on intermediate deep mode-sets or because we
316 * might receive events during session activation, we try to avoid allocaing
317 * dynamic data on those events. Instead, we safe the CRTC id plus a 32bit
318 * counter in there. This way, we only get 32bit counters, not 64bit, but that
319 * should be more than enough. On the bright side, we no longer care whether we
320 * lose events. No memory leaks will occur.
321 * Modern DRM drivers might be fixed to no longer leak events, but we want to
322 * be safe. And associating dynamically allocated data with those events is
323 * kinda ugly, anyway.
324 */
325
326 static uint64_t grdrm_encode_vblank_data(uint32_t id, uint32_t counter) {
327 return id | ((uint64_t)counter << 32);
328 }
329
330 static void grdrm_decode_vblank_data(uint64_t data, uint32_t *out_id, uint32_t *out_counter) {
331 if (out_id)
332 *out_id = data & 0xffffffffU;
333 if (out_counter)
334 *out_counter = (data >> 32) & 0xffffffffU;
335 }
336
337 static bool grdrm_modes_compatible(const struct drm_mode_modeinfo *a, const struct drm_mode_modeinfo *b) {
338 assert(a);
339 assert(b);
340
341 /* Test whether both modes are compatible according to our internal
342 * assumptions on modes. This comparison is highly dependent on how
343 * we treat modes in grdrm. If we export mode details, we need to
344 * make this comparison much stricter. */
345
346 if (a->hdisplay != b->hdisplay)
347 return false;
348 if (a->vdisplay != b->vdisplay)
349 return false;
350 if (a->vrefresh != b->vrefresh)
351 return false;
352
353 return true;
354 }
355
356 /*
357 * Objects
358 */
359
360 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
361 assert_return(card, NULL);
362
363 return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
364 }
365
366 int grdrm_object_add(grdrm_object *object) {
367 int r;
368
369 assert(object);
370 assert(object->card);
371 assert(object->id > 0);
372 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
373 assert(object->free_fn);
374
375 if (object->index >= 32)
376 log_debug("grdrm: %s: object index exceeds 32bit masks: type=%u, index=%" PRIu32,
377 object->card->base.name, object->type, object->index);
378
379 r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
380 if (r < 0)
381 return r;
382
383 return 0;
384 }
385
386 grdrm_object *grdrm_object_free(grdrm_object *object) {
387 if (!object)
388 return NULL;
389
390 assert(object->card);
391 assert(object->id > 0);
392 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
393 assert(object->free_fn);
394
395 hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
396
397 object->free_fn(object);
398 return NULL;
399 }
400
401 /*
402 * Planes
403 */
404
405 static void plane_free(grdrm_object *object) {
406 grdrm_plane *plane = plane_from_object(object);
407
408 free(plane->kern.formats);
409 free(plane->kern.crtcs);
410 free(plane);
411 }
412
413 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index) {
414 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
415 grdrm_plane *plane;
416 int r;
417
418 assert(card);
419
420 plane = new0(grdrm_plane, 1);
421 if (!plane)
422 return -ENOMEM;
423
424 object = &plane->object;
425 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
426
427 plane->kern.max_crtcs = 32;
428 plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
429 if (!plane->kern.crtcs)
430 return -ENOMEM;
431
432 plane->kern.max_formats = 32;
433 plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
434 if (!plane->kern.formats)
435 return -ENOMEM;
436
437 r = grdrm_object_add(object);
438 if (r < 0)
439 return r;
440
441 if (out)
442 *out = plane;
443 object = NULL;
444 return 0;
445 }
446
447 static int grdrm_plane_resync(grdrm_plane *plane) {
448 grdrm_card *card = plane->object.card;
449 size_t tries;
450 int r;
451
452 assert(plane);
453
454 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
455 struct drm_mode_get_plane res;
456 grdrm_object *object;
457 bool resized = false;
458 Iterator iter;
459
460 zero(res);
461 res.plane_id = plane->object.id;
462 res.format_type_ptr = PTR_TO_UINT64(plane->kern.formats);
463 res.count_format_types = plane->kern.max_formats;
464
465 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
466 if (r < 0) {
467 r = -errno;
468 if (r == -ENOENT) {
469 card->async_hotplug = true;
470 r = 0;
471 log_debug("grdrm: %s: plane %u removed during resync", card->base.name, plane->object.id);
472 } else {
473 log_debug("grdrm: %s: cannot retrieve plane %u: %m", card->base.name, plane->object.id);
474 }
475
476 return r;
477 }
478
479 plane->kern.n_crtcs = 0;
480 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
481
482 HASHMAP_FOREACH(object, card->object_map, iter) {
483 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
484 continue;
485 if (!(res.possible_crtcs & (1 << object->index)))
486 continue;
487 if (plane->kern.n_crtcs >= 32) {
488 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
489 card->base.name, plane->object.id);
490 continue;
491 }
492
493 plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
494 }
495
496 if (res.count_format_types > plane->kern.max_formats) {
497 uint32_t max, *t;
498
499 max = ALIGN_POWER2(res.count_format_types);
500 if (!max || max > UINT16_MAX) {
501 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
502 return -ERANGE;
503 }
504
505 t = realloc(plane->kern.formats, sizeof(*t) * max);
506 if (!t)
507 return -ENOMEM;
508
509 plane->kern.formats = t;
510 plane->kern.max_formats = max;
511 resized = true;
512 }
513
514 if (resized)
515 continue;
516
517 plane->kern.n_formats = res.count_format_types;
518 plane->kern.used_crtc = res.crtc_id;
519 plane->kern.used_fb = res.fb_id;
520 plane->kern.gamma_size = res.gamma_size;
521
522 break;
523 }
524
525 if (tries >= GRDRM_MAX_TRIES) {
526 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
527 return -EFAULT;
528 }
529
530 return 0;
531 }
532
533 /*
534 * Connectors
535 */
536
537 static void connector_free(grdrm_object *object) {
538 grdrm_connector *connector = connector_from_object(object);
539
540 free(connector->kern.prop_values);
541 free(connector->kern.prop_ids);
542 free(connector->kern.modes);
543 free(connector->kern.encoders);
544 free(connector);
545 }
546
547 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
548 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
549 grdrm_connector *connector;
550 int r;
551
552 assert(card);
553
554 connector = new0(grdrm_connector, 1);
555 if (!connector)
556 return -ENOMEM;
557
558 object = &connector->object;
559 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
560
561 connector->kern.max_encoders = 32;
562 connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
563 if (!connector->kern.encoders)
564 return -ENOMEM;
565
566 connector->kern.max_modes = 32;
567 connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
568 if (!connector->kern.modes)
569 return -ENOMEM;
570
571 connector->kern.max_props = 32;
572 connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
573 connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
574 if (!connector->kern.prop_ids || !connector->kern.prop_values)
575 return -ENOMEM;
576
577 r = grdrm_object_add(object);
578 if (r < 0)
579 return r;
580
581 if (out)
582 *out = connector;
583 object = NULL;
584 return 0;
585 }
586
587 static int grdrm_connector_resync(grdrm_connector *connector) {
588 grdrm_card *card = connector->object.card;
589 size_t tries;
590 int r;
591
592 assert(connector);
593
594 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
595 struct drm_mode_get_connector res;
596 bool resized = false;
597 uint32_t max;
598
599 zero(res);
600 res.connector_id = connector->object.id;
601 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
602 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
603 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
604 res.count_encoders = connector->kern.max_encoders;
605 res.count_props = connector->kern.max_props;
606
607 /* The kernel reads modes from the EDID information only if we
608 * pass count_modes==0. This is a legacy hack for libdrm (which
609 * called every ioctl twice). Now we have to adopt.. *sigh*.
610 * If we never received an hotplug event, there's no reason to
611 * sync modes. EDID reads are heavy, so skip that if not
612 * required. */
613 if (card->hotplug) {
614 if (tries > 0) {
615 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
616 res.count_modes = connector->kern.max_modes;
617 } else {
618 resized = true;
619 }
620 }
621
622 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
623 if (r < 0) {
624 r = -errno;
625 if (r == -ENOENT) {
626 card->async_hotplug = true;
627 r = 0;
628 log_debug("grdrm: %s: connector %u removed during resync", card->base.name, connector->object.id);
629 } else {
630 log_debug("grdrm: %s: cannot retrieve connector %u: %m", card->base.name, connector->object.id);
631 }
632
633 return r;
634 }
635
636 if (res.count_encoders > connector->kern.max_encoders) {
637 uint32_t *t;
638
639 max = ALIGN_POWER2(res.count_encoders);
640 if (!max || max > UINT16_MAX) {
641 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
642 return -ERANGE;
643 }
644
645 t = realloc(connector->kern.encoders, sizeof(*t) * max);
646 if (!t)
647 return -ENOMEM;
648
649 connector->kern.encoders = t;
650 connector->kern.max_encoders = max;
651 resized = true;
652 }
653
654 if (res.count_modes > connector->kern.max_modes) {
655 struct drm_mode_modeinfo *t;
656
657 max = ALIGN_POWER2(res.count_modes);
658 if (!max || max > UINT16_MAX) {
659 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
660 return -ERANGE;
661 }
662
663 t = realloc(connector->kern.modes, sizeof(*t) * max);
664 if (!t)
665 return -ENOMEM;
666
667 connector->kern.modes = t;
668 connector->kern.max_modes = max;
669 resized = true;
670 }
671
672 if (res.count_props > connector->kern.max_props) {
673 uint32_t *tids;
674 uint64_t *tvals;
675
676 max = ALIGN_POWER2(res.count_props);
677 if (!max || max > UINT16_MAX) {
678 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
679 return -ERANGE;
680 }
681
682 tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
683 if (!tids)
684 return -ENOMEM;
685 connector->kern.prop_ids = tids;
686
687 tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
688 if (!tvals)
689 return -ENOMEM;
690 connector->kern.prop_values = tvals;
691
692 connector->kern.max_props = max;
693 resized = true;
694 }
695
696 if (resized)
697 continue;
698
699 connector->kern.n_encoders = res.count_encoders;
700 connector->kern.n_props = res.count_props;
701 connector->kern.type = res.connector_type;
702 connector->kern.type_id = res.connector_type_id;
703 connector->kern.used_encoder = res.encoder_id;
704 connector->kern.connection = res.connection;
705 connector->kern.mm_width = res.mm_width;
706 connector->kern.mm_height = res.mm_height;
707 connector->kern.subpixel = res.subpixel;
708 if (res.modes_ptr == PTR_TO_UINT64(connector->kern.modes))
709 connector->kern.n_modes = res.count_modes;
710
711 break;
712 }
713
714 if (tries >= GRDRM_MAX_TRIES) {
715 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
716 return -EFAULT;
717 }
718
719 return 0;
720 }
721
722 /*
723 * Encoders
724 */
725
726 static void encoder_free(grdrm_object *object) {
727 grdrm_encoder *encoder = encoder_from_object(object);
728
729 free(encoder->kern.clones);
730 free(encoder->kern.crtcs);
731 free(encoder);
732 }
733
734 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
735 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
736 grdrm_encoder *encoder;
737 int r;
738
739 assert(card);
740
741 encoder = new0(grdrm_encoder, 1);
742 if (!encoder)
743 return -ENOMEM;
744
745 object = &encoder->object;
746 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
747
748 encoder->kern.max_crtcs = 32;
749 encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
750 if (!encoder->kern.crtcs)
751 return -ENOMEM;
752
753 encoder->kern.max_clones = 32;
754 encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
755 if (!encoder->kern.clones)
756 return -ENOMEM;
757
758 r = grdrm_object_add(object);
759 if (r < 0)
760 return r;
761
762 if (out)
763 *out = encoder;
764 object = NULL;
765 return 0;
766 }
767
768 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
769 grdrm_card *card = encoder->object.card;
770 struct drm_mode_get_encoder res;
771 grdrm_object *object;
772 Iterator iter;
773 int r;
774
775 assert(encoder);
776
777 zero(res);
778 res.encoder_id = encoder->object.id;
779
780 r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
781 if (r < 0) {
782 r = -errno;
783 if (r == -ENOENT) {
784 card->async_hotplug = true;
785 r = 0;
786 log_debug("grdrm: %s: encoder %u removed during resync", card->base.name, encoder->object.id);
787 } else {
788 log_debug("grdrm: %s: cannot retrieve encoder %u: %m", card->base.name, encoder->object.id);
789 }
790
791 return r;
792 }
793
794 encoder->kern.type = res.encoder_type;
795 encoder->kern.used_crtc = res.crtc_id;
796
797 encoder->kern.n_crtcs = 0;
798 memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
799
800 HASHMAP_FOREACH(object, card->object_map, iter) {
801 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
802 continue;
803 if (!(res.possible_crtcs & (1 << object->index)))
804 continue;
805 if (encoder->kern.n_crtcs >= 32) {
806 log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
807 continue;
808 }
809
810 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
811 }
812
813 encoder->kern.n_clones = 0;
814 memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
815
816 HASHMAP_FOREACH(object, card->object_map, iter) {
817 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
818 continue;
819 if (!(res.possible_clones & (1 << object->index)))
820 continue;
821 if (encoder->kern.n_clones >= 32) {
822 log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
823 continue;
824 }
825
826 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
827 }
828
829 return 0;
830 }
831
832 /*
833 * Crtcs
834 */
835
836 static void crtc_free(grdrm_object *object) {
837 grdrm_crtc *crtc = crtc_from_object(object);
838
839 if (crtc->pipe)
840 grdev_pipe_free(&crtc->pipe->base);
841 free(crtc->set.connectors);
842 free(crtc->old.connectors);
843 free(crtc->kern.used_connectors);
844 free(crtc);
845 }
846
847 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
848 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
849 grdrm_crtc *crtc;
850 int r;
851
852 assert(card);
853
854 crtc = new0(grdrm_crtc, 1);
855 if (!crtc)
856 return -ENOMEM;
857
858 object = &crtc->object;
859 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
860
861 crtc->kern.max_used_connectors = 32;
862 crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
863 if (!crtc->kern.used_connectors)
864 return -ENOMEM;
865
866 crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
867 if (!crtc->old.connectors)
868 return -ENOMEM;
869
870 r = grdrm_object_add(object);
871 if (r < 0)
872 return r;
873
874 if (out)
875 *out = crtc;
876 object = NULL;
877 return 0;
878 }
879
880 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
881 grdrm_card *card = crtc->object.card;
882 struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
883 int r;
884
885 assert(crtc);
886
887 /* make sure we can cache any combination later */
888 if (card->n_connectors > crtc->kern.max_used_connectors) {
889 uint32_t max, *t;
890
891 max = ALIGN_POWER2(card->n_connectors);
892 if (!max)
893 return -ENOMEM;
894
895 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
896 if (!t)
897 return -ENOMEM;
898
899 crtc->kern.used_connectors = t;
900 crtc->kern.max_used_connectors = max;
901
902 if (!crtc->old.set) {
903 crtc->old.connectors = calloc(sizeof(*t), max);
904 if (!crtc->old.connectors)
905 return -ENOMEM;
906 }
907 }
908
909 /* GETCRTC doesn't return connectors. We have to read all
910 * encoder-state and deduce the setup ourselves.. */
911 crtc->kern.n_used_connectors = 0;
912
913 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
914 if (r < 0) {
915 r = -errno;
916 if (r == -ENOENT) {
917 card->async_hotplug = true;
918 r = 0;
919 log_debug("grdrm: %s: crtc %u removed during resync", card->base.name, crtc->object.id);
920 } else {
921 log_debug("grdrm: %s: cannot retrieve crtc %u: %m", card->base.name, crtc->object.id);
922 }
923
924 return r;
925 }
926
927 crtc->kern.used_fb = res.fb_id;
928 crtc->kern.fb_offset_x = res.x;
929 crtc->kern.fb_offset_y = res.y;
930 crtc->kern.gamma_size = res.gamma_size;
931 crtc->kern.mode_set = res.mode_valid;
932 crtc->kern.mode = res.mode;
933
934 return 0;
935 }
936
937 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
938 uint32_t n_connectors;
939 int r;
940
941 assert(crtc);
942 assert(!crtc->object.assigned);
943 assert(!connector || !connector->object.assigned);
944
945 /* always mark both as assigned; even if assignments cannot be set */
946 crtc->object.assigned = true;
947 if (connector)
948 connector->object.assigned = true;
949
950 /* we will support hw clone mode in the future */
951 n_connectors = connector ? 1 : 0;
952
953 /* bail out if configuration is preserved */
954 if (crtc->set.n_connectors == n_connectors &&
955 (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
956 return;
957
958 crtc->applied = false;
959 crtc->set.n_connectors = 0;
960
961 if (n_connectors > crtc->set.max_connectors) {
962 uint32_t max, *t;
963
964 max = ALIGN_POWER2(n_connectors);
965 if (!max) {
966 r = -ENOMEM;
967 goto error;
968 }
969
970 t = realloc(crtc->set.connectors, sizeof(*t) * max);
971 if (!t) {
972 r = -ENOMEM;
973 goto error;
974 }
975
976 crtc->set.connectors = t;
977 crtc->set.max_connectors = max;
978 }
979
980 if (connector) {
981 struct drm_mode_modeinfo *m, *pref = NULL;
982 uint32_t i;
983
984 for (i = 0; i < connector->kern.n_modes; ++i) {
985 m = &connector->kern.modes[i];
986
987 /* ignore 3D modes by default */
988 if (m->flags & DRM_MODE_FLAG_3D_MASK)
989 continue;
990
991 if (!pref) {
992 pref = m;
993 continue;
994 }
995
996 /* use PREFERRED over non-PREFERRED */
997 if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
998 !(m->type & DRM_MODE_TYPE_PREFERRED))
999 continue;
1000
1001 /* use DRIVER over non-PREFERRED|DRIVER */
1002 if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
1003 !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
1004 continue;
1005
1006 /* always prefer higher resolution */
1007 if (pref->hdisplay > m->hdisplay ||
1008 (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1009 continue;
1010
1011 pref = m;
1012 }
1013
1014 if (pref) {
1015 crtc->set.mode = *pref;
1016 crtc->set.n_connectors = 1;
1017 crtc->set.connectors[0] = connector->object.id;
1018 log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1019 crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1020 } else {
1021 log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1022 crtc->object.card->base.name, connector->object.id);
1023 }
1024 }
1025
1026 return;
1027
1028 error:
1029 log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1030 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1031 }
1032
1033 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1034 grdrm_pipe *pipe;
1035 grdrm_fb *fb;
1036 size_t i;
1037 int r;
1038
1039 assert(crtc);
1040 assert(crtc->object.assigned);
1041
1042 if (crtc->set.n_connectors < 1) {
1043 if (crtc->pipe)
1044 grdev_pipe_free(&crtc->pipe->base);
1045 crtc->pipe = NULL;
1046 return;
1047 }
1048
1049 pipe = crtc->pipe;
1050 if (pipe) {
1051 if (pipe->base.width != crtc->set.mode.hdisplay ||
1052 pipe->base.height != crtc->set.mode.vdisplay ||
1053 pipe->base.vrefresh != crtc->set.mode.vrefresh) {
1054 grdev_pipe_free(&pipe->base);
1055 crtc->pipe = NULL;
1056 pipe = NULL;
1057 }
1058 }
1059
1060 if (crtc->pipe) {
1061 pipe->base.front = NULL;
1062 pipe->base.back = NULL;
1063 for (i = 0; i < pipe->base.max_fbs; ++i) {
1064 fb = fb_from_base(pipe->base.fbs[i]);
1065 if (fb->id == crtc->kern.used_fb)
1066 pipe->base.front = &fb->base;
1067 else if (!fb->flipid)
1068 pipe->base.back = &fb->base;
1069 }
1070 } else {
1071 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1072 if (r < 0) {
1073 log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1074 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1075 return;
1076 }
1077
1078 for (i = 0; i < pipe->base.max_fbs; ++i) {
1079 r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1080 if (r < 0) {
1081 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1082 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1083 grdev_pipe_free(&pipe->base);
1084 return;
1085 }
1086
1087 pipe->base.fbs[i] = &fb->base;
1088 }
1089
1090 pipe->base.front = NULL;
1091 pipe->base.back = pipe->base.fbs[0];
1092 crtc->pipe = pipe;
1093 }
1094
1095 grdev_pipe_ready(&crtc->pipe->base, true);
1096 }
1097
1098 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb *basefb) {
1099 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1100 grdrm_card *card = crtc->object.card;
1101 grdrm_pipe *pipe = crtc->pipe;
1102 grdrm_fb *fb;
1103 int r;
1104
1105 assert(crtc);
1106 assert(basefb);
1107 assert(pipe);
1108
1109 fb = fb_from_base(basefb);
1110
1111 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1112 set_crtc.count_connectors = crtc->set.n_connectors;
1113 set_crtc.fb_id = fb->id;
1114 set_crtc.x = 0;
1115 set_crtc.y = 0;
1116 set_crtc.mode_valid = 1;
1117 set_crtc.mode = crtc->set.mode;
1118
1119 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1120 if (r < 0) {
1121 r = -errno;
1122 log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1123 card->base.name, crtc->object.id);
1124
1125 grdrm_card_async(card, r);
1126 return;
1127 }
1128
1129 if (!crtc->applied) {
1130 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1131 card->base.name, crtc->object.id);
1132 crtc->applied = true;
1133 }
1134
1135 pipe->base.back = NULL;
1136 pipe->base.front = &fb->base;
1137 fb->flipid = 0;
1138 ++pipe->counter;
1139 pipe->base.flipping = false;
1140 pipe->base.flip = false;
1141
1142 /* We cannot schedule dummy page-flips on pipes, hence, the
1143 * application would have to schedule their own frame-timers.
1144 * To avoid duplicating that everywhere, we schedule our own
1145 * timer and raise a fake FRAME event when it fires. */
1146 grdev_pipe_schedule(&pipe->base, 1);
1147 }
1148
1149 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
1150 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1151 grdrm_card *card = crtc->object.card;
1152 grdrm_pipe *pipe = crtc->pipe;
1153 grdrm_fb *fb;
1154 uint32_t cnt;
1155 int r;
1156
1157 assert(crtc);
1158 assert(basefb);
1159 assert(pipe);
1160
1161 if (!crtc->applied) {
1162 if (!grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1163 return 0;
1164
1165 /* TODO: Theoretically, we should be able to page-flip to our
1166 * framebuffer here. We didn't perform any deep modeset, but the
1167 * DRM driver is really supposed to reject our page-flip in case
1168 * the FB is not compatible. We then properly fall back to a
1169 * deep modeset.
1170 * As it turns out, drivers don't to this. Therefore, we need to
1171 * perform a full modeset on enter now. We might avoid this in
1172 * the future with fixed drivers.. */
1173
1174 return 0;
1175 }
1176
1177 fb = fb_from_base(basefb);
1178
1179 cnt = ++pipe->counter ? : ++pipe->counter;
1180 page_flip.fb_id = fb->id;
1181 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1182 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1183
1184 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1185 if (r < 0) {
1186 r = -errno;
1187 /* Avoid excessive logging on EINVAL; it is currently not
1188 * possible to see whether cards support page-flipping, so
1189 * avoid logging on each frame. */
1190 if (r != -EINVAL)
1191 log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1192 card->base.name, crtc->object.id);
1193
1194 if (grdrm_card_async(card, r))
1195 return r;
1196
1197 return 0;
1198 }
1199
1200 if (!crtc->applied) {
1201 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1202 card->base.name, crtc->object.id);
1203 crtc->applied = true;
1204 }
1205
1206 pipe->base.flipping = true;
1207 pipe->base.flip = false;
1208 pipe->counter = cnt;
1209 fb->flipid = cnt;
1210 pipe->base.back = NULL;
1211
1212 /* Raise fake FRAME event if it takes longer than 2
1213 * frames to receive the pageflip event. We assume the
1214 * queue ran over or some other error happened. */
1215 grdev_pipe_schedule(&pipe->base, 2);
1216
1217 return 1;
1218 }
1219
1220 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1221 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1222 grdrm_card *card = crtc->object.card;
1223 grdrm_pipe *pipe;
1224 grdev_fb *fb;
1225 int r;
1226
1227 assert(crtc);
1228 assert(crtc->object.assigned);
1229
1230 pipe = crtc->pipe;
1231 if (!pipe) {
1232 /* If a crtc is not assigned any connector, we want any
1233 * previous setup to be cleared, so make sure the CRTC is
1234 * disabled. Otherwise, there might be content on the CRTC
1235 * while we run, which is not what we want.
1236 * If you want to avoid modesets on specific CRTCs, you should
1237 * still keep their assignment, but never enable the resulting
1238 * pipe. This way, we wouldn't touch it at all. */
1239 if (!crtc->applied) {
1240 crtc->applied = true;
1241 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1242 if (r < 0) {
1243 r = -errno;
1244 log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1245 card->base.name, crtc->object.id);
1246
1247 grdrm_card_async(card, r);
1248 return;
1249 }
1250
1251 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1252 card->base.name, crtc->object.id);
1253 }
1254
1255 return;
1256 }
1257
1258 /* we always fully ignore disabled pipes */
1259 if (!pipe->base.enabled)
1260 return;
1261
1262 assert(crtc->set.n_connectors > 0);
1263
1264 if (pipe->base.flip)
1265 fb = pipe->base.back;
1266 else if (!crtc->applied)
1267 fb = pipe->base.front;
1268 else
1269 return;
1270
1271 if (!fb)
1272 return;
1273
1274 r = grdrm_crtc_commit_flip(crtc, fb);
1275 if (r == 0) {
1276 /* in case we couldn't page-flip, perform deep modeset */
1277 grdrm_crtc_commit_deep(crtc, fb);
1278 }
1279 }
1280
1281 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1282 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1283 grdrm_card *card = crtc->object.card;
1284 int r;
1285
1286 if (!crtc->old.set)
1287 return;
1288
1289 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1290 set_crtc.count_connectors = crtc->old.n_connectors;
1291 set_crtc.fb_id = crtc->old.fb;
1292 set_crtc.x = crtc->old.fb_x;
1293 set_crtc.y = crtc->old.fb_y;
1294 set_crtc.gamma_size = crtc->old.gamma;
1295 set_crtc.mode_valid = crtc->old.mode_set;
1296 set_crtc.mode = crtc->old.mode;
1297
1298 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1299 if (r < 0) {
1300 r = -errno;
1301 log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1302 card->base.name, crtc->object.id);
1303
1304 grdrm_card_async(card, r);
1305 return;
1306 }
1307
1308 if (crtc->pipe) {
1309 ++crtc->pipe->counter;
1310 crtc->pipe->base.front = NULL;
1311 crtc->pipe->base.flipping = false;
1312 }
1313
1314 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1315 }
1316
1317 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1318 bool flipped = false;
1319 grdrm_pipe *pipe;
1320 size_t i;
1321
1322 assert(crtc);
1323 assert(event);
1324
1325 pipe = crtc->pipe;
1326 if (!pipe)
1327 return;
1328
1329 /* We got a page-flip event. To be safe, we reset all FBs on the same
1330 * pipe that have smaller flipids than the flip we got as we know they
1331 * are executed in order. We need to do this to guarantee
1332 * queue-overflows or other missed events don't cause starvation.
1333 * Furthermore, if we find the exact FB this event is for, *and* this
1334 * is the most recent event, we mark it as front FB and raise a
1335 * frame event. */
1336
1337 for (i = 0; i < pipe->base.max_fbs; ++i) {
1338 grdrm_fb *fb;
1339
1340 if (!pipe->base.fbs[i])
1341 continue;
1342
1343 fb = fb_from_base(pipe->base.fbs[i]);
1344 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1345 pipe->base.front = &fb->base;
1346 fb->flipid = 0;
1347 flipped = true;
1348 } else if (counter - fb->flipid < UINT16_MAX) {
1349 fb->flipid = 0;
1350 }
1351 }
1352
1353 if (flipped) {
1354 crtc->pipe->base.flipping = false;
1355 grdev_pipe_frame(&pipe->base);
1356 }
1357 }
1358
1359 /*
1360 * Framebuffers
1361 */
1362
1363 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1364 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1365 struct drm_mode_create_dumb create_dumb = { };
1366 struct drm_mode_map_dumb map_dumb = { };
1367 struct drm_mode_fb_cmd2 add_fb = { };
1368 unsigned int i;
1369 int r;
1370
1371 assert_return(out, -EINVAL);
1372 assert_return(card, -EINVAL);
1373
1374 fb = new0(grdrm_fb, 1);
1375 if (!fb)
1376 return -ENOMEM;
1377
1378 /* TODO: we should choose a compatible format of the previous CRTC
1379 * setting to allow page-flip to it. Only choose fallback if the
1380 * previous setting was crap (non xrgb32'ish). */
1381
1382 fb->card = card;
1383 fb->base.format = DRM_FORMAT_XRGB8888;
1384 fb->base.width = mode->hdisplay;
1385 fb->base.height = mode->vdisplay;
1386
1387 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1388 fb->base.maps[i] = MAP_FAILED;
1389
1390 create_dumb.width = fb->base.width;
1391 create_dumb.height = fb->base.height;
1392 create_dumb.bpp = 32;
1393
1394 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1395 if (r < 0) {
1396 r = -errno;
1397 log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1398 card->base.name, fb->base.width, fb->base.height);
1399 return r;
1400 }
1401
1402 fb->handles[0] = create_dumb.handle;
1403 fb->base.strides[0] = create_dumb.pitch;
1404 fb->sizes[0] = create_dumb.size;
1405
1406 map_dumb.handle = fb->handles[0];
1407
1408 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1409 if (r < 0) {
1410 r = -errno;
1411 log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1412 card->base.name, fb->base.width, fb->base.height);
1413 return r;
1414 }
1415
1416 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1417 if (fb->base.maps[0] == MAP_FAILED) {
1418 r = -errno;
1419 log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1420 card->base.name, fb->base.width, fb->base.height);
1421 return r;
1422 }
1423
1424 memzero(fb->base.maps[0], fb->sizes[0]);
1425
1426 add_fb.width = fb->base.width;
1427 add_fb.height = fb->base.height;
1428 add_fb.pixel_format = fb->base.format;
1429 add_fb.flags = 0;
1430 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1431 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1432 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1433
1434 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1435 if (r < 0) {
1436 r = -errno;
1437 log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1438 card->base.name, fb->base.width, fb->base.height);
1439 return r;
1440 }
1441
1442 fb->id = add_fb.fb_id;
1443
1444 *out = fb;
1445 fb = NULL;
1446 return 0;
1447 }
1448
1449 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1450 unsigned int i;
1451 int r;
1452
1453 if (!fb)
1454 return NULL;
1455
1456 assert(fb->card);
1457
1458 if (fb->base.free_fn)
1459 fb->base.free_fn(fb->base.data.ptr);
1460
1461 if (fb->id > 0 && fb->card->fd >= 0) {
1462 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1463 if (r < 0)
1464 log_debug("grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
1465 fb->card->base.name, fb->id);
1466 }
1467
1468 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1469 struct drm_mode_destroy_dumb destroy_dumb = { };
1470
1471 if (fb->base.maps[i] != MAP_FAILED)
1472 munmap(fb->base.maps[i], fb->sizes[i]);
1473
1474 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1475 destroy_dumb.handle = fb->handles[i];
1476 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1477 if (r < 0)
1478 log_debug("grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
1479 fb->card->base.name, fb->handles[i]);
1480 }
1481 }
1482
1483 free(fb);
1484
1485 return NULL;
1486 }
1487
1488 /*
1489 * Pipes
1490 */
1491
1492 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1493 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1494 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1495 }
1496
1497 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1498 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1499 grdrm_card *card = crtc->object.card;
1500 char name[GRDRM_PIPE_NAME_MAX];
1501 grdrm_pipe *pipe;
1502 int r;
1503
1504 assert_return(crtc, -EINVAL);
1505 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1506
1507 pipe = new0(grdrm_pipe, 1);
1508 if (!pipe)
1509 return -ENOMEM;
1510
1511 basepipe = &pipe->base;
1512 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1513 pipe->crtc = crtc;
1514 pipe->base.width = mode->hdisplay;
1515 pipe->base.height = mode->vdisplay;
1516 pipe->base.vrefresh = mode->vrefresh ? : 25;
1517
1518 grdrm_pipe_name(name, crtc);
1519 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1520 if (r < 0)
1521 return r;
1522
1523 if (out)
1524 *out = pipe;
1525 basepipe = NULL;
1526 return 0;
1527 }
1528
1529 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1530 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1531 size_t i;
1532
1533 assert(pipe->crtc);
1534
1535 for (i = 0; i < pipe->base.max_fbs; ++i)
1536 if (pipe->base.fbs[i])
1537 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1538
1539 free(pipe);
1540 }
1541
1542 static grdev_fb *grdrm_pipe_target(grdev_pipe *basepipe) {
1543 grdrm_fb *fb;
1544 size_t i;
1545
1546 if (!basepipe->back) {
1547 for (i = 0; i < basepipe->max_fbs; ++i) {
1548 if (!basepipe->fbs[i])
1549 continue;
1550
1551 fb = fb_from_base(basepipe->fbs[i]);
1552 if (&fb->base == basepipe->front)
1553 continue;
1554 if (basepipe->flipping && fb->flipid)
1555 continue;
1556
1557 basepipe->back = &fb->base;
1558 break;
1559 }
1560 }
1561
1562 return basepipe->back;
1563 }
1564
1565 static void grdrm_pipe_enable(grdev_pipe *basepipe) {
1566 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1567
1568 pipe->crtc->applied = false;
1569 }
1570
1571 static void grdrm_pipe_disable(grdev_pipe *basepipe) {
1572 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1573
1574 pipe->crtc->applied = false;
1575 }
1576
1577 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1578 .free = grdrm_pipe_free,
1579 .target = grdrm_pipe_target,
1580 .enable = grdrm_pipe_enable,
1581 .disable = grdrm_pipe_disable,
1582 };
1583
1584 /*
1585 * Cards
1586 */
1587
1588 static void grdrm_name(char *out, dev_t devnum) {
1589 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1590 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1591 }
1592
1593 static void grdrm_card_print(grdrm_card *card) {
1594 grdrm_object *object;
1595 grdrm_crtc *crtc;
1596 grdrm_encoder *encoder;
1597 grdrm_connector *connector;
1598 grdrm_plane *plane;
1599 Iterator iter;
1600 uint32_t i;
1601 char *p, *buf;
1602
1603 log_debug("grdrm: %s: state dump", card->base.name);
1604
1605 log_debug(" crtcs:");
1606 HASHMAP_FOREACH(object, card->object_map, iter) {
1607 if (object->type != GRDRM_TYPE_CRTC)
1608 continue;
1609
1610 crtc = crtc_from_object(object);
1611 log_debug(" (id: %u index: %d)", object->id, object->index);
1612
1613 if (crtc->kern.mode_set)
1614 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1615 else
1616 log_debug(" mode: <none>");
1617 }
1618
1619 log_debug(" encoders:");
1620 HASHMAP_FOREACH(object, card->object_map, iter) {
1621 if (object->type != GRDRM_TYPE_ENCODER)
1622 continue;
1623
1624 encoder = encoder_from_object(object);
1625 log_debug(" (id: %u index: %d)", object->id, object->index);
1626
1627 if (encoder->kern.used_crtc)
1628 log_debug(" crtc: %u", encoder->kern.used_crtc);
1629 else
1630 log_debug(" crtc: <none>");
1631
1632 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1633 if (buf) {
1634 buf[0] = 0;
1635 p = buf;
1636
1637 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1638 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1639
1640 log_debug(" possible crtcs:%s", buf);
1641 free(buf);
1642 }
1643
1644 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1645 if (buf) {
1646 buf[0] = 0;
1647 p = buf;
1648
1649 for (i = 0; i < encoder->kern.n_clones; ++i)
1650 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1651
1652 log_debug(" possible clones:%s", buf);
1653 free(buf);
1654 }
1655 }
1656
1657 log_debug(" connectors:");
1658 HASHMAP_FOREACH(object, card->object_map, iter) {
1659 if (object->type != GRDRM_TYPE_CONNECTOR)
1660 continue;
1661
1662 connector = connector_from_object(object);
1663 log_debug(" (id: %u index: %d)", object->id, object->index);
1664 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1665 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1666 connector->kern.mm_width, connector->kern.mm_height);
1667
1668 if (connector->kern.used_encoder)
1669 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1670 else
1671 log_debug(" encoder: <none>");
1672
1673 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1674 if (buf) {
1675 buf[0] = 0;
1676 p = buf;
1677
1678 for (i = 0; i < connector->kern.n_encoders; ++i)
1679 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1680
1681 log_debug(" possible encoders:%s", buf);
1682 free(buf);
1683 }
1684
1685 for (i = 0; i < connector->kern.n_modes; ++i) {
1686 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1687 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1688 }
1689 }
1690
1691 log_debug(" planes:");
1692 HASHMAP_FOREACH(object, card->object_map, iter) {
1693 if (object->type != GRDRM_TYPE_PLANE)
1694 continue;
1695
1696 plane = plane_from_object(object);
1697 log_debug(" (id: %u index: %d)", object->id, object->index);
1698 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1699
1700 if (plane->kern.used_crtc)
1701 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1702 else
1703 log_debug(" crtc: <none>");
1704
1705 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1706 if (buf) {
1707 buf[0] = 0;
1708 p = buf;
1709
1710 for (i = 0; i < plane->kern.n_crtcs; ++i)
1711 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1712
1713 log_debug(" possible crtcs:%s", buf);
1714 free(buf);
1715 }
1716
1717 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1718 if (buf) {
1719 buf[0] = 0;
1720 p = buf;
1721
1722 for (i = 0; i < plane->kern.n_formats; ++i)
1723 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1724
1725 log_debug(" possible formats:%s", buf);
1726 free(buf);
1727 }
1728 }
1729 }
1730
1731 static int grdrm_card_resync(grdrm_card *card) {
1732 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1733 uint32_t allocated = 0;
1734 grdrm_object *object;
1735 Iterator iter;
1736 size_t tries;
1737 int r;
1738
1739 assert(card);
1740
1741 card->async_hotplug = false;
1742 allocated = 0;
1743
1744 /* mark existing objects for possible removal */
1745 HASHMAP_FOREACH(object, card->object_map, iter)
1746 object->present = false;
1747
1748 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1749 struct drm_mode_get_plane_res pres;
1750 struct drm_mode_card_res res;
1751 uint32_t i, max;
1752
1753 if (allocated < card->max_ids) {
1754 free(crtc_ids);
1755 free(encoder_ids);
1756 free(connector_ids);
1757 free(plane_ids);
1758 crtc_ids = new0(uint32_t, card->max_ids);
1759 encoder_ids = new0(uint32_t, card->max_ids);
1760 connector_ids = new0(uint32_t, card->max_ids);
1761 plane_ids = new0(uint32_t, card->max_ids);
1762
1763 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1764 return -ENOMEM;
1765
1766 allocated = card->max_ids;
1767 }
1768
1769 zero(res);
1770 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1771 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1772 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1773 res.count_crtcs = allocated;
1774 res.count_encoders = allocated;
1775 res.count_connectors = allocated;
1776
1777 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1778 if (r < 0) {
1779 r = -errno;
1780 log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
1781 return r;
1782 }
1783
1784 zero(pres);
1785 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1786 pres.count_planes = allocated;
1787
1788 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1789 if (r < 0) {
1790 r = -errno;
1791 log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
1792 return r;
1793 }
1794
1795 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1796 MAX(res.count_connectors, pres.count_planes));
1797 if (max > allocated) {
1798 uint32_t n;
1799
1800 n = ALIGN_POWER2(max);
1801 if (!n || n > UINT16_MAX) {
1802 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
1803 return -ERANGE;
1804 }
1805
1806 /* retry with resized buffers */
1807 card->max_ids = n;
1808 continue;
1809 }
1810
1811 /* mark available objects as present */
1812
1813 for (i = 0; i < res.count_crtcs; ++i) {
1814 object = grdrm_find_object(card, crtc_ids[i]);
1815 if (object && object->type == GRDRM_TYPE_CRTC) {
1816 object->present = true;
1817 object->index = i;
1818 crtc_ids[i] = 0;
1819 }
1820 }
1821
1822 for (i = 0; i < res.count_encoders; ++i) {
1823 object = grdrm_find_object(card, encoder_ids[i]);
1824 if (object && object->type == GRDRM_TYPE_ENCODER) {
1825 object->present = true;
1826 object->index = i;
1827 encoder_ids[i] = 0;
1828 }
1829 }
1830
1831 for (i = 0; i < res.count_connectors; ++i) {
1832 object = grdrm_find_object(card, connector_ids[i]);
1833 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1834 object->present = true;
1835 object->index = i;
1836 connector_ids[i] = 0;
1837 }
1838 }
1839
1840 for (i = 0; i < pres.count_planes; ++i) {
1841 object = grdrm_find_object(card, plane_ids[i]);
1842 if (object && object->type == GRDRM_TYPE_PLANE) {
1843 object->present = true;
1844 object->index = i;
1845 plane_ids[i] = 0;
1846 }
1847 }
1848
1849 /* drop removed objects */
1850
1851 HASHMAP_FOREACH(object, card->object_map, iter)
1852 if (!object->present)
1853 grdrm_object_free(object);
1854
1855 /* add new objects */
1856
1857 card->n_crtcs = res.count_crtcs;
1858 for (i = 0; i < res.count_crtcs; ++i) {
1859 if (crtc_ids[i] < 1)
1860 continue;
1861
1862 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1863 if (r < 0)
1864 return r;
1865 }
1866
1867 card->n_encoders = res.count_encoders;
1868 for (i = 0; i < res.count_encoders; ++i) {
1869 if (encoder_ids[i] < 1)
1870 continue;
1871
1872 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1873 if (r < 0)
1874 return r;
1875 }
1876
1877 card->n_connectors = res.count_connectors;
1878 for (i = 0; i < res.count_connectors; ++i) {
1879 if (connector_ids[i] < 1)
1880 continue;
1881
1882 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1883 if (r < 0)
1884 return r;
1885 }
1886
1887 card->n_planes = pres.count_planes;
1888 for (i = 0; i < pres.count_planes; ++i) {
1889 if (plane_ids[i] < 1)
1890 continue;
1891
1892 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1893 if (r < 0)
1894 return r;
1895 }
1896
1897 /* re-sync objects after object_map is synced */
1898
1899 HASHMAP_FOREACH(object, card->object_map, iter) {
1900 switch (object->type) {
1901 case GRDRM_TYPE_CRTC:
1902 r = grdrm_crtc_resync(crtc_from_object(object));
1903 break;
1904 case GRDRM_TYPE_ENCODER:
1905 r = grdrm_encoder_resync(encoder_from_object(object));
1906 break;
1907 case GRDRM_TYPE_CONNECTOR:
1908 r = grdrm_connector_resync(connector_from_object(object));
1909 break;
1910 case GRDRM_TYPE_PLANE:
1911 r = grdrm_plane_resync(plane_from_object(object));
1912 break;
1913 default:
1914 assert_not_reached("grdrm: invalid object type");
1915 r = 0;
1916 }
1917
1918 if (r < 0)
1919 return r;
1920
1921 if (card->async_hotplug)
1922 break;
1923 }
1924
1925 /* if modeset objects change during sync, start over */
1926 if (card->async_hotplug) {
1927 card->async_hotplug = false;
1928 continue;
1929 }
1930
1931 /* cache crtc/connector relationship */
1932 HASHMAP_FOREACH(object, card->object_map, iter) {
1933 grdrm_connector *connector;
1934 grdrm_encoder *encoder;
1935 grdrm_crtc *crtc;
1936
1937 if (object->type != GRDRM_TYPE_CONNECTOR)
1938 continue;
1939
1940 connector = connector_from_object(object);
1941 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1942 continue;
1943
1944 object = grdrm_find_object(card, connector->kern.used_encoder);
1945 if (!object || object->type != GRDRM_TYPE_ENCODER)
1946 continue;
1947
1948 encoder = encoder_from_object(object);
1949 if (encoder->kern.used_crtc < 1)
1950 continue;
1951
1952 object = grdrm_find_object(card, encoder->kern.used_crtc);
1953 if (!object || object->type != GRDRM_TYPE_CRTC)
1954 continue;
1955
1956 crtc = crtc_from_object(object);
1957 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1958 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1959 }
1960
1961 /* cache old crtc settings for later restore */
1962 HASHMAP_FOREACH(object, card->object_map, iter) {
1963 grdrm_crtc *crtc;
1964
1965 if (object->type != GRDRM_TYPE_CRTC)
1966 continue;
1967
1968 crtc = crtc_from_object(object);
1969
1970 /* Save data if it is the first time we refresh the CRTC. This data can
1971 * be used optionally to restore any previous configuration. For
1972 * instance, it allows us to restore VT configurations after we close
1973 * our session again. */
1974 if (!crtc->old.set) {
1975 crtc->old.fb = crtc->kern.used_fb;
1976 crtc->old.fb_x = crtc->kern.fb_offset_x;
1977 crtc->old.fb_y = crtc->kern.fb_offset_y;
1978 crtc->old.gamma = crtc->kern.gamma_size;
1979 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1980 if (crtc->old.n_connectors)
1981 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1982 crtc->old.mode_set = crtc->kern.mode_set;
1983 crtc->old.mode = crtc->kern.mode;
1984 crtc->old.set = true;
1985 }
1986 }
1987
1988 /* everything synced */
1989 break;
1990 }
1991
1992 if (tries >= GRDRM_MAX_TRIES) {
1993 /*
1994 * Ugh! We were unable to sync the DRM card state due to heavy
1995 * hotplugging. This should never happen, so print a debug
1996 * message and bail out. The next uevent will trigger
1997 * this again.
1998 */
1999
2000 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
2001 return -EFAULT;
2002 }
2003
2004 return 0;
2005 }
2006
2007 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
2008 grdrm_card *card = crtc->object.card;
2009 grdrm_encoder *encoder;
2010 grdrm_object *object;
2011 uint32_t i, j;
2012
2013 if (crtc->object.assigned || connector->object.assigned)
2014 return false;
2015 if (connector->kern.connection != 1)
2016 return false;
2017
2018 for (i = 0; i < connector->kern.n_encoders; ++i) {
2019 object = grdrm_find_object(card, connector->kern.encoders[i]);
2020 if (!object || object->type != GRDRM_TYPE_ENCODER)
2021 continue;
2022
2023 encoder = encoder_from_object(object);
2024 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
2025 if (encoder->kern.crtcs[j] == crtc->object.id) {
2026 grdrm_crtc_assign(crtc, connector);
2027 return true;
2028 }
2029 }
2030 }
2031
2032 return false;
2033 }
2034
2035 static void grdrm_card_configure(grdrm_card *card) {
2036 /*
2037 * Modeset Configuration
2038 * This is where we update our modeset configuration and assign
2039 * connectors to CRTCs. This means, each connector that we want to
2040 * enable needs a CRTC, disabled (or unavailable) connectors are left
2041 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
2042 * are disabled.
2043 * Sounds trivial, but there're several caveats:
2044 *
2045 * * Multiple connectors can be driven by the same CRTC. This is
2046 * known as 'hardware clone mode'. Advantage over software clone
2047 * mode is that only a single CRTC is needed to drive multiple
2048 * displays. However, few hardware supports this and it's a huge
2049 * headache to configure on dynamic demands. Therefore, we only
2050 * support it if configured statically beforehand.
2051 *
2052 * * CRTCs are not created equal. Some might be much more poweful
2053 * than others, including more advanced plane support. So far, our
2054 * CRTC selection is random. You need to supply static
2055 * configuration if you want special setups. So far, there is no
2056 * proper way to do advanced CRTC selection on dynamic demands. It
2057 * is not really clear which demands require what CRTC, so, like
2058 * everyone else, we do random CRTC selection unless explicitly
2059 * states otherwise.
2060 *
2061 * * Each Connector has a list of possible encoders that can drive
2062 * it, and each encoder has a list of possible CRTCs. If this graph
2063 * is a tree, assignment is trivial. However, if not, we cannot
2064 * reliably decide on configurations beforehand. The encoder is
2065 * always selected by the kernel, so we have to actually set a mode
2066 * to know which encoder is used. There is no way to ask the kernel
2067 * whether a given configuration is possible. This will change with
2068 * atomic-modesetting, but until then, we keep our configurations
2069 * simple and assume they work all just fine. If one fails
2070 * unexpectedly, we print a warning and disable it.
2071 *
2072 * Configuring a card consists of several steps:
2073 *
2074 * 1) First of all, we apply any user-configuration. If a user wants
2075 * a fixed configuration, we apply it and preserve it.
2076 * So far, we don't support user configuration files, so this step
2077 * is skipped.
2078 *
2079 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
2080 * might only support limited configurations or require special
2081 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2082 * present.
2083 * So far, we don't support this as there is no known quirk, so
2084 * this step is skipped.
2085 *
2086 * 3) As deep modesets are expensive, we try to avoid them if
2087 * possible. Therefore, we read the current configuration from the
2088 * kernel and try to preserve it, if compatible with our demands.
2089 * If not, we break it and reassign it in a following step.
2090 *
2091 * 4) The main step involves configuring all remaining objects. By
2092 * default, all available connectors are enabled, except for those
2093 * disabled by user-configuration. We lookup a suitable CRTC for
2094 * each connector and assign them. As there might be more
2095 * connectors than CRTCs, we apply some ordering so users can
2096 * select which connectors are more important right now.
2097 * So far, we only apply the default ordering, more might be added
2098 * in the future.
2099 */
2100
2101 grdrm_object *object;
2102 grdrm_crtc *crtc;
2103 Iterator i, j;
2104
2105 /* clear assignments */
2106 HASHMAP_FOREACH(object, card->object_map, i)
2107 object->assigned = false;
2108
2109 /* preserve existing configurations */
2110 HASHMAP_FOREACH(object, card->object_map, i) {
2111 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2112 continue;
2113
2114 crtc = crtc_from_object(object);
2115
2116 if (crtc->applied) {
2117 /* If our mode is set, preserve it. If no connector is
2118 * set, modeset either failed or the pipe is unused. In
2119 * both cases, leave it alone. It might be tried again
2120 * below in case there're remaining connectors.
2121 * Otherwise, try restoring the assignments. If they
2122 * are no longer valid, leave the pipe untouched. */
2123
2124 if (crtc->set.n_connectors < 1)
2125 continue;
2126
2127 assert(crtc->set.n_connectors == 1);
2128
2129 object = grdrm_find_object(card, crtc->set.connectors[0]);
2130 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2131 continue;
2132
2133 card_configure_crtc(crtc, connector_from_object(object));
2134 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2135 /* If our mode is not set on the pipe, we know the kern
2136 * information is valid. Try keeping it. If it's not
2137 * possible, leave the pipe untouched for later
2138 * assignements. */
2139
2140 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2141 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2142 continue;
2143
2144 card_configure_crtc(crtc, connector_from_object(object));
2145 }
2146 }
2147
2148 /* assign remaining objects */
2149 HASHMAP_FOREACH(object, card->object_map, i) {
2150 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2151 continue;
2152
2153 crtc = crtc_from_object(object);
2154
2155 HASHMAP_FOREACH(object, card->object_map, j) {
2156 if (object->type != GRDRM_TYPE_CONNECTOR)
2157 continue;
2158
2159 if (card_configure_crtc(crtc, connector_from_object(object)))
2160 break;
2161 }
2162
2163 if (!crtc->object.assigned)
2164 grdrm_crtc_assign(crtc, NULL);
2165 }
2166
2167 /* expose configuration */
2168 HASHMAP_FOREACH(object, card->object_map, i) {
2169 if (object->type != GRDRM_TYPE_CRTC)
2170 continue;
2171
2172 grdrm_crtc_expose(crtc_from_object(object));
2173 }
2174 }
2175
2176 static void grdrm_card_hotplug(grdrm_card *card) {
2177 int r;
2178
2179 assert(card);
2180
2181 if (!card->running)
2182 return;
2183
2184 log_debug("grdrm: %s/%s: reconfigure card", card->base.session->name, card->base.name);
2185
2186 card->ready = false;
2187 r = grdrm_card_resync(card);
2188 if (r < 0) {
2189 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2190 card->base.session->name, card->base.name, strerror(-r));
2191 return;
2192 }
2193
2194 grdev_session_pin(card->base.session);
2195
2196 /* debug statement to print card information */
2197 if (0)
2198 grdrm_card_print(card);
2199
2200 grdrm_card_configure(card);
2201 card->ready = true;
2202 card->hotplug = false;
2203
2204 grdev_session_unpin(card->base.session);
2205 }
2206
2207 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2208 grdrm_card *card = userdata;
2209 struct drm_event_vblank *vblank;
2210 struct drm_event *event;
2211 uint32_t id, counter;
2212 grdrm_object *object;
2213 char buf[4096];
2214 size_t len;
2215 ssize_t l;
2216
2217 if (revents & (EPOLLHUP | EPOLLERR)) {
2218 /* Immediately close device on HUP; no need to flush pending
2219 * data.. there're no events we care about here. */
2220 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2221 grdrm_card_close(card);
2222 return 0;
2223 }
2224
2225 if (revents & (EPOLLIN)) {
2226 l = read(card->fd, buf, sizeof(buf));
2227 if (l < 0) {
2228 if (errno == EAGAIN || errno == EINTR)
2229 return 0;
2230
2231 log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2232 grdrm_card_close(card);
2233 return 0;
2234 }
2235
2236 for (len = l; len > 0; len -= event->length) {
2237 event = (void*)buf;
2238
2239 if (len < sizeof(*event) || len < event->length) {
2240 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2241 break;
2242 }
2243
2244 switch (event->type) {
2245 case DRM_EVENT_FLIP_COMPLETE:
2246 vblank = (void*)event;
2247 if (event->length < sizeof(*vblank)) {
2248 log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2249 break;
2250 }
2251
2252 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2253 object = grdrm_find_object(card, id);
2254 if (!object || object->type != GRDRM_TYPE_CRTC)
2255 break;
2256
2257 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2258 break;
2259 }
2260 }
2261 }
2262
2263 return 0;
2264 }
2265
2266 static int grdrm_card_add(grdrm_card *card, const char *name) {
2267 assert(card);
2268 assert(card->fd < 0);
2269
2270 card->object_map = hashmap_new(&trivial_hash_ops);
2271 if (!card->object_map)
2272 return -ENOMEM;
2273
2274 return grdev_card_add(&card->base, name);
2275 }
2276
2277 static void grdrm_card_destroy(grdrm_card *card) {
2278 assert(card);
2279 assert(!card->running);
2280 assert(card->fd < 0);
2281 assert(hashmap_size(card->object_map) == 0);
2282
2283 hashmap_free(card->object_map);
2284 }
2285
2286 static void grdrm_card_commit(grdev_card *basecard) {
2287 grdrm_card *card = grdrm_card_from_base(basecard);
2288 grdrm_object *object;
2289 Iterator iter;
2290
2291 HASHMAP_FOREACH(object, card->object_map, iter) {
2292 if (!card->ready)
2293 break;
2294
2295 if (object->type != GRDRM_TYPE_CRTC)
2296 continue;
2297
2298 grdrm_crtc_commit(crtc_from_object(object));
2299 }
2300 }
2301
2302 static void grdrm_card_restore(grdev_card *basecard) {
2303 grdrm_card *card = grdrm_card_from_base(basecard);
2304 grdrm_object *object;
2305 Iterator iter;
2306
2307 HASHMAP_FOREACH(object, card->object_map, iter) {
2308 if (!card->ready)
2309 break;
2310
2311 if (object->type != GRDRM_TYPE_CRTC)
2312 continue;
2313
2314 grdrm_crtc_restore(crtc_from_object(object));
2315 }
2316 }
2317
2318 static void grdrm_card_enable(grdrm_card *card) {
2319 assert(card);
2320
2321 if (card->fd < 0 || card->running)
2322 return;
2323
2324 /* ignore cards without DUMB_BUFFER capability */
2325 if (!card->cap_dumb)
2326 return;
2327
2328 assert(card->fd_src);
2329
2330 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2331
2332 card->running = true;
2333 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2334 grdrm_card_hotplug(card);
2335 }
2336
2337 static void grdrm_card_disable(grdrm_card *card) {
2338 grdrm_object *object;
2339 Iterator iter;
2340
2341 assert(card);
2342
2343 if (card->fd < 0 || !card->running)
2344 return;
2345
2346 assert(card->fd_src);
2347
2348 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2349
2350 card->running = false;
2351 card->ready = false;
2352 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2353
2354 /* stop all pipes */
2355 HASHMAP_FOREACH(object, card->object_map, iter) {
2356 grdrm_crtc *crtc;
2357
2358 if (object->type != GRDRM_TYPE_CRTC)
2359 continue;
2360
2361 crtc = crtc_from_object(object);
2362 crtc->applied = false;
2363 if (crtc->pipe)
2364 grdev_pipe_ready(&crtc->pipe->base, false);
2365 }
2366 }
2367
2368 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2369 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2370 _cleanup_close_ int fd = dev_fd;
2371 struct drm_get_cap cap;
2372 int r, flags;
2373
2374 assert(card);
2375 assert(dev_fd >= 0);
2376 assert(card->fd != dev_fd);
2377
2378 pin = grdev_session_pin(card->base.session);
2379 grdrm_card_close(card);
2380
2381 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2382
2383 r = fd_nonblock(fd, true);
2384 if (r < 0)
2385 return r;
2386
2387 r = fd_cloexec(fd, true);
2388 if (r < 0)
2389 return r;
2390
2391 flags = fcntl(fd, F_GETFL, 0);
2392 if (flags < 0)
2393 return -errno;
2394 if ((flags & O_ACCMODE) != O_RDWR)
2395 return -EACCES;
2396
2397 r = sd_event_add_io(card->base.session->context->event,
2398 &card->fd_src,
2399 fd,
2400 EPOLLHUP | EPOLLERR | EPOLLIN,
2401 grdrm_card_io_fn,
2402 card);
2403 if (r < 0)
2404 return r;
2405
2406 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2407
2408 card->hotplug = true;
2409 card->fd = fd;
2410 fd = -1;
2411
2412 /* cache DUMB_BUFFER capability */
2413 cap.capability = DRM_CAP_DUMB_BUFFER;
2414 cap.value = 0;
2415 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2416 card->cap_dumb = r >= 0 && cap.value;
2417 if (r < 0)
2418 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2419 card->base.session->name, card->base.name, strerror(-r));
2420 else if (!card->cap_dumb)
2421 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2422 card->base.session->name, card->base.name);
2423
2424 /* cache TIMESTAMP_MONOTONIC capability */
2425 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2426 cap.value = 0;
2427 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2428 card->cap_monotonic = r >= 0 && cap.value;
2429 if (r < 0)
2430 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2431 card->base.session->name, card->base.name, strerror(-r));
2432 else if (!card->cap_monotonic)
2433 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2434 card->base.session->name, card->base.name);
2435
2436 return 0;
2437 }
2438
2439 static void grdrm_card_close(grdrm_card *card) {
2440 grdrm_object *object;
2441
2442 if (card->fd < 0)
2443 return;
2444
2445 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2446
2447 grdrm_card_disable(card);
2448
2449 card->fd_src = sd_event_source_unref(card->fd_src);
2450 card->fd = safe_close(card->fd);
2451
2452 grdev_session_pin(card->base.session);
2453 while ((object = hashmap_first(card->object_map)))
2454 grdrm_object_free(object);
2455 grdev_session_unpin(card->base.session);
2456 }
2457
2458 static bool grdrm_card_async(grdrm_card *card, int r) {
2459 switch (r) {
2460 case -EACCES:
2461 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2462 * (or we did something terribly wrong). Immediately disable
2463 * the card, so we stop all pipes and wait to be activated
2464 * again. */
2465 grdrm_card_disable(card);
2466 break;
2467 case -ENOENT:
2468 /* DRM objects can be hotplugged at any time. If an object is
2469 * removed that we use, we remember that state so a following
2470 * call can test for this.
2471 * Note that we also get a uevent as followup, this will resync
2472 * the whole device. */
2473 card->async_hotplug = true;
2474 break;
2475 }
2476
2477 return !card->ready;
2478 }
2479
2480 /*
2481 * Unmanaged Cards
2482 * The unmanaged DRM card opens the device node for a given DRM device
2483 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2484 * the device only if we really require it and releases it as soon as we're
2485 * disabled or closed.
2486 * The unmanaged element can be used in all situations where you have direct
2487 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2488 * outside of user sessions and in emergency situations where logind is not
2489 * available.
2490 */
2491
2492 static void unmanaged_card_enable(grdev_card *basecard) {
2493 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2494 int r, fd;
2495
2496 if (cu->card.fd < 0) {
2497 /* try open on activation if it failed during allocation */
2498 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2499 if (fd < 0) {
2500 /* not fatal; simply ignore the device */
2501 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2502 basecard->session->name, basecard->name, cu->devnode);
2503 return;
2504 }
2505
2506 /* we might already be DRM-Master by open(); that's fine */
2507
2508 r = grdrm_card_open(&cu->card, fd);
2509 if (r < 0) {
2510 log_debug("grdrm: %s/%s: cannot open: %s",
2511 basecard->session->name, basecard->name, strerror(-r));
2512 return;
2513 }
2514 }
2515
2516 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2517 if (r < 0) {
2518 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2519 basecard->session->name, basecard->name);
2520 return;
2521 }
2522
2523 grdrm_card_enable(&cu->card);
2524 }
2525
2526 static void unmanaged_card_disable(grdev_card *basecard) {
2527 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2528
2529 grdrm_card_disable(&cu->card);
2530 }
2531
2532 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2533 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2534 char name[GRDRM_CARD_NAME_MAX];
2535 unmanaged_card *cu;
2536 const char *devnode;
2537 dev_t devnum;
2538 int r, fd;
2539
2540 assert_return(session, -EINVAL);
2541 assert_return(ud, -EINVAL);
2542
2543 devnode = udev_device_get_devnode(ud);
2544 devnum = udev_device_get_devnum(ud);
2545 if (!devnode || devnum == 0)
2546 return -ENODEV;
2547
2548 grdrm_name(name, devnum);
2549
2550 cu = new0(unmanaged_card, 1);
2551 if (!cu)
2552 return -ENOMEM;
2553
2554 basecard = &cu->card.base;
2555 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2556
2557 cu->devnode = strdup(devnode);
2558 if (!cu->devnode)
2559 return -ENOMEM;
2560
2561 r = grdrm_card_add(&cu->card, name);
2562 if (r < 0)
2563 return r;
2564
2565 /* try to open but ignore errors */
2566 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2567 if (fd < 0) {
2568 /* not fatal; allow uaccess based control on activation */
2569 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2570 basecard->session->name, basecard->name, cu->devnode);
2571 } else {
2572 /* We might get DRM-Master implicitly on open(); drop it immediately
2573 * so we acquire it only once we're actually enabled. We don't
2574 * really care whether this call fails or not, but lets log any
2575 * weird errors, anyway. */
2576 r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2577 if (r < 0 && errno != EACCES && errno != EINVAL)
2578 log_debug("grdrm: %s/%s: cannot drop DRM-Master: %m",
2579 basecard->session->name, basecard->name);
2580
2581 r = grdrm_card_open(&cu->card, fd);
2582 if (r < 0)
2583 log_debug("grdrm: %s/%s: cannot open: %s",
2584 basecard->session->name, basecard->name, strerror(-r));
2585 }
2586
2587 if (out)
2588 *out = basecard;
2589 basecard = NULL;
2590 return 0;
2591 }
2592
2593 static void unmanaged_card_free(grdev_card *basecard) {
2594 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2595
2596 assert(!basecard->enabled);
2597
2598 grdrm_card_close(&cu->card);
2599 grdrm_card_destroy(&cu->card);
2600 free(cu->devnode);
2601 free(cu);
2602 }
2603
2604 static const grdev_card_vtable unmanaged_card_vtable = {
2605 .free = unmanaged_card_free,
2606 .enable = unmanaged_card_enable,
2607 .disable = unmanaged_card_disable,
2608 .commit = grdrm_card_commit,
2609 .restore = grdrm_card_restore,
2610 };
2611
2612 /*
2613 * Managed Cards
2614 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2615 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2616 * logind passes us a file-descriptor whenever our session is activated. Thus,
2617 * we don't need access to the device node directly.
2618 * Furthermore, whenever the session is put asleep, logind revokes the
2619 * file-descriptor so we loose access to the device.
2620 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2621 * you run inside a user session with exclusive device access.
2622 */
2623
2624 static void managed_card_enable(grdev_card *card) {
2625 managed_card *cm = managed_card_from_base(card);
2626
2627 /* If the device is manually re-enabled, we try to resume our card
2628 * management. Note that we have no control over DRM-Master and the fd,
2629 * so we have to take over the state from the last logind event. */
2630
2631 if (cm->master)
2632 grdrm_card_enable(&cm->card);
2633 }
2634
2635 static void managed_card_disable(grdev_card *card) {
2636 managed_card *cm = managed_card_from_base(card);
2637
2638 /* If the device is manually disabled, we keep the FD but put our card
2639 * management asleep. This way, we can wake up at any time, but don't
2640 * touch the device while asleep. */
2641
2642 grdrm_card_disable(&cm->card);
2643 }
2644
2645 static int managed_card_pause_device_fn(sd_bus *bus,
2646 sd_bus_message *signal,
2647 void *userdata,
2648 sd_bus_error *ret_error) {
2649 managed_card *cm = userdata;
2650 grdev_session *session = cm->card.base.session;
2651 uint32_t major, minor;
2652 const char *mode;
2653 int r;
2654
2655 /*
2656 * We get PauseDevice() signals from logind whenever a device we
2657 * requested was, or is about to be, paused. Arguments are major/minor
2658 * number of the device and the mode of the operation.
2659 * In case the event is not about our device, we ignore it. Otherwise,
2660 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2661 * already handled an EACCES error from a modeset ioctl, in which case
2662 * we already disabled the device.
2663 *
2664 * @mode can be one of the following:
2665 * "pause": The device is about to be paused. We must react
2666 * immediately and respond with PauseDeviceComplete(). Once
2667 * we replied, logind will pause the device. Note that
2668 * logind might apply any kind of timeout and force pause
2669 * the device if we don't respond in a timely manner. In
2670 * this case, we will receive a second PauseDevice event
2671 * with @mode set to "force" (or similar).
2672 * "force": The device was disabled forecfully by logind. DRM-Master
2673 * was already dropped. This is just an asynchronous
2674 * notification so we can put the device asleep (in case
2675 * we didn't already notice the dropped DRM-Master).
2676 * "gone": This is like "force" but is sent if the device was
2677 * paused due to a device-removal event.
2678 *
2679 * We always handle PauseDevice signals as "force" as we properly
2680 * support asynchronously dropping DRM-Master, anyway. But in case
2681 * logind sent mode "pause", we also call PauseDeviceComplete() to
2682 * immediately acknowledge the request.
2683 */
2684
2685 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2686 if (r < 0) {
2687 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2688 session->name, cm->card.base.name);
2689 return 0;
2690 }
2691
2692 /* not our device? */
2693 if (makedev(major, minor) != cm->devnum)
2694 return 0;
2695
2696 cm->master = false;
2697 grdrm_card_disable(&cm->card);
2698
2699 if (streq(mode, "pause")) {
2700 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2701
2702 /*
2703 * Sending PauseDeviceComplete() is racy if logind triggers the
2704 * timeout. That is, if we take too long and logind pauses the
2705 * device by sending a forced PauseDevice, our
2706 * PauseDeviceComplete call will be stray. That's fine, though.
2707 * logind ignores such stray calls. Only if logind also sent a
2708 * further PauseDevice() signal, it might match our call
2709 * incorrectly to the newer PauseDevice(). That's fine, too, as
2710 * we handle that event asynchronously, anyway. Therefore,
2711 * whatever happens, we're fine. Yay!
2712 */
2713
2714 r = sd_bus_message_new_method_call(session->context->sysbus,
2715 &m,
2716 "org.freedesktop.login1",
2717 session->path,
2718 "org.freedesktop.login1.Session",
2719 "PauseDeviceComplete");
2720 if (r >= 0) {
2721 r = sd_bus_message_append(m, "uu", major, minor);
2722 if (r >= 0)
2723 r = sd_bus_send(session->context->sysbus, m, NULL);
2724 }
2725
2726 if (r < 0)
2727 log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2728 session->name, cm->card.base.name, strerror(-r));
2729 }
2730
2731 return 0;
2732 }
2733
2734 static int managed_card_resume_device_fn(sd_bus *bus,
2735 sd_bus_message *signal,
2736 void *userdata,
2737 sd_bus_error *ret_error) {
2738 managed_card *cm = userdata;
2739 grdev_session *session = cm->card.base.session;
2740 uint32_t major, minor;
2741 int r, fd;
2742
2743 /*
2744 * We get ResumeDevice signals whenever logind resumed a previously
2745 * paused device. The arguments contain the major/minor number of the
2746 * related device and a new file-descriptor for the freshly opened
2747 * device-node.
2748 * If the signal is not about our device, we simply ignore it.
2749 * Otherwise, we immediately resume the device. Note that we drop the
2750 * new file-descriptor as we already have one from TakeDevice(). logind
2751 * preserves the file-context across pause/resume for DRM but only
2752 * drops/acquires DRM-Master accordingly. This way, our context (like
2753 * DRM-FBs and BOs) is preserved.
2754 */
2755
2756 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2757 if (r < 0) {
2758 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2759 session->name, cm->card.base.name);
2760 return 0;
2761 }
2762
2763 /* not our device? */
2764 if (makedev(major, minor) != cm->devnum)
2765 return 0;
2766
2767 if (cm->card.fd < 0) {
2768 /* This shouldn't happen. We should already own an FD from
2769 * TakeDevice(). However, lets be safe and use this FD in case
2770 * we really don't have one. There is no harm in doing this
2771 * and our code works fine this way. */
2772 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2773 if (fd < 0) {
2774 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2775 session->name, cm->card.base.name);
2776 return 0;
2777 }
2778
2779 r = grdrm_card_open(&cm->card, fd);
2780 if (r < 0) {
2781 log_debug("grdrm: %s/%s: cannot open: %s",
2782 session->name, cm->card.base.name, strerror(-r));
2783 return 0;
2784 }
2785 }
2786
2787 cm->master = true;
2788 if (cm->card.base.enabled)
2789 grdrm_card_enable(&cm->card);
2790
2791 return 0;
2792 }
2793
2794 static int managed_card_setup_bus(managed_card *cm) {
2795 grdev_session *session = cm->card.base.session;
2796 _cleanup_free_ char *match = NULL;
2797 int r;
2798
2799 match = strjoin("type='signal',"
2800 "sender='org.freedesktop.login1',"
2801 "interface='org.freedesktop.login1.Session',"
2802 "member='PauseDevice',"
2803 "path='", session->path, "'",
2804 NULL);
2805 if (!match)
2806 return -ENOMEM;
2807
2808 r = sd_bus_add_match(session->context->sysbus,
2809 &cm->slot_pause_device,
2810 match,
2811 managed_card_pause_device_fn,
2812 cm);
2813 if (r < 0)
2814 return r;
2815
2816 free(match);
2817 match = strjoin("type='signal',"
2818 "sender='org.freedesktop.login1',"
2819 "interface='org.freedesktop.login1.Session',"
2820 "member='ResumeDevice',"
2821 "path='", session->path, "'",
2822 NULL);
2823 if (!match)
2824 return -ENOMEM;
2825
2826 r = sd_bus_add_match(session->context->sysbus,
2827 &cm->slot_resume_device,
2828 match,
2829 managed_card_resume_device_fn,
2830 cm);
2831 if (r < 0)
2832 return r;
2833
2834 return 0;
2835 }
2836
2837 static int managed_card_take_device_fn(sd_bus *bus,
2838 sd_bus_message *reply,
2839 void *userdata,
2840 sd_bus_error *ret_error) {
2841 managed_card *cm = userdata;
2842 grdev_session *session = cm->card.base.session;
2843 int r, paused, fd;
2844
2845 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2846
2847 if (sd_bus_message_is_method_error(reply, NULL)) {
2848 const sd_bus_error *error = sd_bus_message_get_error(reply);
2849
2850 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2851 session->name, cm->card.base.name, error->name, error->message);
2852 return 0;
2853 }
2854
2855 cm->acquired = true;
2856
2857 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2858 if (r < 0) {
2859 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2860 session->name, cm->card.base.name);
2861 return 0;
2862 }
2863
2864 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2865 if (fd < 0) {
2866 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2867 session->name, cm->card.base.name);
2868 return 0;
2869 }
2870
2871 r = grdrm_card_open(&cm->card, fd);
2872 if (r < 0) {
2873 log_debug("grdrm: %s/%s: cannot open: %s",
2874 session->name, cm->card.base.name, strerror(-r));
2875 return 0;
2876 }
2877
2878 if (!paused && cm->card.base.enabled)
2879 grdrm_card_enable(&cm->card);
2880
2881 return 0;
2882 }
2883
2884 static void managed_card_take_device(managed_card *cm) {
2885 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2886 grdev_session *session = cm->card.base.session;
2887 int r;
2888
2889 r = sd_bus_message_new_method_call(session->context->sysbus,
2890 &m,
2891 "org.freedesktop.login1",
2892 session->path,
2893 "org.freedesktop.login1.Session",
2894 "TakeDevice");
2895 if (r < 0)
2896 goto error;
2897
2898 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2899 if (r < 0)
2900 goto error;
2901
2902 r = sd_bus_call_async(session->context->sysbus,
2903 &cm->slot_take_device,
2904 m,
2905 managed_card_take_device_fn,
2906 cm,
2907 0);
2908 if (r < 0)
2909 goto error;
2910
2911 cm->requested = true;
2912 return;
2913
2914 error:
2915 log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2916 session->name, cm->card.base.name, strerror(-r));
2917 }
2918
2919 static void managed_card_release_device(managed_card *cm) {
2920 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2921 grdev_session *session = cm->card.base.session;
2922 int r;
2923
2924 /*
2925 * If TakeDevice() is pending or was successful, make sure to
2926 * release the device again. We don't care for return-values,
2927 * so send it without waiting or callbacks.
2928 * If a failed TakeDevice() is pending, but someone else took
2929 * the device on the same bus-connection, we might incorrectly
2930 * release their device. This is an unlikely race, though.
2931 * Furthermore, you really shouldn't have two users of the
2932 * controller-API on the same session, on the same devices, *AND* on
2933 * the same bus-connection. So we don't care for that race..
2934 */
2935
2936 grdrm_card_close(&cm->card);
2937 cm->requested = false;
2938
2939 if (!cm->acquired && !cm->slot_take_device)
2940 return;
2941
2942 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2943 cm->acquired = false;
2944
2945 r = sd_bus_message_new_method_call(session->context->sysbus,
2946 &m,
2947 "org.freedesktop.login1",
2948 session->path,
2949 "org.freedesktop.login1.Session",
2950 "ReleaseDevice");
2951 if (r >= 0) {
2952 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2953 if (r >= 0)
2954 r = sd_bus_send(session->context->sysbus, m, NULL);
2955 }
2956
2957 if (r < 0 && r != -ENOTCONN)
2958 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2959 session->name, cm->card.base.name, strerror(-r));
2960 }
2961
2962 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2963 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2964 char name[GRDRM_CARD_NAME_MAX];
2965 managed_card *cm;
2966 dev_t devnum;
2967 int r;
2968
2969 assert_return(session, -EINVAL);
2970 assert_return(session->managed, -EINVAL);
2971 assert_return(session->context->sysbus, -EINVAL);
2972 assert_return(ud, -EINVAL);
2973
2974 devnum = udev_device_get_devnum(ud);
2975 if (devnum == 0)
2976 return -ENODEV;
2977
2978 grdrm_name(name, devnum);
2979
2980 cm = new0(managed_card, 1);
2981 if (!cm)
2982 return -ENOMEM;
2983
2984 basecard = &cm->card.base;
2985 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2986 cm->devnum = devnum;
2987
2988 r = managed_card_setup_bus(cm);
2989 if (r < 0)
2990 return r;
2991
2992 r = grdrm_card_add(&cm->card, name);
2993 if (r < 0)
2994 return r;
2995
2996 managed_card_take_device(cm);
2997
2998 if (out)
2999 *out = basecard;
3000 basecard = NULL;
3001 return 0;
3002 }
3003
3004 static void managed_card_free(grdev_card *basecard) {
3005 managed_card *cm = managed_card_from_base(basecard);
3006
3007 assert(!basecard->enabled);
3008
3009 managed_card_release_device(cm);
3010 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
3011 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
3012 grdrm_card_destroy(&cm->card);
3013 free(cm);
3014 }
3015
3016 static const grdev_card_vtable managed_card_vtable = {
3017 .free = managed_card_free,
3018 .enable = managed_card_enable,
3019 .disable = managed_card_disable,
3020 .commit = grdrm_card_commit,
3021 .restore = grdrm_card_restore,
3022 };
3023
3024 /*
3025 * Generic Constructor
3026 * Instead of relying on the caller to choose between managed and unmanaged
3027 * DRM devices, the grdev_drm_new() constructor does that for you (by
3028 * looking at session->managed).
3029 */
3030
3031 bool grdev_is_drm_card(grdev_card *basecard) {
3032 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
3033 basecard->vtable == &managed_card_vtable);
3034 }
3035
3036 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
3037 char name[GRDRM_CARD_NAME_MAX];
3038
3039 assert_return(session, NULL);
3040 assert_return(devnum != 0, NULL);
3041
3042 grdrm_name(name, devnum);
3043 return grdev_find_card(session, name);
3044 }
3045
3046 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
3047 assert_return(session, -EINVAL);
3048 assert_return(ud, -EINVAL);
3049
3050 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
3051 }
3052
3053 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
3054 const char *p, *action;
3055 grdrm_card *card;
3056 dev_t devnum;
3057
3058 assert(basecard);
3059 assert(grdev_is_drm_card(basecard));
3060 assert(ud);
3061
3062 card = grdrm_card_from_base(basecard);
3063
3064 action = udev_device_get_action(ud);
3065 if (!action || streq(action, "add") || streq(action, "remove")) {
3066 /* If we get add/remove events on DRM nodes without devnum, we
3067 * got hotplugged DRM objects so refresh the device. */
3068 devnum = udev_device_get_devnum(ud);
3069 if (devnum == 0) {
3070 card->hotplug = true;
3071 grdrm_card_hotplug(card);
3072 }
3073 } else if (streq_ptr(action, "change")) {
3074 /* A change event with HOTPLUG=1 is sent whenever a connector
3075 * changed state. Refresh the device to update our state. */
3076 p = udev_device_get_property_value(ud, "HOTPLUG");
3077 if (streq_ptr(p, "1")) {
3078 card->hotplug = true;
3079 grdrm_card_hotplug(card);
3080 }
3081 }
3082 }