1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com>
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.
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.
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/>.
27 #include <sys/ioctl.h>
29 #include <sys/types.h>
30 #include <systemd/sd-bus.h>
31 #include <systemd/sd-event.h>
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 */
37 #include <drm_fourcc.h>
43 #include "grdev-internal.h"
45 #include "udev-util.h"
48 #define GRDRM_MAX_TRIES (16)
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;
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;
79 void (*free_fn) (grdrm_object *object);
102 struct grdrm_connector {
108 uint32_t used_encoder;
115 uint32_t max_encoders;
119 struct drm_mode_modeinfo *modes;
123 uint64_t *prop_values;
127 struct grdrm_encoder {
148 uint32_t fb_offset_x;
149 uint32_t fb_offset_y;
152 uint32_t n_used_connectors;
153 uint32_t max_used_connectors;
154 uint32_t *used_connectors;
157 struct drm_mode_modeinfo mode;
167 uint32_t n_connectors;
168 uint32_t *connectors;
171 struct drm_mode_modeinfo mode;
175 struct drm_mode_modeinfo mode;
176 uint32_t n_connectors;
177 uint32_t max_connectors;
178 uint32_t *connectors;
186 #define GRDRM_OBJECT_INIT(_card, _id, _index, _type, _free_fn) ((grdrm_object){ \
191 .free_fn = (_free_fn), \
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);
198 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_object*, grdrm_object_free);
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);
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)
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);
227 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_fb*, grdrm_fb_free);
229 #define fb_from_base(_fb) container_of((_fb), grdrm_fb, base)
241 #define grdrm_pipe_from_base(_e) container_of((_e), grdrm_pipe, base)
243 #define GRDRM_PIPE_NAME_MAX (GRDRM_CARD_NAME_MAX + 1 + DECIMAL_STR_MAX(uint32_t))
245 static const grdev_pipe_vtable grdrm_pipe_vtable;
247 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs);
257 sd_event_source *fd_src;
261 uint32_t n_connectors;
266 bool async_hotplug : 1;
271 bool cap_monotonic : 1;
274 struct unmanaged_card {
279 struct managed_card {
283 sd_bus_slot *slot_pause_device;
284 sd_bus_slot *slot_resume_device;
285 sd_bus_slot *slot_take_device;
287 bool requested : 1; /* TakeDevice() was sent */
288 bool acquired : 1; /* TakeDevice() was successful */
289 bool master : 1; /* we are DRM-Master */
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)
298 #define GRDRM_CARD_INIT(_vtable, _session) ((grdrm_card){ \
299 .base = GRDEV_CARD_INIT((_vtable), (_session)), \
304 #define GRDRM_CARD_NAME_MAX (6 + DECIMAL_STR_MAX(unsigned) * 2)
306 static const grdev_card_vtable unmanaged_card_vtable;
307 static const grdev_card_vtable managed_card_vtable;
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);
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.
326 static uint64_t grdrm_encode_vblank_data(uint32_t id, uint32_t counter) {
327 return id | ((uint64_t)counter << 32);
330 static void grdrm_decode_vblank_data(uint64_t data, uint32_t *out_id, uint32_t *out_counter) {
332 *out_id = data & 0xffffffffU;
334 *out_counter = (data >> 32) & 0xffffffffU;
337 static bool grdrm_modes_compatible(const struct drm_mode_modeinfo *a, const struct drm_mode_modeinfo *b) {
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. */
346 if (a->hdisplay != b->hdisplay)
348 if (a->vdisplay != b->vdisplay)
350 if (a->vrefresh != b->vrefresh)
360 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
361 assert_return(card, NULL);
363 return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
366 int grdrm_object_add(grdrm_object *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);
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);
379 r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
386 grdrm_object *grdrm_object_free(grdrm_object *object) {
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);
395 hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
397 object->free_fn(object);
405 static void plane_free(grdrm_object *object) {
406 grdrm_plane *plane = plane_from_object(object);
408 free(plane->kern.formats);
409 free(plane->kern.crtcs);
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;
420 plane = new0(grdrm_plane, 1);
424 object = &plane->object;
425 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
427 plane->kern.max_crtcs = 32;
428 plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
429 if (!plane->kern.crtcs)
432 plane->kern.max_formats = 32;
433 plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
434 if (!plane->kern.formats)
437 r = grdrm_object_add(object);
447 static int grdrm_plane_resync(grdrm_plane *plane) {
448 grdrm_card *card = plane->object.card;
454 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
455 struct drm_mode_get_plane res;
456 grdrm_object *object;
457 bool resized = false;
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;
465 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
469 card->async_hotplug = true;
471 log_debug("grdrm: %s: plane %u removed during resync", card->base.name, plane->object.id);
473 log_debug("grdrm: %s: cannot retrieve plane %u: %m", card->base.name, plane->object.id);
479 plane->kern.n_crtcs = 0;
480 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
482 HASHMAP_FOREACH(object, card->object_map, iter) {
483 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
485 if (!(res.possible_crtcs & (1 << object->index)))
487 if (plane->kern.n_crtcs >= 32) {
488 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
489 card->base.name, plane->object.id);
493 plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
496 if (res.count_format_types > plane->kern.max_formats) {
499 max = ALIGN_POWER2(res.count_format_types);
500 if (!max || max > UINT16_MAX) {
501 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
505 t = realloc(plane->kern.formats, sizeof(*t) * max);
509 plane->kern.formats = t;
510 plane->kern.max_formats = max;
517 plane->kern.n_formats = res.count_format_types;
518 plane->kern.used_crtc = res.crtc_id;
519 plane->kern.used_fb = res.fb_id;
520 plane->kern.gamma_size = res.gamma_size;
525 if (tries >= GRDRM_MAX_TRIES) {
526 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
537 static void connector_free(grdrm_object *object) {
538 grdrm_connector *connector = connector_from_object(object);
540 free(connector->kern.prop_values);
541 free(connector->kern.prop_ids);
542 free(connector->kern.modes);
543 free(connector->kern.encoders);
547 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
548 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
549 grdrm_connector *connector;
554 connector = new0(grdrm_connector, 1);
558 object = &connector->object;
559 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
561 connector->kern.max_encoders = 32;
562 connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
563 if (!connector->kern.encoders)
566 connector->kern.max_modes = 32;
567 connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
568 if (!connector->kern.modes)
571 connector->kern.max_props = 32;
572 connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
573 connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
574 if (!connector->kern.prop_ids || !connector->kern.prop_values)
577 r = grdrm_object_add(object);
587 static int grdrm_connector_resync(grdrm_connector *connector) {
588 grdrm_card *card = connector->object.card;
594 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
595 struct drm_mode_get_connector res;
596 bool resized = false;
600 res.connector_id = connector->object.id;
601 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
602 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
603 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
604 res.count_encoders = connector->kern.max_encoders;
605 res.count_props = connector->kern.max_props;
607 /* The kernel reads modes from the EDID information only if we
608 * pass count_modes==0. This is a legacy hack for libdrm (which
609 * called every ioctl twice). Now we have to adopt.. *sigh*.
610 * If we never received an hotplug event, there's no reason to
611 * sync modes. EDID reads are heavy, so skip that if not
615 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
616 res.count_modes = connector->kern.max_modes;
622 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
626 card->async_hotplug = true;
628 log_debug("grdrm: %s: connector %u removed during resync", card->base.name, connector->object.id);
630 log_debug("grdrm: %s: cannot retrieve connector %u: %m", card->base.name, connector->object.id);
636 if (res.count_encoders > connector->kern.max_encoders) {
639 max = ALIGN_POWER2(res.count_encoders);
640 if (!max || max > UINT16_MAX) {
641 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
645 t = realloc(connector->kern.encoders, sizeof(*t) * max);
649 connector->kern.encoders = t;
650 connector->kern.max_encoders = max;
654 if (res.count_modes > connector->kern.max_modes) {
655 struct drm_mode_modeinfo *t;
657 max = ALIGN_POWER2(res.count_modes);
658 if (!max || max > UINT16_MAX) {
659 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
663 t = realloc(connector->kern.modes, sizeof(*t) * max);
667 connector->kern.modes = t;
668 connector->kern.max_modes = max;
672 if (res.count_props > connector->kern.max_props) {
676 max = ALIGN_POWER2(res.count_props);
677 if (!max || max > UINT16_MAX) {
678 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
682 tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
685 connector->kern.prop_ids = tids;
687 tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
690 connector->kern.prop_values = tvals;
692 connector->kern.max_props = max;
699 connector->kern.n_encoders = res.count_encoders;
700 connector->kern.n_props = res.count_props;
701 connector->kern.type = res.connector_type;
702 connector->kern.type_id = res.connector_type_id;
703 connector->kern.used_encoder = res.encoder_id;
704 connector->kern.connection = res.connection;
705 connector->kern.mm_width = res.mm_width;
706 connector->kern.mm_height = res.mm_height;
707 connector->kern.subpixel = res.subpixel;
708 if (res.modes_ptr == PTR_TO_UINT64(connector->kern.modes))
709 connector->kern.n_modes = res.count_modes;
714 if (tries >= GRDRM_MAX_TRIES) {
715 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
726 static void encoder_free(grdrm_object *object) {
727 grdrm_encoder *encoder = encoder_from_object(object);
729 free(encoder->kern.clones);
730 free(encoder->kern.crtcs);
734 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
735 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
736 grdrm_encoder *encoder;
741 encoder = new0(grdrm_encoder, 1);
745 object = &encoder->object;
746 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
748 encoder->kern.max_crtcs = 32;
749 encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
750 if (!encoder->kern.crtcs)
753 encoder->kern.max_clones = 32;
754 encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
755 if (!encoder->kern.clones)
758 r = grdrm_object_add(object);
768 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
769 grdrm_card *card = encoder->object.card;
770 struct drm_mode_get_encoder res;
771 grdrm_object *object;
778 res.encoder_id = encoder->object.id;
780 r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
784 card->async_hotplug = true;
786 log_debug("grdrm: %s: encoder %u removed during resync", card->base.name, encoder->object.id);
788 log_debug("grdrm: %s: cannot retrieve encoder %u: %m", card->base.name, encoder->object.id);
794 encoder->kern.type = res.encoder_type;
795 encoder->kern.used_crtc = res.crtc_id;
797 encoder->kern.n_crtcs = 0;
798 memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
800 HASHMAP_FOREACH(object, card->object_map, iter) {
801 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
803 if (!(res.possible_crtcs & (1 << object->index)))
805 if (encoder->kern.n_crtcs >= 32) {
806 log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
810 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
813 encoder->kern.n_clones = 0;
814 memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
816 HASHMAP_FOREACH(object, card->object_map, iter) {
817 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
819 if (!(res.possible_clones & (1 << object->index)))
821 if (encoder->kern.n_clones >= 32) {
822 log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
826 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
836 static void crtc_free(grdrm_object *object) {
837 grdrm_crtc *crtc = crtc_from_object(object);
840 grdev_pipe_free(&crtc->pipe->base);
841 free(crtc->set.connectors);
842 free(crtc->old.connectors);
843 free(crtc->kern.used_connectors);
847 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
848 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
854 crtc = new0(grdrm_crtc, 1);
858 object = &crtc->object;
859 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
861 crtc->kern.max_used_connectors = 32;
862 crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
863 if (!crtc->kern.used_connectors)
866 crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
867 if (!crtc->old.connectors)
870 r = grdrm_object_add(object);
880 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
881 grdrm_card *card = crtc->object.card;
882 struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
887 /* make sure we can cache any combination later */
888 if (card->n_connectors > crtc->kern.max_used_connectors) {
891 max = ALIGN_POWER2(card->n_connectors);
895 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
899 crtc->kern.used_connectors = t;
900 crtc->kern.max_used_connectors = max;
902 if (!crtc->old.set) {
903 crtc->old.connectors = calloc(sizeof(*t), max);
904 if (!crtc->old.connectors)
909 /* GETCRTC doesn't return connectors. We have to read all
910 * encoder-state and deduce the setup ourselves.. */
911 crtc->kern.n_used_connectors = 0;
913 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
917 card->async_hotplug = true;
919 log_debug("grdrm: %s: crtc %u removed during resync", card->base.name, crtc->object.id);
921 log_debug("grdrm: %s: cannot retrieve crtc %u: %m", card->base.name, crtc->object.id);
927 crtc->kern.used_fb = res.fb_id;
928 crtc->kern.fb_offset_x = res.x;
929 crtc->kern.fb_offset_y = res.y;
930 crtc->kern.gamma_size = res.gamma_size;
931 crtc->kern.mode_set = res.mode_valid;
932 crtc->kern.mode = res.mode;
937 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
938 uint32_t n_connectors;
942 assert(!crtc->object.assigned);
943 assert(!connector || !connector->object.assigned);
945 /* always mark both as assigned; even if assignments cannot be set */
946 crtc->object.assigned = true;
948 connector->object.assigned = true;
950 /* we will support hw clone mode in the future */
951 n_connectors = connector ? 1 : 0;
953 /* bail out if configuration is preserved */
954 if (crtc->set.n_connectors == n_connectors &&
955 (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
958 crtc->applied = false;
959 crtc->set.n_connectors = 0;
961 if (n_connectors > crtc->set.max_connectors) {
964 max = ALIGN_POWER2(n_connectors);
970 t = realloc(crtc->set.connectors, sizeof(*t) * max);
976 crtc->set.connectors = t;
977 crtc->set.max_connectors = max;
981 struct drm_mode_modeinfo *m, *pref = NULL;
984 for (i = 0; i < connector->kern.n_modes; ++i) {
985 m = &connector->kern.modes[i];
987 /* ignore 3D modes by default */
988 if (m->flags & DRM_MODE_FLAG_3D_MASK)
996 /* use PREFERRED over non-PREFERRED */
997 if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
998 !(m->type & DRM_MODE_TYPE_PREFERRED))
1001 /* use DRIVER over non-PREFERRED|DRIVER */
1002 if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
1003 !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
1006 /* always prefer higher resolution */
1007 if (pref->hdisplay > m->hdisplay ||
1008 (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1015 crtc->set.mode = *pref;
1016 crtc->set.n_connectors = 1;
1017 crtc->set.connectors[0] = connector->object.id;
1018 log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1019 crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1021 log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1022 crtc->object.card->base.name, connector->object.id);
1029 log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1030 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1033 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1040 assert(crtc->object.assigned);
1042 if (crtc->set.n_connectors < 1) {
1044 grdev_pipe_free(&crtc->pipe->base);
1051 if (pipe->base.width != crtc->set.mode.hdisplay ||
1052 pipe->base.height != crtc->set.mode.vdisplay ||
1053 pipe->base.vrefresh != crtc->set.mode.vrefresh) {
1054 grdev_pipe_free(&pipe->base);
1061 pipe->base.front = NULL;
1062 pipe->base.back = NULL;
1063 for (i = 0; i < pipe->base.max_fbs; ++i) {
1064 fb = fb_from_base(pipe->base.fbs[i]);
1065 if (fb->id == crtc->kern.used_fb)
1066 pipe->base.front = &fb->base;
1067 else if (!fb->flipid)
1068 pipe->base.back = &fb->base;
1071 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1073 log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1074 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1078 for (i = 0; i < pipe->base.max_fbs; ++i) {
1079 r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1081 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1082 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1083 grdev_pipe_free(&pipe->base);
1087 pipe->base.fbs[i] = &fb->base;
1090 pipe->base.front = NULL;
1091 pipe->base.back = pipe->base.fbs[0];
1095 grdev_pipe_ready(&crtc->pipe->base, true);
1098 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
1099 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1100 grdrm_card *card = crtc->object.card;
1101 grdrm_pipe *pipe = crtc->pipe;
1102 grdrm_fb *fb = fb_from_base(*slot);
1111 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1112 set_crtc.count_connectors = crtc->set.n_connectors;
1113 set_crtc.fb_id = fb->id;
1116 set_crtc.mode_valid = 1;
1117 set_crtc.mode = crtc->set.mode;
1119 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1122 log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1123 card->base.name, crtc->object.id);
1125 grdrm_card_async(card, r);
1129 if (!crtc->applied) {
1130 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1131 card->base.name, crtc->object.id);
1132 crtc->applied = true;
1136 pipe->base.front = &fb->base;
1139 pipe->base.flipping = false;
1140 pipe->base.flip = false;
1142 /* We cannot schedule dummy page-flips on pipes, hence, the
1143 * application would have to schedule their own frame-timers.
1144 * To avoid duplicating that everywhere, we schedule our own
1145 * timer and raise a fake FRAME event when it fires. */
1146 grdev_pipe_schedule(&pipe->base, 1);
1148 if (!pipe->base.back) {
1149 for (i = 0; i < pipe->base.max_fbs; ++i) {
1150 if (!pipe->base.fbs[i])
1153 fb = fb_from_base(pipe->base.fbs[i]);
1154 if (&fb->base == pipe->base.front)
1158 pipe->base.back = &fb->base;
1164 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb **slot) {
1165 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1166 grdrm_card *card = crtc->object.card;
1167 grdrm_pipe *pipe = crtc->pipe;
1168 grdrm_fb *fb = fb_from_base(*slot);
1178 if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1181 cnt = ++pipe->counter ? : ++pipe->counter;
1182 page_flip.fb_id = fb->id;
1183 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1184 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1186 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1189 /* Avoid excessive logging on EINVAL; it is currently not
1190 * possible to see whether cards support page-flipping, so
1191 * avoid logging on each frame. */
1193 log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1194 card->base.name, crtc->object.id);
1196 if (grdrm_card_async(card, r))
1202 if (!crtc->applied) {
1203 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1204 card->base.name, crtc->object.id);
1205 crtc->applied = true;
1208 pipe->base.flipping = true;
1209 pipe->base.flip = false;
1210 pipe->counter = cnt;
1214 /* Raise fake FRAME event if it takes longer than 2
1215 * frames to receive the pageflip event. We assume the
1216 * queue ran over or some other error happened. */
1217 grdev_pipe_schedule(&pipe->base, 2);
1219 if (!pipe->base.back) {
1220 for (i = 0; i < pipe->base.max_fbs; ++i) {
1221 if (!pipe->base.fbs[i])
1224 fb = fb_from_base(pipe->base.fbs[i]);
1225 if (&fb->base == pipe->base.front)
1230 pipe->base.back = &fb->base;
1238 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1239 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1240 grdrm_card *card = crtc->object.card;
1246 assert(crtc->object.assigned);
1250 /* If a crtc is not assigned any connector, we want any
1251 * previous setup to be cleared, so make sure the CRTC is
1252 * disabled. Otherwise, there might be content on the CRTC
1253 * while we run, which is not what we want.
1254 * If you want to avoid modesets on specific CRTCs, you should
1255 * still keep their assignment, but never enable the resulting
1256 * pipe. This way, we wouldn't touch it at all. */
1257 if (!crtc->applied) {
1258 crtc->applied = true;
1259 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1262 log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1263 card->base.name, crtc->object.id);
1265 grdrm_card_async(card, r);
1269 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1270 card->base.name, crtc->object.id);
1276 /* we always fully ignore disabled pipes */
1277 if (!pipe->base.enabled)
1280 assert(crtc->set.n_connectors > 0);
1282 if (pipe->base.flip)
1283 slot = &pipe->base.back;
1284 else if (!crtc->applied)
1285 slot = &pipe->base.front;
1292 r = grdrm_crtc_commit_flip(crtc, slot);
1294 /* in case we couldn't page-flip, perform deep modeset */
1295 grdrm_crtc_commit_deep(crtc, slot);
1299 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1300 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1301 grdrm_card *card = crtc->object.card;
1307 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1308 set_crtc.count_connectors = crtc->old.n_connectors;
1309 set_crtc.fb_id = crtc->old.fb;
1310 set_crtc.x = crtc->old.fb_x;
1311 set_crtc.y = crtc->old.fb_y;
1312 set_crtc.gamma_size = crtc->old.gamma;
1313 set_crtc.mode_valid = crtc->old.mode_set;
1314 set_crtc.mode = crtc->old.mode;
1316 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1319 log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1320 card->base.name, crtc->object.id);
1322 grdrm_card_async(card, r);
1327 ++crtc->pipe->counter;
1328 crtc->pipe->base.front = NULL;
1329 crtc->pipe->base.flipping = false;
1332 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1335 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1336 bool flipped = false;
1338 grdrm_fb *back = NULL;
1348 /* We got a page-flip event. To be safe, we reset all FBs on the same
1349 * pipe that have smaller flipids than the flip we got as we know they
1350 * are executed in order. We need to do this to guarantee
1351 * queue-overflows or other missed events don't cause starvation.
1352 * Furthermore, if we find the exact FB this event is for, *and* this
1353 * is the most recent event, we mark it as front FB and raise a
1356 for (i = 0; i < pipe->base.max_fbs; ++i) {
1359 if (!pipe->base.fbs[i])
1362 fb = fb_from_base(pipe->base.fbs[i]);
1363 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1364 pipe->base.front = &fb->base;
1367 } else if (counter - fb->flipid < UINT16_MAX) {
1370 } else if (fb->flipid == 0) {
1375 if (!pipe->base.back && back)
1376 pipe->base.back = &back->base;
1379 crtc->pipe->base.flipping = false;
1380 grdev_pipe_frame(&pipe->base);
1388 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1389 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1390 struct drm_mode_create_dumb create_dumb = { };
1391 struct drm_mode_map_dumb map_dumb = { };
1392 struct drm_mode_fb_cmd2 add_fb = { };
1396 assert_return(out, -EINVAL);
1397 assert_return(card, -EINVAL);
1399 fb = new0(grdrm_fb, 1);
1403 /* TODO: we should choose a compatible format of the previous CRTC
1404 * setting to allow page-flip to it. Only choose fallback if the
1405 * previous setting was crap (non xrgb32'ish). */
1408 fb->base.format = DRM_FORMAT_XRGB8888;
1409 fb->base.width = mode->hdisplay;
1410 fb->base.height = mode->vdisplay;
1412 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1413 fb->base.maps[i] = MAP_FAILED;
1415 create_dumb.width = fb->base.width;
1416 create_dumb.height = fb->base.height;
1417 create_dumb.bpp = 32;
1419 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1422 log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1423 card->base.name, fb->base.width, fb->base.height);
1427 fb->handles[0] = create_dumb.handle;
1428 fb->base.strides[0] = create_dumb.pitch;
1429 fb->sizes[0] = create_dumb.size;
1431 map_dumb.handle = fb->handles[0];
1433 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1436 log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1437 card->base.name, fb->base.width, fb->base.height);
1441 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1442 if (fb->base.maps[0] == MAP_FAILED) {
1444 log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1445 card->base.name, fb->base.width, fb->base.height);
1449 memzero(fb->base.maps[0], fb->sizes[0]);
1451 add_fb.width = fb->base.width;
1452 add_fb.height = fb->base.height;
1453 add_fb.pixel_format = fb->base.format;
1455 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1456 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1457 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1459 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1462 log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1463 card->base.name, fb->base.width, fb->base.height);
1467 fb->id = add_fb.fb_id;
1474 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1483 if (fb->id > 0 && fb->card->fd >= 0) {
1484 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1486 log_debug("grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
1487 fb->card->base.name, fb->id);
1490 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1491 struct drm_mode_destroy_dumb destroy_dumb = { };
1493 if (fb->base.maps[i] != MAP_FAILED)
1494 munmap(fb->base.maps[i], fb->sizes[i]);
1496 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1497 destroy_dumb.handle = fb->handles[i];
1498 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1500 log_debug("grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
1501 fb->card->base.name, fb->handles[i]);
1514 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1515 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1516 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1519 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1520 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1521 grdrm_card *card = crtc->object.card;
1522 char name[GRDRM_PIPE_NAME_MAX];
1526 assert_return(crtc, -EINVAL);
1527 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1529 pipe = new0(grdrm_pipe, 1);
1533 basepipe = &pipe->base;
1534 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1536 pipe->base.width = mode->hdisplay;
1537 pipe->base.height = mode->vdisplay;
1538 pipe->base.vrefresh = mode->vrefresh ? : 25;
1540 grdrm_pipe_name(name, crtc);
1541 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1551 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1552 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1557 for (i = 0; i < pipe->base.max_fbs; ++i)
1558 if (pipe->base.fbs[i])
1559 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1564 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1565 .free = grdrm_pipe_free,
1572 static void grdrm_name(char *out, dev_t devnum) {
1573 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1574 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1577 static void grdrm_card_print(grdrm_card *card) {
1578 grdrm_object *object;
1580 grdrm_encoder *encoder;
1581 grdrm_connector *connector;
1587 log_debug("grdrm: %s: state dump", card->base.name);
1589 log_debug(" crtcs:");
1590 HASHMAP_FOREACH(object, card->object_map, iter) {
1591 if (object->type != GRDRM_TYPE_CRTC)
1594 crtc = crtc_from_object(object);
1595 log_debug(" (id: %u index: %d)", object->id, object->index);
1597 if (crtc->kern.mode_set)
1598 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1600 log_debug(" mode: <none>");
1603 log_debug(" encoders:");
1604 HASHMAP_FOREACH(object, card->object_map, iter) {
1605 if (object->type != GRDRM_TYPE_ENCODER)
1608 encoder = encoder_from_object(object);
1609 log_debug(" (id: %u index: %d)", object->id, object->index);
1611 if (encoder->kern.used_crtc)
1612 log_debug(" crtc: %u", encoder->kern.used_crtc);
1614 log_debug(" crtc: <none>");
1616 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1621 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1622 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1624 log_debug(" possible crtcs:%s", buf);
1628 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1633 for (i = 0; i < encoder->kern.n_clones; ++i)
1634 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1636 log_debug(" possible clones:%s", buf);
1641 log_debug(" connectors:");
1642 HASHMAP_FOREACH(object, card->object_map, iter) {
1643 if (object->type != GRDRM_TYPE_CONNECTOR)
1646 connector = connector_from_object(object);
1647 log_debug(" (id: %u index: %d)", object->id, object->index);
1648 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1649 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1650 connector->kern.mm_width, connector->kern.mm_height);
1652 if (connector->kern.used_encoder)
1653 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1655 log_debug(" encoder: <none>");
1657 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1662 for (i = 0; i < connector->kern.n_encoders; ++i)
1663 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1665 log_debug(" possible encoders:%s", buf);
1669 for (i = 0; i < connector->kern.n_modes; ++i) {
1670 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1671 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1675 log_debug(" planes:");
1676 HASHMAP_FOREACH(object, card->object_map, iter) {
1677 if (object->type != GRDRM_TYPE_PLANE)
1680 plane = plane_from_object(object);
1681 log_debug(" (id: %u index: %d)", object->id, object->index);
1682 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1684 if (plane->kern.used_crtc)
1685 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1687 log_debug(" crtc: <none>");
1689 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1694 for (i = 0; i < plane->kern.n_crtcs; ++i)
1695 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1697 log_debug(" possible crtcs:%s", buf);
1701 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1706 for (i = 0; i < plane->kern.n_formats; ++i)
1707 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1709 log_debug(" possible formats:%s", buf);
1715 static int grdrm_card_resync(grdrm_card *card) {
1716 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1717 uint32_t allocated = 0;
1718 grdrm_object *object;
1725 card->async_hotplug = false;
1728 /* mark existing objects for possible removal */
1729 HASHMAP_FOREACH(object, card->object_map, iter)
1730 object->present = false;
1732 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1733 struct drm_mode_get_plane_res pres;
1734 struct drm_mode_card_res res;
1737 if (allocated < card->max_ids) {
1740 free(connector_ids);
1742 crtc_ids = new0(uint32_t, card->max_ids);
1743 encoder_ids = new0(uint32_t, card->max_ids);
1744 connector_ids = new0(uint32_t, card->max_ids);
1745 plane_ids = new0(uint32_t, card->max_ids);
1747 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1750 allocated = card->max_ids;
1754 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1755 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1756 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1757 res.count_crtcs = allocated;
1758 res.count_encoders = allocated;
1759 res.count_connectors = allocated;
1761 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1764 log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
1769 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1770 pres.count_planes = allocated;
1772 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1775 log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
1779 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1780 MAX(res.count_connectors, pres.count_planes));
1781 if (max > allocated) {
1784 n = ALIGN_POWER2(max);
1785 if (!n || n > UINT16_MAX) {
1786 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
1790 /* retry with resized buffers */
1795 /* mark available objects as present */
1797 for (i = 0; i < res.count_crtcs; ++i) {
1798 object = grdrm_find_object(card, crtc_ids[i]);
1799 if (object && object->type == GRDRM_TYPE_CRTC) {
1800 object->present = true;
1806 for (i = 0; i < res.count_encoders; ++i) {
1807 object = grdrm_find_object(card, encoder_ids[i]);
1808 if (object && object->type == GRDRM_TYPE_ENCODER) {
1809 object->present = true;
1815 for (i = 0; i < res.count_connectors; ++i) {
1816 object = grdrm_find_object(card, connector_ids[i]);
1817 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1818 object->present = true;
1820 connector_ids[i] = 0;
1824 for (i = 0; i < pres.count_planes; ++i) {
1825 object = grdrm_find_object(card, plane_ids[i]);
1826 if (object && object->type == GRDRM_TYPE_PLANE) {
1827 object->present = true;
1833 /* drop removed objects */
1835 HASHMAP_FOREACH(object, card->object_map, iter)
1836 if (!object->present)
1837 grdrm_object_free(object);
1839 /* add new objects */
1841 card->n_crtcs = res.count_crtcs;
1842 for (i = 0; i < res.count_crtcs; ++i) {
1843 if (crtc_ids[i] < 1)
1846 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1851 card->n_encoders = res.count_encoders;
1852 for (i = 0; i < res.count_encoders; ++i) {
1853 if (encoder_ids[i] < 1)
1856 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1861 card->n_connectors = res.count_connectors;
1862 for (i = 0; i < res.count_connectors; ++i) {
1863 if (connector_ids[i] < 1)
1866 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1871 card->n_planes = pres.count_planes;
1872 for (i = 0; i < pres.count_planes; ++i) {
1873 if (plane_ids[i] < 1)
1876 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1881 /* re-sync objects after object_map is synced */
1883 HASHMAP_FOREACH(object, card->object_map, iter) {
1884 switch (object->type) {
1885 case GRDRM_TYPE_CRTC:
1886 r = grdrm_crtc_resync(crtc_from_object(object));
1888 case GRDRM_TYPE_ENCODER:
1889 r = grdrm_encoder_resync(encoder_from_object(object));
1891 case GRDRM_TYPE_CONNECTOR:
1892 r = grdrm_connector_resync(connector_from_object(object));
1894 case GRDRM_TYPE_PLANE:
1895 r = grdrm_plane_resync(plane_from_object(object));
1898 assert_not_reached("grdrm: invalid object type");
1905 if (card->async_hotplug)
1909 /* if modeset objects change during sync, start over */
1910 if (card->async_hotplug) {
1911 card->async_hotplug = false;
1915 /* cache crtc/connector relationship */
1916 HASHMAP_FOREACH(object, card->object_map, iter) {
1917 grdrm_connector *connector;
1918 grdrm_encoder *encoder;
1921 if (object->type != GRDRM_TYPE_CONNECTOR)
1924 connector = connector_from_object(object);
1925 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1928 object = grdrm_find_object(card, connector->kern.used_encoder);
1929 if (!object || object->type != GRDRM_TYPE_ENCODER)
1932 encoder = encoder_from_object(object);
1933 if (encoder->kern.used_crtc < 1)
1936 object = grdrm_find_object(card, encoder->kern.used_crtc);
1937 if (!object || object->type != GRDRM_TYPE_CRTC)
1940 crtc = crtc_from_object(object);
1941 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1942 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1945 /* cache old crtc settings for later restore */
1946 HASHMAP_FOREACH(object, card->object_map, iter) {
1949 if (object->type != GRDRM_TYPE_CRTC)
1952 crtc = crtc_from_object(object);
1954 /* Save data if it is the first time we refresh the CRTC. This data can
1955 * be used optionally to restore any previous configuration. For
1956 * instance, it allows us to restore VT configurations after we close
1957 * our session again. */
1958 if (!crtc->old.set) {
1959 crtc->old.fb = crtc->kern.used_fb;
1960 crtc->old.fb_x = crtc->kern.fb_offset_x;
1961 crtc->old.fb_y = crtc->kern.fb_offset_y;
1962 crtc->old.gamma = crtc->kern.gamma_size;
1963 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1964 if (crtc->old.n_connectors)
1965 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1966 crtc->old.mode_set = crtc->kern.mode_set;
1967 crtc->old.mode = crtc->kern.mode;
1968 crtc->old.set = true;
1972 /* everything synced */
1976 if (tries >= GRDRM_MAX_TRIES) {
1978 * Ugh! We were unable to sync the DRM card state due to heavy
1979 * hotplugging. This should never happen, so print a debug
1980 * message and bail out. The next uevent will trigger
1984 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
1991 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
1992 grdrm_card *card = crtc->object.card;
1993 grdrm_encoder *encoder;
1994 grdrm_object *object;
1997 if (crtc->object.assigned || connector->object.assigned)
1999 if (connector->kern.connection != 1)
2002 for (i = 0; i < connector->kern.n_encoders; ++i) {
2003 object = grdrm_find_object(card, connector->kern.encoders[i]);
2004 if (!object || object->type != GRDRM_TYPE_ENCODER)
2007 encoder = encoder_from_object(object);
2008 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
2009 if (encoder->kern.crtcs[j] == crtc->object.id) {
2010 grdrm_crtc_assign(crtc, connector);
2019 static void grdrm_card_configure(grdrm_card *card) {
2021 * Modeset Configuration
2022 * This is where we update our modeset configuration and assign
2023 * connectors to CRTCs. This means, each connector that we want to
2024 * enable needs a CRTC, disabled (or unavailable) connectors are left
2025 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
2027 * Sounds trivial, but there're several caveats:
2029 * * Multiple connectors can be driven by the same CRTC. This is
2030 * known as 'hardware clone mode'. Advantage over software clone
2031 * mode is that only a single CRTC is needed to drive multiple
2032 * displays. However, few hardware supports this and it's a huge
2033 * headache to configure on dynamic demands. Therefore, we only
2034 * support it if configured statically beforehand.
2036 * * CRTCs are not created equal. Some might be much more poweful
2037 * than others, including more advanced plane support. So far, our
2038 * CRTC selection is random. You need to supply static
2039 * configuration if you want special setups. So far, there is no
2040 * proper way to do advanced CRTC selection on dynamic demands. It
2041 * is not really clear which demands require what CRTC, so, like
2042 * everyone else, we do random CRTC selection unless explicitly
2045 * * Each Connector has a list of possible encoders that can drive
2046 * it, and each encoder has a list of possible CRTCs. If this graph
2047 * is a tree, assignment is trivial. However, if not, we cannot
2048 * reliably decide on configurations beforehand. The encoder is
2049 * always selected by the kernel, so we have to actually set a mode
2050 * to know which encoder is used. There is no way to ask the kernel
2051 * whether a given configuration is possible. This will change with
2052 * atomic-modesetting, but until then, we keep our configurations
2053 * simple and assume they work all just fine. If one fails
2054 * unexpectedly, we print a warning and disable it.
2056 * Configuring a card consists of several steps:
2058 * 1) First of all, we apply any user-configuration. If a user wants
2059 * a fixed configuration, we apply it and preserve it.
2060 * So far, we don't support user configuration files, so this step
2063 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
2064 * might only support limited configurations or require special
2065 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2067 * So far, we don't support this as there is no known quirk, so
2068 * this step is skipped.
2070 * 3) As deep modesets are expensive, we try to avoid them if
2071 * possible. Therefore, we read the current configuration from the
2072 * kernel and try to preserve it, if compatible with our demands.
2073 * If not, we break it and reassign it in a following step.
2075 * 4) The main step involves configuring all remaining objects. By
2076 * default, all available connectors are enabled, except for those
2077 * disabled by user-configuration. We lookup a suitable CRTC for
2078 * each connector and assign them. As there might be more
2079 * connectors than CRTCs, we apply some ordering so users can
2080 * select which connectors are more important right now.
2081 * So far, we only apply the default ordering, more might be added
2085 grdrm_object *object;
2089 /* clear assignments */
2090 HASHMAP_FOREACH(object, card->object_map, i)
2091 object->assigned = false;
2093 /* preserve existing configurations */
2094 HASHMAP_FOREACH(object, card->object_map, i) {
2095 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2098 crtc = crtc_from_object(object);
2100 if (crtc->applied) {
2101 /* If our mode is set, preserve it. If no connector is
2102 * set, modeset either failed or the pipe is unused. In
2103 * both cases, leave it alone. It might be tried again
2104 * below in case there're remaining connectors.
2105 * Otherwise, try restoring the assignments. If they
2106 * are no longer valid, leave the pipe untouched. */
2108 if (crtc->set.n_connectors < 1)
2111 assert(crtc->set.n_connectors == 1);
2113 object = grdrm_find_object(card, crtc->set.connectors[0]);
2114 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2117 card_configure_crtc(crtc, connector_from_object(object));
2118 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2119 /* If our mode is not set on the pipe, we know the kern
2120 * information is valid. Try keeping it. If it's not
2121 * possible, leave the pipe untouched for later
2124 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2125 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2128 card_configure_crtc(crtc, connector_from_object(object));
2132 /* assign remaining objects */
2133 HASHMAP_FOREACH(object, card->object_map, i) {
2134 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2137 crtc = crtc_from_object(object);
2139 HASHMAP_FOREACH(object, card->object_map, j) {
2140 if (object->type != GRDRM_TYPE_CONNECTOR)
2143 if (card_configure_crtc(crtc, connector_from_object(object)))
2147 if (!crtc->object.assigned)
2148 grdrm_crtc_assign(crtc, NULL);
2151 /* expose configuration */
2152 HASHMAP_FOREACH(object, card->object_map, i) {
2153 if (object->type != GRDRM_TYPE_CRTC)
2156 grdrm_crtc_expose(crtc_from_object(object));
2160 static void grdrm_card_hotplug(grdrm_card *card) {
2168 log_debug("grdrm: %s/%s: reconfigure card", card->base.session->name, card->base.name);
2170 card->ready = false;
2171 r = grdrm_card_resync(card);
2173 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2174 card->base.session->name, card->base.name, strerror(-r));
2178 grdev_session_pin(card->base.session);
2180 /* debug statement to print card information */
2182 grdrm_card_print(card);
2184 grdrm_card_configure(card);
2186 card->hotplug = false;
2188 grdev_session_unpin(card->base.session);
2191 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2192 grdrm_card *card = userdata;
2193 struct drm_event_vblank *vblank;
2194 struct drm_event *event;
2195 uint32_t id, counter;
2196 grdrm_object *object;
2201 if (revents & (EPOLLHUP | EPOLLERR)) {
2202 /* Immediately close device on HUP; no need to flush pending
2203 * data.. there're no events we care about here. */
2204 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2205 grdrm_card_close(card);
2209 if (revents & (EPOLLIN)) {
2210 l = read(card->fd, buf, sizeof(buf));
2212 if (errno == EAGAIN || errno == EINTR)
2215 log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2216 grdrm_card_close(card);
2220 for (len = l; len > 0; len -= event->length) {
2223 if (len < sizeof(*event) || len < event->length) {
2224 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2228 switch (event->type) {
2229 case DRM_EVENT_FLIP_COMPLETE:
2230 vblank = (void*)event;
2231 if (event->length < sizeof(*vblank)) {
2232 log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2236 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2237 object = grdrm_find_object(card, id);
2238 if (!object || object->type != GRDRM_TYPE_CRTC)
2241 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2250 static int grdrm_card_add(grdrm_card *card, const char *name) {
2252 assert(card->fd < 0);
2254 card->object_map = hashmap_new(&trivial_hash_ops);
2255 if (!card->object_map)
2258 return grdev_card_add(&card->base, name);
2261 static void grdrm_card_destroy(grdrm_card *card) {
2263 assert(!card->running);
2264 assert(card->fd < 0);
2265 assert(hashmap_size(card->object_map) == 0);
2267 hashmap_free(card->object_map);
2270 static void grdrm_card_commit(grdev_card *basecard) {
2271 grdrm_card *card = grdrm_card_from_base(basecard);
2272 grdrm_object *object;
2275 HASHMAP_FOREACH(object, card->object_map, iter) {
2279 if (object->type != GRDRM_TYPE_CRTC)
2282 grdrm_crtc_commit(crtc_from_object(object));
2286 static void grdrm_card_restore(grdev_card *basecard) {
2287 grdrm_card *card = grdrm_card_from_base(basecard);
2288 grdrm_object *object;
2291 HASHMAP_FOREACH(object, card->object_map, iter) {
2295 if (object->type != GRDRM_TYPE_CRTC)
2298 grdrm_crtc_restore(crtc_from_object(object));
2302 static void grdrm_card_enable(grdrm_card *card) {
2305 if (card->fd < 0 || card->running)
2308 /* ignore cards without DUMB_BUFFER capability */
2309 if (!card->cap_dumb)
2312 assert(card->fd_src);
2314 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2316 card->running = true;
2317 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2318 grdrm_card_hotplug(card);
2321 static void grdrm_card_disable(grdrm_card *card) {
2322 grdrm_object *object;
2327 if (card->fd < 0 || !card->running)
2330 assert(card->fd_src);
2332 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2334 card->running = false;
2335 card->ready = false;
2336 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2338 /* stop all pipes */
2339 HASHMAP_FOREACH(object, card->object_map, iter) {
2342 if (object->type != GRDRM_TYPE_CRTC)
2345 crtc = crtc_from_object(object);
2346 crtc->applied = false;
2348 grdev_pipe_ready(&crtc->pipe->base, false);
2352 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2353 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2354 _cleanup_close_ int fd = dev_fd;
2355 struct drm_get_cap cap;
2359 assert(dev_fd >= 0);
2360 assert(card->fd != dev_fd);
2362 pin = grdev_session_pin(card->base.session);
2363 grdrm_card_close(card);
2365 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2367 r = fd_nonblock(fd, true);
2371 r = fd_cloexec(fd, true);
2375 flags = fcntl(fd, F_GETFL, 0);
2378 if ((flags & O_ACCMODE) != O_RDWR)
2381 r = sd_event_add_io(card->base.session->context->event,
2384 EPOLLHUP | EPOLLERR | EPOLLIN,
2390 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2392 card->hotplug = true;
2396 /* cache DUMB_BUFFER capability */
2397 cap.capability = DRM_CAP_DUMB_BUFFER;
2399 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2400 card->cap_dumb = r >= 0 && cap.value;
2402 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2403 card->base.session->name, card->base.name, strerror(-r));
2404 else if (!card->cap_dumb)
2405 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2406 card->base.session->name, card->base.name);
2408 /* cache TIMESTAMP_MONOTONIC capability */
2409 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2411 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2412 card->cap_monotonic = r >= 0 && cap.value;
2414 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2415 card->base.session->name, card->base.name, strerror(-r));
2416 else if (!card->cap_monotonic)
2417 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2418 card->base.session->name, card->base.name);
2423 static void grdrm_card_close(grdrm_card *card) {
2424 grdrm_object *object;
2429 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2431 grdrm_card_disable(card);
2433 card->fd_src = sd_event_source_unref(card->fd_src);
2434 card->fd = safe_close(card->fd);
2436 grdev_session_pin(card->base.session);
2437 while ((object = hashmap_first(card->object_map)))
2438 grdrm_object_free(object);
2439 grdev_session_unpin(card->base.session);
2442 static bool grdrm_card_async(grdrm_card *card, int r) {
2445 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2446 * (or we did something terribly wrong). Immediately disable
2447 * the card, so we stop all pipes and wait to be activated
2449 grdrm_card_disable(card);
2452 /* DRM objects can be hotplugged at any time. If an object is
2453 * removed that we use, we remember that state so a following
2454 * call can test for this.
2455 * Note that we also get a uevent as followup, this will resync
2456 * the whole device. */
2457 card->async_hotplug = true;
2461 return !card->ready;
2466 * The unmanaged DRM card opens the device node for a given DRM device
2467 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2468 * the device only if we really require it and releases it as soon as we're
2469 * disabled or closed.
2470 * The unmanaged element can be used in all situations where you have direct
2471 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2472 * outside of user sessions and in emergency situations where logind is not
2476 static void unmanaged_card_enable(grdev_card *basecard) {
2477 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2480 if (cu->card.fd < 0) {
2481 /* try open on activation if it failed during allocation */
2482 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2484 /* not fatal; simply ignore the device */
2485 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2486 basecard->session->name, basecard->name, cu->devnode);
2490 /* we might already be DRM-Master by open(); that's fine */
2492 r = grdrm_card_open(&cu->card, fd);
2494 log_debug("grdrm: %s/%s: cannot open: %s",
2495 basecard->session->name, basecard->name, strerror(-r));
2500 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2502 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2503 basecard->session->name, basecard->name);
2507 grdrm_card_enable(&cu->card);
2510 static void unmanaged_card_disable(grdev_card *basecard) {
2511 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2513 grdrm_card_disable(&cu->card);
2516 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2517 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2518 char name[GRDRM_CARD_NAME_MAX];
2520 const char *devnode;
2524 assert_return(session, -EINVAL);
2525 assert_return(ud, -EINVAL);
2527 devnode = udev_device_get_devnode(ud);
2528 devnum = udev_device_get_devnum(ud);
2529 if (!devnode || devnum == 0)
2532 grdrm_name(name, devnum);
2534 cu = new0(unmanaged_card, 1);
2538 basecard = &cu->card.base;
2539 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2541 cu->devnode = strdup(devnode);
2545 r = grdrm_card_add(&cu->card, name);
2549 /* try to open but ignore errors */
2550 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2552 /* not fatal; allow uaccess based control on activation */
2553 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2554 basecard->session->name, basecard->name, cu->devnode);
2556 /* We might get DRM-Master implicitly on open(); drop it immediately
2557 * so we acquire it only once we're actually enabled. We don't
2558 * really care whether this call fails or not, but lets log any
2559 * weird errors, anyway. */
2560 r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2561 if (r < 0 && errno != EACCES && errno != EINVAL)
2562 log_debug("grdrm: %s/%s: cannot drop DRM-Master: %m",
2563 basecard->session->name, basecard->name);
2565 r = grdrm_card_open(&cu->card, fd);
2567 log_debug("grdrm: %s/%s: cannot open: %s",
2568 basecard->session->name, basecard->name, strerror(-r));
2577 static void unmanaged_card_free(grdev_card *basecard) {
2578 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2580 assert(!basecard->enabled);
2582 grdrm_card_close(&cu->card);
2583 grdrm_card_destroy(&cu->card);
2588 static const grdev_card_vtable unmanaged_card_vtable = {
2589 .free = unmanaged_card_free,
2590 .enable = unmanaged_card_enable,
2591 .disable = unmanaged_card_disable,
2592 .commit = grdrm_card_commit,
2593 .restore = grdrm_card_restore,
2598 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2599 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2600 * logind passes us a file-descriptor whenever our session is activated. Thus,
2601 * we don't need access to the device node directly.
2602 * Furthermore, whenever the session is put asleep, logind revokes the
2603 * file-descriptor so we loose access to the device.
2604 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2605 * you run inside a user session with exclusive device access.
2608 static void managed_card_enable(grdev_card *card) {
2609 managed_card *cm = managed_card_from_base(card);
2611 /* If the device is manually re-enabled, we try to resume our card
2612 * management. Note that we have no control over DRM-Master and the fd,
2613 * so we have to take over the state from the last logind event. */
2616 grdrm_card_enable(&cm->card);
2619 static void managed_card_disable(grdev_card *card) {
2620 managed_card *cm = managed_card_from_base(card);
2622 /* If the device is manually disabled, we keep the FD but put our card
2623 * management asleep. This way, we can wake up at any time, but don't
2624 * touch the device while asleep. */
2626 grdrm_card_disable(&cm->card);
2629 static int managed_card_pause_device_fn(sd_bus *bus,
2630 sd_bus_message *signal,
2632 sd_bus_error *ret_error) {
2633 managed_card *cm = userdata;
2634 grdev_session *session = cm->card.base.session;
2635 uint32_t major, minor;
2640 * We get PauseDevice() signals from logind whenever a device we
2641 * requested was, or is about to be, paused. Arguments are major/minor
2642 * number of the device and the mode of the operation.
2643 * In case the event is not about our device, we ignore it. Otherwise,
2644 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2645 * already handled an EACCES error from a modeset ioctl, in which case
2646 * we already disabled the device.
2648 * @mode can be one of the following:
2649 * "pause": The device is about to be paused. We must react
2650 * immediately and respond with PauseDeviceComplete(). Once
2651 * we replied, logind will pause the device. Note that
2652 * logind might apply any kind of timeout and force pause
2653 * the device if we don't respond in a timely manner. In
2654 * this case, we will receive a second PauseDevice event
2655 * with @mode set to "force" (or similar).
2656 * "force": The device was disabled forecfully by logind. DRM-Master
2657 * was already dropped. This is just an asynchronous
2658 * notification so we can put the device asleep (in case
2659 * we didn't already notice the dropped DRM-Master).
2660 * "gone": This is like "force" but is sent if the device was
2661 * paused due to a device-removal event.
2663 * We always handle PauseDevice signals as "force" as we properly
2664 * support asynchronously dropping DRM-Master, anyway. But in case
2665 * logind sent mode "pause", we also call PauseDeviceComplete() to
2666 * immediately acknowledge the request.
2669 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2671 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2672 session->name, cm->card.base.name);
2676 /* not our device? */
2677 if (makedev(major, minor) != cm->devnum)
2681 grdrm_card_disable(&cm->card);
2683 if (streq(mode, "pause")) {
2684 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2687 * Sending PauseDeviceComplete() is racy if logind triggers the
2688 * timeout. That is, if we take too long and logind pauses the
2689 * device by sending a forced PauseDevice, our
2690 * PauseDeviceComplete call will be stray. That's fine, though.
2691 * logind ignores such stray calls. Only if logind also sent a
2692 * further PauseDevice() signal, it might match our call
2693 * incorrectly to the newer PauseDevice(). That's fine, too, as
2694 * we handle that event asynchronously, anyway. Therefore,
2695 * whatever happens, we're fine. Yay!
2698 r = sd_bus_message_new_method_call(session->context->sysbus,
2700 "org.freedesktop.login1",
2702 "org.freedesktop.login1.Session",
2703 "PauseDeviceComplete");
2705 r = sd_bus_message_append(m, "uu", major, minor);
2707 r = sd_bus_send(session->context->sysbus, m, NULL);
2711 log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2712 session->name, cm->card.base.name, strerror(-r));
2718 static int managed_card_resume_device_fn(sd_bus *bus,
2719 sd_bus_message *signal,
2721 sd_bus_error *ret_error) {
2722 managed_card *cm = userdata;
2723 grdev_session *session = cm->card.base.session;
2724 uint32_t major, minor;
2728 * We get ResumeDevice signals whenever logind resumed a previously
2729 * paused device. The arguments contain the major/minor number of the
2730 * related device and a new file-descriptor for the freshly opened
2732 * If the signal is not about our device, we simply ignore it.
2733 * Otherwise, we immediately resume the device. Note that we drop the
2734 * new file-descriptor as we already have one from TakeDevice(). logind
2735 * preserves the file-context across pause/resume for DRM but only
2736 * drops/acquires DRM-Master accordingly. This way, our context (like
2737 * DRM-FBs and BOs) is preserved.
2740 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2742 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2743 session->name, cm->card.base.name);
2747 /* not our device? */
2748 if (makedev(major, minor) != cm->devnum)
2751 if (cm->card.fd < 0) {
2752 /* This shouldn't happen. We should already own an FD from
2753 * TakeDevice(). However, lets be safe and use this FD in case
2754 * we really don't have one. There is no harm in doing this
2755 * and our code works fine this way. */
2756 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2758 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2759 session->name, cm->card.base.name);
2763 r = grdrm_card_open(&cm->card, fd);
2765 log_debug("grdrm: %s/%s: cannot open: %s",
2766 session->name, cm->card.base.name, strerror(-r));
2772 if (cm->card.base.enabled)
2773 grdrm_card_enable(&cm->card);
2778 static int managed_card_setup_bus(managed_card *cm) {
2779 grdev_session *session = cm->card.base.session;
2780 _cleanup_free_ char *match = NULL;
2783 match = strjoin("type='signal',"
2784 "sender='org.freedesktop.login1',"
2785 "interface='org.freedesktop.login1.Session',"
2786 "member='PauseDevice',"
2787 "path='", session->path, "'",
2792 r = sd_bus_add_match(session->context->sysbus,
2793 &cm->slot_pause_device,
2795 managed_card_pause_device_fn,
2801 match = strjoin("type='signal',"
2802 "sender='org.freedesktop.login1',"
2803 "interface='org.freedesktop.login1.Session',"
2804 "member='ResumeDevice',"
2805 "path='", session->path, "'",
2810 r = sd_bus_add_match(session->context->sysbus,
2811 &cm->slot_resume_device,
2813 managed_card_resume_device_fn,
2821 static int managed_card_take_device_fn(sd_bus *bus,
2822 sd_bus_message *reply,
2824 sd_bus_error *ret_error) {
2825 managed_card *cm = userdata;
2826 grdev_session *session = cm->card.base.session;
2829 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2831 if (sd_bus_message_is_method_error(reply, NULL)) {
2832 const sd_bus_error *error = sd_bus_message_get_error(reply);
2834 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2835 session->name, cm->card.base.name, error->name, error->message);
2839 cm->acquired = true;
2841 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2843 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2844 session->name, cm->card.base.name);
2848 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2850 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2851 session->name, cm->card.base.name);
2855 r = grdrm_card_open(&cm->card, fd);
2857 log_debug("grdrm: %s/%s: cannot open: %s",
2858 session->name, cm->card.base.name, strerror(-r));
2862 if (!paused && cm->card.base.enabled)
2863 grdrm_card_enable(&cm->card);
2868 static void managed_card_take_device(managed_card *cm) {
2869 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2870 grdev_session *session = cm->card.base.session;
2873 r = sd_bus_message_new_method_call(session->context->sysbus,
2875 "org.freedesktop.login1",
2877 "org.freedesktop.login1.Session",
2882 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2886 r = sd_bus_call_async(session->context->sysbus,
2887 &cm->slot_take_device,
2889 managed_card_take_device_fn,
2895 cm->requested = true;
2899 log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2900 session->name, cm->card.base.name, strerror(-r));
2903 static void managed_card_release_device(managed_card *cm) {
2904 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2905 grdev_session *session = cm->card.base.session;
2909 * If TakeDevice() is pending or was successful, make sure to
2910 * release the device again. We don't care for return-values,
2911 * so send it without waiting or callbacks.
2912 * If a failed TakeDevice() is pending, but someone else took
2913 * the device on the same bus-connection, we might incorrectly
2914 * release their device. This is an unlikely race, though.
2915 * Furthermore, you really shouldn't have two users of the
2916 * controller-API on the same session, on the same devices, *AND* on
2917 * the same bus-connection. So we don't care for that race..
2920 grdrm_card_close(&cm->card);
2921 cm->requested = false;
2923 if (!cm->acquired && !cm->slot_take_device)
2926 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2927 cm->acquired = false;
2929 r = sd_bus_message_new_method_call(session->context->sysbus,
2931 "org.freedesktop.login1",
2933 "org.freedesktop.login1.Session",
2936 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2938 r = sd_bus_send(session->context->sysbus, m, NULL);
2941 if (r < 0 && r != -ENOTCONN)
2942 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2943 session->name, cm->card.base.name, strerror(-r));
2946 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2947 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2948 char name[GRDRM_CARD_NAME_MAX];
2953 assert_return(session, -EINVAL);
2954 assert_return(session->managed, -EINVAL);
2955 assert_return(session->context->sysbus, -EINVAL);
2956 assert_return(ud, -EINVAL);
2958 devnum = udev_device_get_devnum(ud);
2962 grdrm_name(name, devnum);
2964 cm = new0(managed_card, 1);
2968 basecard = &cm->card.base;
2969 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2970 cm->devnum = devnum;
2972 r = managed_card_setup_bus(cm);
2976 r = grdrm_card_add(&cm->card, name);
2980 managed_card_take_device(cm);
2988 static void managed_card_free(grdev_card *basecard) {
2989 managed_card *cm = managed_card_from_base(basecard);
2991 assert(!basecard->enabled);
2993 managed_card_release_device(cm);
2994 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
2995 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
2996 grdrm_card_destroy(&cm->card);
3000 static const grdev_card_vtable managed_card_vtable = {
3001 .free = managed_card_free,
3002 .enable = managed_card_enable,
3003 .disable = managed_card_disable,
3004 .commit = grdrm_card_commit,
3005 .restore = grdrm_card_restore,
3009 * Generic Constructor
3010 * Instead of relying on the caller to choose between managed and unmanaged
3011 * DRM devices, the grdev_drm_new() constructor does that for you (by
3012 * looking at session->managed).
3015 bool grdev_is_drm_card(grdev_card *basecard) {
3016 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
3017 basecard->vtable == &managed_card_vtable);
3020 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
3021 char name[GRDRM_CARD_NAME_MAX];
3023 assert_return(session, NULL);
3024 assert_return(devnum != 0, NULL);
3026 grdrm_name(name, devnum);
3027 return grdev_find_card(session, name);
3030 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
3031 assert_return(session, -EINVAL);
3032 assert_return(ud, -EINVAL);
3034 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
3037 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
3038 const char *p, *action;
3043 assert(grdev_is_drm_card(basecard));
3046 card = grdrm_card_from_base(basecard);
3048 action = udev_device_get_action(ud);
3049 if (!action || streq(action, "add") || streq(action, "remove")) {
3050 /* If we get add/remove events on DRM nodes without devnum, we
3051 * got hotplugged DRM objects so refresh the device. */
3052 devnum = udev_device_get_devnum(ud);
3054 card->hotplug = true;
3055 grdrm_card_hotplug(card);
3057 } else if (streq_ptr(action, "change")) {
3058 /* A change event with HOTPLUG=1 is sent whenever a connector
3059 * changed state. Refresh the device to update our state. */
3060 p = udev_device_get_property_value(ud, "HOTPLUG");
3061 if (streq_ptr(p, "1")) {
3062 card->hotplug = true;
3063 grdrm_card_hotplug(card);