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