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"
47 #define GRDRM_MAX_TRIES (16)
49 typedef struct grdrm_object grdrm_object;
50 typedef struct grdrm_plane grdrm_plane;
51 typedef struct grdrm_connector grdrm_connector;
52 typedef struct grdrm_encoder grdrm_encoder;
53 typedef struct grdrm_crtc grdrm_crtc;
55 typedef struct grdrm_fb grdrm_fb;
56 typedef struct grdrm_pipe grdrm_pipe;
57 typedef struct grdrm_card grdrm_card;
58 typedef struct unmanaged_card unmanaged_card;
59 typedef struct managed_card managed_card;
78 void (*free_fn) (grdrm_object *object);
101 struct grdrm_connector {
107 uint32_t used_encoder;
114 uint32_t max_encoders;
118 struct drm_mode_modeinfo *modes;
122 uint64_t *prop_values;
126 struct grdrm_encoder {
147 uint32_t fb_offset_x;
148 uint32_t fb_offset_y;
151 uint32_t n_used_connectors;
152 uint32_t max_used_connectors;
153 uint32_t *used_connectors;
156 struct drm_mode_modeinfo mode;
166 uint32_t n_connectors;
167 uint32_t *connectors;
170 struct drm_mode_modeinfo mode;
174 struct drm_mode_modeinfo mode;
175 uint32_t n_connectors;
176 uint32_t max_connectors;
177 uint32_t *connectors;
185 #define GRDRM_OBJECT_INIT(_card, _id, _index, _type, _free_fn) ((grdrm_object){ \
190 .free_fn = (_free_fn), \
193 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id);
194 int grdrm_object_add(grdrm_object *object);
195 grdrm_object *grdrm_object_free(grdrm_object *object);
197 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_object*, grdrm_object_free);
199 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index);
200 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index);
201 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index);
202 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index);
204 #define plane_from_object(_obj) container_of((_obj), grdrm_plane, object)
205 #define connector_from_object(_obj) container_of((_obj), grdrm_connector, object)
206 #define encoder_from_object(_obj) container_of((_obj), grdrm_encoder, object)
207 #define crtc_from_object(_obj) container_of((_obj), grdrm_crtc, object)
223 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode);
224 grdrm_fb *grdrm_fb_free(grdrm_fb *fb);
226 DEFINE_TRIVIAL_CLEANUP_FUNC(grdrm_fb*, grdrm_fb_free);
228 #define fb_from_base(_fb) container_of((_fb), grdrm_fb, base)
240 #define grdrm_pipe_from_base(_e) container_of((_e), grdrm_pipe, base)
242 #define GRDRM_PIPE_NAME_MAX (GRDRM_CARD_NAME_MAX + 1 + DECIMAL_STR_MAX(uint32_t))
244 static const grdev_pipe_vtable grdrm_pipe_vtable;
246 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs);
256 sd_event_source *fd_src;
260 uint32_t n_connectors;
265 bool async_hotplug : 1;
270 bool cap_monotonic : 1;
273 struct unmanaged_card {
278 struct managed_card {
282 sd_bus_slot *slot_pause_device;
283 sd_bus_slot *slot_resume_device;
284 sd_bus_slot *slot_take_device;
286 bool requested : 1; /* TakeDevice() was sent */
287 bool acquired : 1; /* TakeDevice() was successful */
288 bool master : 1; /* we are DRM-Master */
291 #define grdrm_card_from_base(_e) container_of((_e), grdrm_card, base)
292 #define unmanaged_card_from_base(_e) \
293 container_of(grdrm_card_from_base(_e), unmanaged_card, card)
294 #define managed_card_from_base(_e) \
295 container_of(grdrm_card_from_base(_e), managed_card, card)
297 #define GRDRM_CARD_INIT(_vtable, _session) ((grdrm_card){ \
298 .base = GRDEV_CARD_INIT((_vtable), (_session)), \
303 #define GRDRM_CARD_NAME_MAX (6 + DECIMAL_STR_MAX(unsigned) * 2)
305 static const grdev_card_vtable unmanaged_card_vtable;
306 static const grdev_card_vtable managed_card_vtable;
308 static int grdrm_card_open(grdrm_card *card, int dev_fd);
309 static void grdrm_card_close(grdrm_card *card);
310 static bool grdrm_card_async(grdrm_card *card, int r);
313 * The page-flip event of the kernel provides 64bit of arbitrary user-data. As
314 * drivers tend to drop events on intermediate deep mode-sets or because we
315 * might receive events during session activation, we try to avoid allocaing
316 * dynamic data on those events. Instead, we safe the CRTC id plus a 32bit
317 * counter in there. This way, we only get 32bit counters, not 64bit, but that
318 * should be more than enough. On the bright side, we no longer care whether we
319 * lose events. No memory leaks will occur.
320 * Modern DRM drivers might be fixed to no longer leak events, but we want to
321 * be safe. And associating dynamically allocated data with those events is
322 * kinda ugly, anyway.
325 static uint64_t grdrm_encode_vblank_data(uint32_t id, uint32_t counter) {
326 return id | ((uint64_t)counter << 32);
329 static void grdrm_decode_vblank_data(uint64_t data, uint32_t *out_id, uint32_t *out_counter) {
331 *out_id = data & 0xffffffffU;
333 *out_counter = (data >> 32) & 0xffffffffU;
336 static bool grdrm_modes_compatible(const struct drm_mode_modeinfo *a, const struct drm_mode_modeinfo *b) {
340 /* Test whether both modes are compatible according to our internal
341 * assumptions on modes. This comparison is highly dependent on how
342 * we treat modes in grdrm. If we export mode details, we need to
343 * make this comparison much stricter. */
345 if (a->hdisplay != b->hdisplay)
347 if (a->vdisplay != b->vdisplay)
349 if (a->vrefresh != b->vrefresh)
359 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
360 assert_return(card, NULL);
362 return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
365 int grdrm_object_add(grdrm_object *object) {
369 assert(object->card);
370 assert(object->id > 0);
371 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
372 assert(object->free_fn);
374 if (object->index >= 32)
375 log_debug("grdrm: %s: object index exceeds 32bit masks: type=%u, index=%" PRIu32,
376 object->card->base.name, object->type, object->index);
378 r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
385 grdrm_object *grdrm_object_free(grdrm_object *object) {
389 assert(object->card);
390 assert(object->id > 0);
391 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
392 assert(object->free_fn);
394 hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
396 object->free_fn(object);
404 static void plane_free(grdrm_object *object) {
405 grdrm_plane *plane = plane_from_object(object);
407 free(plane->kern.formats);
408 free(plane->kern.crtcs);
412 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index) {
413 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
419 plane = new0(grdrm_plane, 1);
423 object = &plane->object;
424 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
426 plane->kern.max_crtcs = 32;
427 plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
428 if (!plane->kern.crtcs)
431 plane->kern.max_formats = 32;
432 plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
433 if (!plane->kern.formats)
436 r = grdrm_object_add(object);
446 static int grdrm_plane_resync(grdrm_plane *plane) {
447 grdrm_card *card = plane->object.card;
453 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
454 struct drm_mode_get_plane res;
455 grdrm_object *object;
456 bool resized = false;
460 res.plane_id = plane->object.id;
461 res.format_type_ptr = PTR_TO_UINT64(plane->kern.formats);
462 res.count_format_types = plane->kern.max_formats;
464 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
468 card->async_hotplug = true;
470 log_debug("grdrm: %s: plane %u removed during resync",
471 card->base.name, plane->object.id);
473 log_debug_errno(errno, "grdrm: %s: cannot retrieve plane %u: %m",
474 card->base.name, plane->object.id);
480 plane->kern.n_crtcs = 0;
481 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
483 HASHMAP_FOREACH(object, card->object_map, iter) {
484 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
486 if (!(res.possible_crtcs & (1 << object->index)))
488 if (plane->kern.n_crtcs >= 32) {
489 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
490 card->base.name, plane->object.id);
494 plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
497 if (res.count_format_types > plane->kern.max_formats) {
500 max = ALIGN_POWER2(res.count_format_types);
501 if (!max || max > UINT16_MAX) {
502 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
506 t = realloc(plane->kern.formats, sizeof(*t) * max);
510 plane->kern.formats = t;
511 plane->kern.max_formats = max;
518 plane->kern.n_formats = res.count_format_types;
519 plane->kern.used_crtc = res.crtc_id;
520 plane->kern.used_fb = res.fb_id;
521 plane->kern.gamma_size = res.gamma_size;
526 if (tries >= GRDRM_MAX_TRIES) {
527 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
538 static void connector_free(grdrm_object *object) {
539 grdrm_connector *connector = connector_from_object(object);
541 free(connector->kern.prop_values);
542 free(connector->kern.prop_ids);
543 free(connector->kern.modes);
544 free(connector->kern.encoders);
548 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
549 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
550 grdrm_connector *connector;
555 connector = new0(grdrm_connector, 1);
559 object = &connector->object;
560 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
562 connector->kern.max_encoders = 32;
563 connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
564 if (!connector->kern.encoders)
567 connector->kern.max_modes = 32;
568 connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
569 if (!connector->kern.modes)
572 connector->kern.max_props = 32;
573 connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
574 connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
575 if (!connector->kern.prop_ids || !connector->kern.prop_values)
578 r = grdrm_object_add(object);
588 static int grdrm_connector_resync(grdrm_connector *connector) {
589 grdrm_card *card = connector->object.card;
595 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
596 struct drm_mode_get_connector res;
597 bool resized = false;
601 res.connector_id = connector->object.id;
602 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
603 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
604 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
605 res.count_encoders = connector->kern.max_encoders;
606 res.count_props = connector->kern.max_props;
608 /* The kernel reads modes from the EDID information only if we
609 * pass count_modes==0. This is a legacy hack for libdrm (which
610 * called every ioctl twice). Now we have to adopt.. *sigh*.
611 * If we never received an hotplug event, there's no reason to
612 * sync modes. EDID reads are heavy, so skip that if not
616 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
617 res.count_modes = connector->kern.max_modes;
623 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
627 card->async_hotplug = true;
629 log_debug("grdrm: %s: connector %u removed during resync",
630 card->base.name, connector->object.id);
632 log_debug_errno(errno, "grdrm: %s: cannot retrieve connector %u: %m",
633 card->base.name, connector->object.id);
639 if (res.count_encoders > connector->kern.max_encoders) {
642 max = ALIGN_POWER2(res.count_encoders);
643 if (!max || max > UINT16_MAX) {
644 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
648 t = realloc(connector->kern.encoders, sizeof(*t) * max);
652 connector->kern.encoders = t;
653 connector->kern.max_encoders = max;
657 if (res.count_modes > connector->kern.max_modes) {
658 struct drm_mode_modeinfo *t;
660 max = ALIGN_POWER2(res.count_modes);
661 if (!max || max > UINT16_MAX) {
662 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
666 t = realloc(connector->kern.modes, sizeof(*t) * max);
670 connector->kern.modes = t;
671 connector->kern.max_modes = max;
675 if (res.count_props > connector->kern.max_props) {
679 max = ALIGN_POWER2(res.count_props);
680 if (!max || max > UINT16_MAX) {
681 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
685 tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
688 connector->kern.prop_ids = tids;
690 tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
693 connector->kern.prop_values = tvals;
695 connector->kern.max_props = max;
702 connector->kern.n_encoders = res.count_encoders;
703 connector->kern.n_props = res.count_props;
704 connector->kern.type = res.connector_type;
705 connector->kern.type_id = res.connector_type_id;
706 connector->kern.used_encoder = res.encoder_id;
707 connector->kern.connection = res.connection;
708 connector->kern.mm_width = res.mm_width;
709 connector->kern.mm_height = res.mm_height;
710 connector->kern.subpixel = res.subpixel;
711 if (res.modes_ptr == PTR_TO_UINT64(connector->kern.modes))
712 connector->kern.n_modes = res.count_modes;
717 if (tries >= GRDRM_MAX_TRIES) {
718 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
729 static void encoder_free(grdrm_object *object) {
730 grdrm_encoder *encoder = encoder_from_object(object);
732 free(encoder->kern.clones);
733 free(encoder->kern.crtcs);
737 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
738 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
739 grdrm_encoder *encoder;
744 encoder = new0(grdrm_encoder, 1);
748 object = &encoder->object;
749 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
751 encoder->kern.max_crtcs = 32;
752 encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
753 if (!encoder->kern.crtcs)
756 encoder->kern.max_clones = 32;
757 encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
758 if (!encoder->kern.clones)
761 r = grdrm_object_add(object);
771 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
772 grdrm_card *card = encoder->object.card;
773 struct drm_mode_get_encoder res;
774 grdrm_object *object;
781 res.encoder_id = encoder->object.id;
783 r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
787 card->async_hotplug = true;
789 log_debug("grdrm: %s: encoder %u removed during resync",
790 card->base.name, encoder->object.id);
792 log_debug_errno(errno, "grdrm: %s: cannot retrieve encoder %u: %m",
793 card->base.name, encoder->object.id);
799 encoder->kern.type = res.encoder_type;
800 encoder->kern.used_crtc = res.crtc_id;
802 encoder->kern.n_crtcs = 0;
803 memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
805 HASHMAP_FOREACH(object, card->object_map, iter) {
806 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
808 if (!(res.possible_crtcs & (1 << object->index)))
810 if (encoder->kern.n_crtcs >= 32) {
811 log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
815 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
818 encoder->kern.n_clones = 0;
819 memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
821 HASHMAP_FOREACH(object, card->object_map, iter) {
822 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
824 if (!(res.possible_clones & (1 << object->index)))
826 if (encoder->kern.n_clones >= 32) {
827 log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
831 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
841 static void crtc_free(grdrm_object *object) {
842 grdrm_crtc *crtc = crtc_from_object(object);
845 grdev_pipe_free(&crtc->pipe->base);
846 free(crtc->set.connectors);
847 free(crtc->old.connectors);
848 free(crtc->kern.used_connectors);
852 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
853 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
859 crtc = new0(grdrm_crtc, 1);
863 object = &crtc->object;
864 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
866 crtc->kern.max_used_connectors = 32;
867 crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
868 if (!crtc->kern.used_connectors)
871 crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
872 if (!crtc->old.connectors)
875 r = grdrm_object_add(object);
885 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
886 grdrm_card *card = crtc->object.card;
887 struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
892 /* make sure we can cache any combination later */
893 if (card->n_connectors > crtc->kern.max_used_connectors) {
896 max = ALIGN_POWER2(card->n_connectors);
900 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
904 crtc->kern.used_connectors = t;
905 crtc->kern.max_used_connectors = max;
907 if (!crtc->old.set) {
908 crtc->old.connectors = calloc(sizeof(*t), max);
909 if (!crtc->old.connectors)
914 /* GETCRTC doesn't return connectors. We have to read all
915 * encoder-state and deduce the setup ourselves.. */
916 crtc->kern.n_used_connectors = 0;
918 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
922 card->async_hotplug = true;
924 log_debug("grdrm: %s: crtc %u removed during resync",
925 card->base.name, crtc->object.id);
927 log_debug_errno(errno, "grdrm: %s: cannot retrieve crtc %u: %m",
928 card->base.name, crtc->object.id);
934 crtc->kern.used_fb = res.fb_id;
935 crtc->kern.fb_offset_x = res.x;
936 crtc->kern.fb_offset_y = res.y;
937 crtc->kern.gamma_size = res.gamma_size;
938 crtc->kern.mode_set = res.mode_valid;
939 crtc->kern.mode = res.mode;
944 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
945 uint32_t n_connectors;
949 assert(!crtc->object.assigned);
950 assert(!connector || !connector->object.assigned);
952 /* always mark both as assigned; even if assignments cannot be set */
953 crtc->object.assigned = true;
955 connector->object.assigned = true;
957 /* we will support hw clone mode in the future */
958 n_connectors = connector ? 1 : 0;
960 /* bail out if configuration is preserved */
961 if (crtc->set.n_connectors == n_connectors &&
962 (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
965 crtc->applied = false;
966 crtc->set.n_connectors = 0;
968 if (n_connectors > crtc->set.max_connectors) {
971 max = ALIGN_POWER2(n_connectors);
977 t = realloc(crtc->set.connectors, sizeof(*t) * max);
983 crtc->set.connectors = t;
984 crtc->set.max_connectors = max;
988 struct drm_mode_modeinfo *m, *pref = NULL;
991 for (i = 0; i < connector->kern.n_modes; ++i) {
992 m = &connector->kern.modes[i];
994 /* ignore 3D modes by default */
995 if (m->flags & DRM_MODE_FLAG_3D_MASK)
1003 /* use PREFERRED over non-PREFERRED */
1004 if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
1005 !(m->type & DRM_MODE_TYPE_PREFERRED))
1008 /* use DRIVER over non-PREFERRED|DRIVER */
1009 if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
1010 !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
1013 /* always prefer higher resolution */
1014 if (pref->hdisplay > m->hdisplay ||
1015 (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1022 crtc->set.mode = *pref;
1023 crtc->set.n_connectors = 1;
1024 crtc->set.connectors[0] = connector->object.id;
1025 log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1026 crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1028 log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1029 crtc->object.card->base.name, connector->object.id);
1036 log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1037 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1040 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1047 assert(crtc->object.assigned);
1049 if (crtc->set.n_connectors < 1) {
1051 grdev_pipe_free(&crtc->pipe->base);
1058 if (pipe->base.width != crtc->set.mode.hdisplay ||
1059 pipe->base.height != crtc->set.mode.vdisplay ||
1060 pipe->base.vrefresh != crtc->set.mode.vrefresh) {
1061 grdev_pipe_free(&pipe->base);
1068 pipe->base.front = NULL;
1069 pipe->base.back = NULL;
1070 for (i = 0; i < pipe->base.max_fbs; ++i) {
1071 fb = fb_from_base(pipe->base.fbs[i]);
1072 if (fb->id == crtc->kern.used_fb)
1073 pipe->base.front = &fb->base;
1074 else if (!fb->flipid)
1075 pipe->base.back = &fb->base;
1078 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1080 log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1081 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1085 for (i = 0; i < pipe->base.max_fbs; ++i) {
1086 r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1088 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1089 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1090 grdev_pipe_free(&pipe->base);
1094 pipe->base.fbs[i] = &fb->base;
1097 pipe->base.front = NULL;
1098 pipe->base.back = pipe->base.fbs[0];
1102 grdev_pipe_ready(&crtc->pipe->base, true);
1105 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb *basefb) {
1106 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1107 grdrm_card *card = crtc->object.card;
1108 grdrm_pipe *pipe = crtc->pipe;
1116 fb = fb_from_base(basefb);
1118 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1119 set_crtc.count_connectors = crtc->set.n_connectors;
1120 set_crtc.fb_id = fb->id;
1123 set_crtc.mode_valid = 1;
1124 set_crtc.mode = crtc->set.mode;
1126 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1129 log_debug_errno(errno, "grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1130 card->base.name, crtc->object.id);
1132 grdrm_card_async(card, r);
1136 if (!crtc->applied) {
1137 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1138 card->base.name, crtc->object.id);
1139 crtc->applied = true;
1142 pipe->base.back = NULL;
1143 pipe->base.front = &fb->base;
1146 pipe->base.flipping = false;
1147 pipe->base.flip = false;
1149 /* We cannot schedule dummy page-flips on pipes, hence, the
1150 * application would have to schedule their own frame-timers.
1151 * To avoid duplicating that everywhere, we schedule our own
1152 * timer and raise a fake FRAME event when it fires. */
1153 grdev_pipe_schedule(&pipe->base, 1);
1156 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
1157 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1158 grdrm_card *card = crtc->object.card;
1159 grdrm_pipe *pipe = crtc->pipe;
1168 if (!crtc->applied) {
1169 if (!grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1172 /* TODO: Theoretically, we should be able to page-flip to our
1173 * framebuffer here. We didn't perform any deep modeset, but the
1174 * DRM driver is really supposed to reject our page-flip in case
1175 * the FB is not compatible. We then properly fall back to a
1177 * As it turns out, drivers don't to this. Therefore, we need to
1178 * perform a full modeset on enter now. We might avoid this in
1179 * the future with fixed drivers.. */
1184 fb = fb_from_base(basefb);
1186 cnt = ++pipe->counter ? : ++pipe->counter;
1187 page_flip.fb_id = fb->id;
1188 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1189 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1191 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1194 /* Avoid excessive logging on EINVAL; it is currently not
1195 * possible to see whether cards support page-flipping, so
1196 * avoid logging on each frame. */
1198 log_debug_errno(errno, "grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1199 card->base.name, crtc->object.id);
1201 if (grdrm_card_async(card, r))
1207 if (!crtc->applied) {
1208 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1209 card->base.name, crtc->object.id);
1210 crtc->applied = true;
1213 pipe->base.flipping = true;
1214 pipe->base.flip = false;
1215 pipe->counter = cnt;
1217 pipe->base.back = NULL;
1219 /* Raise fake FRAME event if it takes longer than 2
1220 * frames to receive the pageflip event. We assume the
1221 * queue ran over or some other error happened. */
1222 grdev_pipe_schedule(&pipe->base, 2);
1227 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1228 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1229 grdrm_card *card = crtc->object.card;
1235 assert(crtc->object.assigned);
1239 /* If a crtc is not assigned any connector, we want any
1240 * previous setup to be cleared, so make sure the CRTC is
1241 * disabled. Otherwise, there might be content on the CRTC
1242 * while we run, which is not what we want.
1243 * If you want to avoid modesets on specific CRTCs, you should
1244 * still keep their assignment, but never enable the resulting
1245 * pipe. This way, we wouldn't touch it at all. */
1246 if (!crtc->applied) {
1247 crtc->applied = true;
1248 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1251 log_debug_errno(errno, "grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1252 card->base.name, crtc->object.id);
1254 grdrm_card_async(card, r);
1258 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1259 card->base.name, crtc->object.id);
1265 /* we always fully ignore disabled pipes */
1266 if (!pipe->base.enabled)
1269 assert(crtc->set.n_connectors > 0);
1271 if (pipe->base.flip)
1272 fb = pipe->base.back;
1273 else if (!crtc->applied)
1274 fb = pipe->base.front;
1281 r = grdrm_crtc_commit_flip(crtc, fb);
1283 /* in case we couldn't page-flip, perform deep modeset */
1284 grdrm_crtc_commit_deep(crtc, fb);
1288 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1289 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1290 grdrm_card *card = crtc->object.card;
1296 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1297 set_crtc.count_connectors = crtc->old.n_connectors;
1298 set_crtc.fb_id = crtc->old.fb;
1299 set_crtc.x = crtc->old.fb_x;
1300 set_crtc.y = crtc->old.fb_y;
1301 set_crtc.gamma_size = crtc->old.gamma;
1302 set_crtc.mode_valid = crtc->old.mode_set;
1303 set_crtc.mode = crtc->old.mode;
1305 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1308 log_debug_errno(errno, "grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1309 card->base.name, crtc->object.id);
1311 grdrm_card_async(card, r);
1316 ++crtc->pipe->counter;
1317 crtc->pipe->base.front = NULL;
1318 crtc->pipe->base.flipping = false;
1321 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1324 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1325 bool flipped = false;
1336 /* We got a page-flip event. To be safe, we reset all FBs on the same
1337 * pipe that have smaller flipids than the flip we got as we know they
1338 * are executed in order. We need to do this to guarantee
1339 * queue-overflows or other missed events don't cause starvation.
1340 * Furthermore, if we find the exact FB this event is for, *and* this
1341 * is the most recent event, we mark it as front FB and raise a
1344 for (i = 0; i < pipe->base.max_fbs; ++i) {
1347 if (!pipe->base.fbs[i])
1350 fb = fb_from_base(pipe->base.fbs[i]);
1351 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1352 pipe->base.front = &fb->base;
1355 } else if (counter - fb->flipid < UINT16_MAX) {
1361 crtc->pipe->base.flipping = false;
1362 grdev_pipe_frame(&pipe->base);
1370 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1371 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1372 struct drm_mode_create_dumb create_dumb = { };
1373 struct drm_mode_map_dumb map_dumb = { };
1374 struct drm_mode_fb_cmd2 add_fb = { };
1378 assert_return(out, -EINVAL);
1379 assert_return(card, -EINVAL);
1381 fb = new0(grdrm_fb, 1);
1385 /* TODO: we should choose a compatible format of the previous CRTC
1386 * setting to allow page-flip to it. Only choose fallback if the
1387 * previous setting was crap (non xrgb32'ish). */
1390 fb->base.format = DRM_FORMAT_XRGB8888;
1391 fb->base.width = mode->hdisplay;
1392 fb->base.height = mode->vdisplay;
1394 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1395 fb->base.maps[i] = MAP_FAILED;
1397 create_dumb.width = fb->base.width;
1398 create_dumb.height = fb->base.height;
1399 create_dumb.bpp = 32;
1401 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1403 r = negative_errno();
1404 log_debug_errno(errno, "grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1405 card->base.name, fb->base.width, fb->base.height);
1409 fb->handles[0] = create_dumb.handle;
1410 fb->base.strides[0] = create_dumb.pitch;
1411 fb->sizes[0] = create_dumb.size;
1413 map_dumb.handle = fb->handles[0];
1415 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1417 r = negative_errno();
1418 log_debug_errno(errno, "grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1419 card->base.name, fb->base.width, fb->base.height);
1423 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1424 if (fb->base.maps[0] == MAP_FAILED) {
1425 r = negative_errno();
1426 log_debug_errno(errno, "grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1427 card->base.name, fb->base.width, fb->base.height);
1431 memzero(fb->base.maps[0], fb->sizes[0]);
1433 add_fb.width = fb->base.width;
1434 add_fb.height = fb->base.height;
1435 add_fb.pixel_format = fb->base.format;
1437 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1438 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1439 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1441 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1443 r = negative_errno();
1444 log_debug_errno(errno, "grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1445 card->base.name, fb->base.width, fb->base.height);
1449 fb->id = add_fb.fb_id;
1456 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1465 if (fb->base.free_fn)
1466 fb->base.free_fn(fb->base.data.ptr);
1468 if (fb->id > 0 && fb->card->fd >= 0) {
1469 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1471 log_debug_errno(errno, "grdrm: %s: cannot delete framebuffer %" PRIu32 ": %m",
1472 fb->card->base.name, fb->id);
1475 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1476 struct drm_mode_destroy_dumb destroy_dumb = { };
1478 if (fb->base.maps[i] != MAP_FAILED)
1479 munmap(fb->base.maps[i], fb->sizes[i]);
1481 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1482 destroy_dumb.handle = fb->handles[i];
1483 r = ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1485 log_debug_errno(errno, "grdrm: %s: cannot destroy dumb-buffer %" PRIu32 ": %m",
1486 fb->card->base.name, fb->handles[i]);
1499 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1500 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1501 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1504 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1505 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1506 grdrm_card *card = crtc->object.card;
1507 char name[GRDRM_PIPE_NAME_MAX];
1511 assert_return(crtc, -EINVAL);
1512 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1514 pipe = new0(grdrm_pipe, 1);
1518 basepipe = &pipe->base;
1519 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1521 pipe->base.width = mode->hdisplay;
1522 pipe->base.height = mode->vdisplay;
1523 pipe->base.vrefresh = mode->vrefresh ? : 25;
1525 grdrm_pipe_name(name, crtc);
1526 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1536 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1537 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1542 for (i = 0; i < pipe->base.max_fbs; ++i)
1543 if (pipe->base.fbs[i])
1544 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1549 static grdev_fb *grdrm_pipe_target(grdev_pipe *basepipe) {
1553 if (!basepipe->back) {
1554 for (i = 0; i < basepipe->max_fbs; ++i) {
1555 if (!basepipe->fbs[i])
1558 fb = fb_from_base(basepipe->fbs[i]);
1559 if (&fb->base == basepipe->front)
1561 if (basepipe->flipping && fb->flipid)
1564 basepipe->back = &fb->base;
1569 return basepipe->back;
1572 static void grdrm_pipe_enable(grdev_pipe *basepipe) {
1573 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1575 pipe->crtc->applied = false;
1578 static void grdrm_pipe_disable(grdev_pipe *basepipe) {
1579 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1581 pipe->crtc->applied = false;
1584 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1585 .free = grdrm_pipe_free,
1586 .target = grdrm_pipe_target,
1587 .enable = grdrm_pipe_enable,
1588 .disable = grdrm_pipe_disable,
1595 static void grdrm_name(char *out, dev_t devnum) {
1596 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1597 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1600 static void grdrm_card_print(grdrm_card *card) {
1601 grdrm_object *object;
1603 grdrm_encoder *encoder;
1604 grdrm_connector *connector;
1610 log_debug("grdrm: %s: state dump", card->base.name);
1612 log_debug(" crtcs:");
1613 HASHMAP_FOREACH(object, card->object_map, iter) {
1614 if (object->type != GRDRM_TYPE_CRTC)
1617 crtc = crtc_from_object(object);
1618 log_debug(" (id: %u index: %d)", object->id, object->index);
1620 if (crtc->kern.mode_set)
1621 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1623 log_debug(" mode: <none>");
1626 log_debug(" encoders:");
1627 HASHMAP_FOREACH(object, card->object_map, iter) {
1628 if (object->type != GRDRM_TYPE_ENCODER)
1631 encoder = encoder_from_object(object);
1632 log_debug(" (id: %u index: %d)", object->id, object->index);
1634 if (encoder->kern.used_crtc)
1635 log_debug(" crtc: %u", encoder->kern.used_crtc);
1637 log_debug(" crtc: <none>");
1639 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1644 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1645 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1647 log_debug(" possible crtcs:%s", buf);
1651 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1656 for (i = 0; i < encoder->kern.n_clones; ++i)
1657 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1659 log_debug(" possible clones:%s", buf);
1664 log_debug(" connectors:");
1665 HASHMAP_FOREACH(object, card->object_map, iter) {
1666 if (object->type != GRDRM_TYPE_CONNECTOR)
1669 connector = connector_from_object(object);
1670 log_debug(" (id: %u index: %d)", object->id, object->index);
1671 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1672 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1673 connector->kern.mm_width, connector->kern.mm_height);
1675 if (connector->kern.used_encoder)
1676 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1678 log_debug(" encoder: <none>");
1680 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1685 for (i = 0; i < connector->kern.n_encoders; ++i)
1686 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1688 log_debug(" possible encoders:%s", buf);
1692 for (i = 0; i < connector->kern.n_modes; ++i) {
1693 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1694 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1698 log_debug(" planes:");
1699 HASHMAP_FOREACH(object, card->object_map, iter) {
1700 if (object->type != GRDRM_TYPE_PLANE)
1703 plane = plane_from_object(object);
1704 log_debug(" (id: %u index: %d)", object->id, object->index);
1705 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1707 if (plane->kern.used_crtc)
1708 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1710 log_debug(" crtc: <none>");
1712 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1717 for (i = 0; i < plane->kern.n_crtcs; ++i)
1718 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1720 log_debug(" possible crtcs:%s", buf);
1724 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1729 for (i = 0; i < plane->kern.n_formats; ++i)
1730 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1732 log_debug(" possible formats:%s", buf);
1738 static int grdrm_card_resync(grdrm_card *card) {
1739 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1740 uint32_t allocated = 0;
1741 grdrm_object *object;
1748 card->async_hotplug = false;
1751 /* mark existing objects for possible removal */
1752 HASHMAP_FOREACH(object, card->object_map, iter)
1753 object->present = false;
1755 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1756 struct drm_mode_get_plane_res pres;
1757 struct drm_mode_card_res res;
1760 if (allocated < card->max_ids) {
1763 free(connector_ids);
1765 crtc_ids = new0(uint32_t, card->max_ids);
1766 encoder_ids = new0(uint32_t, card->max_ids);
1767 connector_ids = new0(uint32_t, card->max_ids);
1768 plane_ids = new0(uint32_t, card->max_ids);
1770 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1773 allocated = card->max_ids;
1777 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1778 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1779 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1780 res.count_crtcs = allocated;
1781 res.count_encoders = allocated;
1782 res.count_connectors = allocated;
1784 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1787 log_debug_errno(errno, "grdrm: %s: cannot retrieve drm resources: %m",
1793 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1794 pres.count_planes = allocated;
1796 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1799 log_debug_errno(errno, "grdrm: %s: cannot retrieve drm plane-resources: %m",
1804 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1805 MAX(res.count_connectors, pres.count_planes));
1806 if (max > allocated) {
1809 n = ALIGN_POWER2(max);
1810 if (!n || n > UINT16_MAX) {
1811 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32,
1812 card->base.name, max);
1816 /* retry with resized buffers */
1821 /* mark available objects as present */
1823 for (i = 0; i < res.count_crtcs; ++i) {
1824 object = grdrm_find_object(card, crtc_ids[i]);
1825 if (object && object->type == GRDRM_TYPE_CRTC) {
1826 object->present = true;
1832 for (i = 0; i < res.count_encoders; ++i) {
1833 object = grdrm_find_object(card, encoder_ids[i]);
1834 if (object && object->type == GRDRM_TYPE_ENCODER) {
1835 object->present = true;
1841 for (i = 0; i < res.count_connectors; ++i) {
1842 object = grdrm_find_object(card, connector_ids[i]);
1843 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1844 object->present = true;
1846 connector_ids[i] = 0;
1850 for (i = 0; i < pres.count_planes; ++i) {
1851 object = grdrm_find_object(card, plane_ids[i]);
1852 if (object && object->type == GRDRM_TYPE_PLANE) {
1853 object->present = true;
1859 /* drop removed objects */
1861 HASHMAP_FOREACH(object, card->object_map, iter)
1862 if (!object->present)
1863 grdrm_object_free(object);
1865 /* add new objects */
1867 card->n_crtcs = res.count_crtcs;
1868 for (i = 0; i < res.count_crtcs; ++i) {
1869 if (crtc_ids[i] < 1)
1872 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1877 card->n_encoders = res.count_encoders;
1878 for (i = 0; i < res.count_encoders; ++i) {
1879 if (encoder_ids[i] < 1)
1882 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1887 card->n_connectors = res.count_connectors;
1888 for (i = 0; i < res.count_connectors; ++i) {
1889 if (connector_ids[i] < 1)
1892 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1897 card->n_planes = pres.count_planes;
1898 for (i = 0; i < pres.count_planes; ++i) {
1899 if (plane_ids[i] < 1)
1902 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1907 /* re-sync objects after object_map is synced */
1909 HASHMAP_FOREACH(object, card->object_map, iter) {
1910 switch (object->type) {
1911 case GRDRM_TYPE_CRTC:
1912 r = grdrm_crtc_resync(crtc_from_object(object));
1914 case GRDRM_TYPE_ENCODER:
1915 r = grdrm_encoder_resync(encoder_from_object(object));
1917 case GRDRM_TYPE_CONNECTOR:
1918 r = grdrm_connector_resync(connector_from_object(object));
1920 case GRDRM_TYPE_PLANE:
1921 r = grdrm_plane_resync(plane_from_object(object));
1924 assert_not_reached("grdrm: invalid object type");
1931 if (card->async_hotplug)
1935 /* if modeset objects change during sync, start over */
1936 if (card->async_hotplug) {
1937 card->async_hotplug = false;
1941 /* cache crtc/connector relationship */
1942 HASHMAP_FOREACH(object, card->object_map, iter) {
1943 grdrm_connector *connector;
1944 grdrm_encoder *encoder;
1947 if (object->type != GRDRM_TYPE_CONNECTOR)
1950 connector = connector_from_object(object);
1951 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1954 object = grdrm_find_object(card, connector->kern.used_encoder);
1955 if (!object || object->type != GRDRM_TYPE_ENCODER)
1958 encoder = encoder_from_object(object);
1959 if (encoder->kern.used_crtc < 1)
1962 object = grdrm_find_object(card, encoder->kern.used_crtc);
1963 if (!object || object->type != GRDRM_TYPE_CRTC)
1966 crtc = crtc_from_object(object);
1967 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1968 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1971 /* cache old crtc settings for later restore */
1972 HASHMAP_FOREACH(object, card->object_map, iter) {
1975 if (object->type != GRDRM_TYPE_CRTC)
1978 crtc = crtc_from_object(object);
1980 /* Save data if it is the first time we refresh the CRTC. This data can
1981 * be used optionally to restore any previous configuration. For
1982 * instance, it allows us to restore VT configurations after we close
1983 * our session again. */
1984 if (!crtc->old.set) {
1985 crtc->old.fb = crtc->kern.used_fb;
1986 crtc->old.fb_x = crtc->kern.fb_offset_x;
1987 crtc->old.fb_y = crtc->kern.fb_offset_y;
1988 crtc->old.gamma = crtc->kern.gamma_size;
1989 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1990 if (crtc->old.n_connectors)
1991 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1992 crtc->old.mode_set = crtc->kern.mode_set;
1993 crtc->old.mode = crtc->kern.mode;
1994 crtc->old.set = true;
1998 /* everything synced */
2002 if (tries >= GRDRM_MAX_TRIES) {
2004 * Ugh! We were unable to sync the DRM card state due to heavy
2005 * hotplugging. This should never happen, so print a debug
2006 * message and bail out. The next uevent will trigger
2010 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
2017 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
2018 grdrm_card *card = crtc->object.card;
2019 grdrm_encoder *encoder;
2020 grdrm_object *object;
2023 if (crtc->object.assigned || connector->object.assigned)
2025 if (connector->kern.connection != 1)
2028 for (i = 0; i < connector->kern.n_encoders; ++i) {
2029 object = grdrm_find_object(card, connector->kern.encoders[i]);
2030 if (!object || object->type != GRDRM_TYPE_ENCODER)
2033 encoder = encoder_from_object(object);
2034 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
2035 if (encoder->kern.crtcs[j] == crtc->object.id) {
2036 grdrm_crtc_assign(crtc, connector);
2045 static void grdrm_card_configure(grdrm_card *card) {
2047 * Modeset Configuration
2048 * This is where we update our modeset configuration and assign
2049 * connectors to CRTCs. This means, each connector that we want to
2050 * enable needs a CRTC, disabled (or unavailable) connectors are left
2051 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
2053 * Sounds trivial, but there're several caveats:
2055 * * Multiple connectors can be driven by the same CRTC. This is
2056 * known as 'hardware clone mode'. Advantage over software clone
2057 * mode is that only a single CRTC is needed to drive multiple
2058 * displays. However, few hardware supports this and it's a huge
2059 * headache to configure on dynamic demands. Therefore, we only
2060 * support it if configured statically beforehand.
2062 * * CRTCs are not created equal. Some might be much more powerful
2063 * than others, including more advanced plane support. So far, our
2064 * CRTC selection is random. You need to supply static
2065 * configuration if you want special setups. So far, there is no
2066 * proper way to do advanced CRTC selection on dynamic demands. It
2067 * is not really clear which demands require what CRTC, so, like
2068 * everyone else, we do random CRTC selection unless explicitly
2071 * * Each Connector has a list of possible encoders that can drive
2072 * it, and each encoder has a list of possible CRTCs. If this graph
2073 * is a tree, assignment is trivial. However, if not, we cannot
2074 * reliably decide on configurations beforehand. The encoder is
2075 * always selected by the kernel, so we have to actually set a mode
2076 * to know which encoder is used. There is no way to ask the kernel
2077 * whether a given configuration is possible. This will change with
2078 * atomic-modesetting, but until then, we keep our configurations
2079 * simple and assume they work all just fine. If one fails
2080 * unexpectedly, we print a warning and disable it.
2082 * Configuring a card consists of several steps:
2084 * 1) First of all, we apply any user-configuration. If a user wants
2085 * a fixed configuration, we apply it and preserve it.
2086 * So far, we don't support user configuration files, so this step
2089 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
2090 * might only support limited configurations or require special
2091 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2093 * So far, we don't support this as there is no known quirk, so
2094 * this step is skipped.
2096 * 3) As deep modesets are expensive, we try to avoid them if
2097 * possible. Therefore, we read the current configuration from the
2098 * kernel and try to preserve it, if compatible with our demands.
2099 * If not, we break it and reassign it in a following step.
2101 * 4) The main step involves configuring all remaining objects. By
2102 * default, all available connectors are enabled, except for those
2103 * disabled by user-configuration. We lookup a suitable CRTC for
2104 * each connector and assign them. As there might be more
2105 * connectors than CRTCs, we apply some ordering so users can
2106 * select which connectors are more important right now.
2107 * So far, we only apply the default ordering, more might be added
2111 grdrm_object *object;
2115 /* clear assignments */
2116 HASHMAP_FOREACH(object, card->object_map, i)
2117 object->assigned = false;
2119 /* preserve existing configurations */
2120 HASHMAP_FOREACH(object, card->object_map, i) {
2121 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2124 crtc = crtc_from_object(object);
2126 if (crtc->applied) {
2127 /* If our mode is set, preserve it. If no connector is
2128 * set, modeset either failed or the pipe is unused. In
2129 * both cases, leave it alone. It might be tried again
2130 * below in case there're remaining connectors.
2131 * Otherwise, try restoring the assignments. If they
2132 * are no longer valid, leave the pipe untouched. */
2134 if (crtc->set.n_connectors < 1)
2137 assert(crtc->set.n_connectors == 1);
2139 object = grdrm_find_object(card, crtc->set.connectors[0]);
2140 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2143 card_configure_crtc(crtc, connector_from_object(object));
2144 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2145 /* If our mode is not set on the pipe, we know the kern
2146 * information is valid. Try keeping it. If it's not
2147 * possible, leave the pipe untouched for later
2150 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2151 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2154 card_configure_crtc(crtc, connector_from_object(object));
2158 /* assign remaining objects */
2159 HASHMAP_FOREACH(object, card->object_map, i) {
2160 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2163 crtc = crtc_from_object(object);
2165 HASHMAP_FOREACH(object, card->object_map, j) {
2166 if (object->type != GRDRM_TYPE_CONNECTOR)
2169 if (card_configure_crtc(crtc, connector_from_object(object)))
2173 if (!crtc->object.assigned)
2174 grdrm_crtc_assign(crtc, NULL);
2177 /* expose configuration */
2178 HASHMAP_FOREACH(object, card->object_map, i) {
2179 if (object->type != GRDRM_TYPE_CRTC)
2182 grdrm_crtc_expose(crtc_from_object(object));
2186 static void grdrm_card_hotplug(grdrm_card *card) {
2194 log_debug("grdrm: %s/%s: reconfigure card", card->base.session->name, card->base.name);
2196 card->ready = false;
2197 r = grdrm_card_resync(card);
2199 log_debug_errno(r, "grdrm: %s/%s: cannot re-sync card: %m",
2200 card->base.session->name, card->base.name);
2204 grdev_session_pin(card->base.session);
2206 /* debug statement to print card information */
2208 grdrm_card_print(card);
2210 grdrm_card_configure(card);
2212 card->hotplug = false;
2214 grdev_session_unpin(card->base.session);
2217 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2218 grdrm_card *card = userdata;
2219 struct drm_event_vblank *vblank;
2220 struct drm_event *event;
2221 uint32_t id, counter;
2222 grdrm_object *object;
2227 if (revents & (EPOLLHUP | EPOLLERR)) {
2228 /* Immediately close device on HUP; no need to flush pending
2229 * data.. there're no events we care about here. */
2230 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2231 grdrm_card_close(card);
2235 if (revents & (EPOLLIN)) {
2236 l = read(card->fd, buf, sizeof(buf));
2238 if (errno == EAGAIN || errno == EINTR)
2241 log_debug_errno(errno, "grdrm: %s/%s: read error: %m",
2242 card->base.session->name, card->base.name);
2243 grdrm_card_close(card);
2247 for (len = l; len > 0; len -= event->length) {
2250 if (len < sizeof(*event) || len < event->length) {
2251 log_debug("grdrm: %s/%s: truncated event",
2252 card->base.session->name, card->base.name);
2256 switch (event->type) {
2257 case DRM_EVENT_FLIP_COMPLETE:
2258 vblank = (void*)event;
2259 if (event->length < sizeof(*vblank)) {
2260 log_debug("grdrm: %s/%s: truncated vblank event",
2261 card->base.session->name, card->base.name);
2265 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2266 object = grdrm_find_object(card, id);
2267 if (!object || object->type != GRDRM_TYPE_CRTC)
2270 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2279 static int grdrm_card_add(grdrm_card *card, const char *name) {
2281 assert(card->fd < 0);
2283 card->object_map = hashmap_new(&trivial_hash_ops);
2284 if (!card->object_map)
2287 return grdev_card_add(&card->base, name);
2290 static void grdrm_card_destroy(grdrm_card *card) {
2292 assert(!card->running);
2293 assert(card->fd < 0);
2294 assert(hashmap_size(card->object_map) == 0);
2296 hashmap_free(card->object_map);
2299 static void grdrm_card_commit(grdev_card *basecard) {
2300 grdrm_card *card = grdrm_card_from_base(basecard);
2301 grdrm_object *object;
2304 HASHMAP_FOREACH(object, card->object_map, iter) {
2308 if (object->type != GRDRM_TYPE_CRTC)
2311 grdrm_crtc_commit(crtc_from_object(object));
2315 static void grdrm_card_restore(grdev_card *basecard) {
2316 grdrm_card *card = grdrm_card_from_base(basecard);
2317 grdrm_object *object;
2320 HASHMAP_FOREACH(object, card->object_map, iter) {
2324 if (object->type != GRDRM_TYPE_CRTC)
2327 grdrm_crtc_restore(crtc_from_object(object));
2331 static void grdrm_card_enable(grdrm_card *card) {
2334 if (card->fd < 0 || card->running)
2337 /* ignore cards without DUMB_BUFFER capability */
2338 if (!card->cap_dumb)
2341 assert(card->fd_src);
2343 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2345 card->running = true;
2346 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2347 grdrm_card_hotplug(card);
2350 static void grdrm_card_disable(grdrm_card *card) {
2351 grdrm_object *object;
2356 if (card->fd < 0 || !card->running)
2359 assert(card->fd_src);
2361 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2363 card->running = false;
2364 card->ready = false;
2365 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2367 /* stop all pipes */
2368 HASHMAP_FOREACH(object, card->object_map, iter) {
2371 if (object->type != GRDRM_TYPE_CRTC)
2374 crtc = crtc_from_object(object);
2375 crtc->applied = false;
2377 grdev_pipe_ready(&crtc->pipe->base, false);
2381 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2382 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2383 _cleanup_close_ int fd = dev_fd;
2384 struct drm_get_cap cap;
2388 assert(dev_fd >= 0);
2389 assert(card->fd != dev_fd);
2391 pin = grdev_session_pin(card->base.session);
2392 grdrm_card_close(card);
2394 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2396 r = fd_nonblock(fd, true);
2400 r = fd_cloexec(fd, true);
2404 flags = fcntl(fd, F_GETFL, 0);
2407 if ((flags & O_ACCMODE) != O_RDWR)
2410 r = sd_event_add_io(card->base.session->context->event,
2413 EPOLLHUP | EPOLLERR | EPOLLIN,
2419 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2421 card->hotplug = true;
2425 /* cache DUMB_BUFFER capability */
2426 cap.capability = DRM_CAP_DUMB_BUFFER;
2428 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2429 card->cap_dumb = r >= 0 && cap.value;
2431 log_debug_errno(r, "grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %m",
2432 card->base.session->name, card->base.name);
2433 else if (!card->cap_dumb)
2434 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2435 card->base.session->name, card->base.name);
2437 /* cache TIMESTAMP_MONOTONIC capability */
2438 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2440 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2441 card->cap_monotonic = r >= 0 && cap.value;
2443 log_debug_errno(r, "grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %m",
2444 card->base.session->name, card->base.name);
2445 else if (!card->cap_monotonic)
2446 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2447 card->base.session->name, card->base.name);
2452 static void grdrm_card_close(grdrm_card *card) {
2453 grdrm_object *object;
2458 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2460 grdrm_card_disable(card);
2462 card->fd_src = sd_event_source_unref(card->fd_src);
2463 card->fd = safe_close(card->fd);
2465 grdev_session_pin(card->base.session);
2466 while ((object = hashmap_first(card->object_map)))
2467 grdrm_object_free(object);
2468 grdev_session_unpin(card->base.session);
2471 static bool grdrm_card_async(grdrm_card *card, int r) {
2474 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2475 * (or we did something terribly wrong). Immediately disable
2476 * the card, so we stop all pipes and wait to be activated
2478 grdrm_card_disable(card);
2481 /* DRM objects can be hotplugged at any time. If an object is
2482 * removed that we use, we remember that state so a following
2483 * call can test for this.
2484 * Note that we also get a uevent as followup, this will resync
2485 * the whole device. */
2486 card->async_hotplug = true;
2490 return !card->ready;
2495 * The unmanaged DRM card opens the device node for a given DRM device
2496 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2497 * the device only if we really require it and releases it as soon as we're
2498 * disabled or closed.
2499 * The unmanaged element can be used in all situations where you have direct
2500 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2501 * outside of user sessions and in emergency situations where logind is not
2505 static void unmanaged_card_enable(grdev_card *basecard) {
2506 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2509 if (cu->card.fd < 0) {
2510 /* try open on activation if it failed during allocation */
2511 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2513 /* not fatal; simply ignore the device */
2514 log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
2515 basecard->session->name, basecard->name, cu->devnode);
2519 /* we might already be DRM-Master by open(); that's fine */
2521 r = grdrm_card_open(&cu->card, fd);
2523 log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2524 basecard->session->name, basecard->name);
2529 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2531 log_debug_errno(errno, "grdrm: %s/%s: cannot acquire DRM-Master: %m",
2532 basecard->session->name, basecard->name);
2536 grdrm_card_enable(&cu->card);
2539 static void unmanaged_card_disable(grdev_card *basecard) {
2540 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2542 grdrm_card_disable(&cu->card);
2545 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2546 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2547 char name[GRDRM_CARD_NAME_MAX];
2549 const char *devnode;
2553 assert_return(session, -EINVAL);
2554 assert_return(ud, -EINVAL);
2556 devnode = udev_device_get_devnode(ud);
2557 devnum = udev_device_get_devnum(ud);
2558 if (!devnode || devnum == 0)
2561 grdrm_name(name, devnum);
2563 cu = new0(unmanaged_card, 1);
2567 basecard = &cu->card.base;
2568 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2570 cu->devnode = strdup(devnode);
2574 r = grdrm_card_add(&cu->card, name);
2578 /* try to open but ignore errors */
2579 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2581 /* not fatal; allow uaccess based control on activation */
2582 log_debug_errno(errno, "grdrm: %s/%s: cannot open node %s: %m",
2583 basecard->session->name, basecard->name, cu->devnode);
2585 /* We might get DRM-Master implicitly on open(); drop it immediately
2586 * so we acquire it only once we're actually enabled. We don't
2587 * really care whether this call fails or not, but lets log any
2588 * weird errors, anyway. */
2589 r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2590 if (r < 0 && errno != EACCES && errno != EINVAL)
2591 log_debug_errno(errno, "grdrm: %s/%s: cannot drop DRM-Master: %m",
2592 basecard->session->name, basecard->name);
2594 r = grdrm_card_open(&cu->card, fd);
2596 log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2597 basecard->session->name, basecard->name);
2606 static void unmanaged_card_free(grdev_card *basecard) {
2607 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2609 assert(!basecard->enabled);
2611 grdrm_card_close(&cu->card);
2612 grdrm_card_destroy(&cu->card);
2617 static const grdev_card_vtable unmanaged_card_vtable = {
2618 .free = unmanaged_card_free,
2619 .enable = unmanaged_card_enable,
2620 .disable = unmanaged_card_disable,
2621 .commit = grdrm_card_commit,
2622 .restore = grdrm_card_restore,
2627 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2628 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2629 * logind passes us a file-descriptor whenever our session is activated. Thus,
2630 * we don't need access to the device node directly.
2631 * Furthermore, whenever the session is put asleep, logind revokes the
2632 * file-descriptor so we loose access to the device.
2633 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2634 * you run inside a user session with exclusive device access.
2637 static void managed_card_enable(grdev_card *card) {
2638 managed_card *cm = managed_card_from_base(card);
2640 /* If the device is manually re-enabled, we try to resume our card
2641 * management. Note that we have no control over DRM-Master and the fd,
2642 * so we have to take over the state from the last logind event. */
2645 grdrm_card_enable(&cm->card);
2648 static void managed_card_disable(grdev_card *card) {
2649 managed_card *cm = managed_card_from_base(card);
2651 /* If the device is manually disabled, we keep the FD but put our card
2652 * management asleep. This way, we can wake up at any time, but don't
2653 * touch the device while asleep. */
2655 grdrm_card_disable(&cm->card);
2658 static int managed_card_pause_device_fn(sd_bus *bus,
2659 sd_bus_message *signal,
2661 sd_bus_error *ret_error) {
2662 managed_card *cm = userdata;
2663 grdev_session *session = cm->card.base.session;
2664 uint32_t major, minor;
2669 * We get PauseDevice() signals from logind whenever a device we
2670 * requested was, or is about to be, paused. Arguments are major/minor
2671 * number of the device and the mode of the operation.
2672 * In case the event is not about our device, we ignore it. Otherwise,
2673 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2674 * already handled an EACCES error from a modeset ioctl, in which case
2675 * we already disabled the device.
2677 * @mode can be one of the following:
2678 * "pause": The device is about to be paused. We must react
2679 * immediately and respond with PauseDeviceComplete(). Once
2680 * we replied, logind will pause the device. Note that
2681 * logind might apply any kind of timeout and force pause
2682 * the device if we don't respond in a timely manner. In
2683 * this case, we will receive a second PauseDevice event
2684 * with @mode set to "force" (or similar).
2685 * "force": The device was disabled forecfully by logind. DRM-Master
2686 * was already dropped. This is just an asynchronous
2687 * notification so we can put the device asleep (in case
2688 * we didn't already notice the dropped DRM-Master).
2689 * "gone": This is like "force" but is sent if the device was
2690 * paused due to a device-removal event.
2692 * We always handle PauseDevice signals as "force" as we properly
2693 * support asynchronously dropping DRM-Master, anyway. But in case
2694 * logind sent mode "pause", we also call PauseDeviceComplete() to
2695 * immediately acknowledge the request.
2698 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2700 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2701 session->name, cm->card.base.name);
2705 /* not our device? */
2706 if (makedev(major, minor) != cm->devnum)
2710 grdrm_card_disable(&cm->card);
2712 if (streq(mode, "pause")) {
2713 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2716 * Sending PauseDeviceComplete() is racy if logind triggers the
2717 * timeout. That is, if we take too long and logind pauses the
2718 * device by sending a forced PauseDevice, our
2719 * PauseDeviceComplete call will be stray. That's fine, though.
2720 * logind ignores such stray calls. Only if logind also sent a
2721 * further PauseDevice() signal, it might match our call
2722 * incorrectly to the newer PauseDevice(). That's fine, too, as
2723 * we handle that event asynchronously, anyway. Therefore,
2724 * whatever happens, we're fine. Yay!
2727 r = sd_bus_message_new_method_call(session->context->sysbus,
2729 "org.freedesktop.login1",
2731 "org.freedesktop.login1.Session",
2732 "PauseDeviceComplete");
2734 r = sd_bus_message_append(m, "uu", major, minor);
2736 r = sd_bus_send(session->context->sysbus, m, NULL);
2740 log_debug_errno(r, "grdrm: %s/%s: cannot send PauseDeviceComplete: %m",
2741 session->name, cm->card.base.name);
2747 static int managed_card_resume_device_fn(sd_bus *bus,
2748 sd_bus_message *signal,
2750 sd_bus_error *ret_error) {
2751 managed_card *cm = userdata;
2752 grdev_session *session = cm->card.base.session;
2753 uint32_t major, minor;
2757 * We get ResumeDevice signals whenever logind resumed a previously
2758 * paused device. The arguments contain the major/minor number of the
2759 * related device and a new file-descriptor for the freshly opened
2761 * If the signal is not about our device, we simply ignore it.
2762 * Otherwise, we immediately resume the device. Note that we drop the
2763 * new file-descriptor as we already have one from TakeDevice(). logind
2764 * preserves the file-context across pause/resume for DRM but only
2765 * drops/acquires DRM-Master accordingly. This way, our context (like
2766 * DRM-FBs and BOs) is preserved.
2769 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2771 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2772 session->name, cm->card.base.name);
2776 /* not our device? */
2777 if (makedev(major, minor) != cm->devnum)
2780 if (cm->card.fd < 0) {
2781 /* This shouldn't happen. We should already own an FD from
2782 * TakeDevice(). However, lets be safe and use this FD in case
2783 * we really don't have one. There is no harm in doing this
2784 * and our code works fine this way. */
2785 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2787 log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
2788 session->name, cm->card.base.name);
2792 r = grdrm_card_open(&cm->card, fd);
2794 log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2795 session->name, cm->card.base.name);
2801 if (cm->card.base.enabled)
2802 grdrm_card_enable(&cm->card);
2807 static int managed_card_setup_bus(managed_card *cm) {
2808 grdev_session *session = cm->card.base.session;
2809 _cleanup_free_ char *match = NULL;
2812 match = strjoin("type='signal',"
2813 "sender='org.freedesktop.login1',"
2814 "interface='org.freedesktop.login1.Session',"
2815 "member='PauseDevice',"
2816 "path='", session->path, "'",
2821 r = sd_bus_add_match(session->context->sysbus,
2822 &cm->slot_pause_device,
2824 managed_card_pause_device_fn,
2830 match = strjoin("type='signal',"
2831 "sender='org.freedesktop.login1',"
2832 "interface='org.freedesktop.login1.Session',"
2833 "member='ResumeDevice',"
2834 "path='", session->path, "'",
2839 r = sd_bus_add_match(session->context->sysbus,
2840 &cm->slot_resume_device,
2842 managed_card_resume_device_fn,
2850 static int managed_card_take_device_fn(sd_bus *bus,
2851 sd_bus_message *reply,
2853 sd_bus_error *ret_error) {
2854 managed_card *cm = userdata;
2855 grdev_session *session = cm->card.base.session;
2858 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2860 if (sd_bus_message_is_method_error(reply, NULL)) {
2861 const sd_bus_error *error = sd_bus_message_get_error(reply);
2863 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2864 session->name, cm->card.base.name, error->name, error->message);
2868 cm->acquired = true;
2870 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2872 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2873 session->name, cm->card.base.name);
2877 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2879 log_debug_errno(errno, "grdrm: %s/%s: cannot duplicate fd: %m",
2880 session->name, cm->card.base.name);
2884 r = grdrm_card_open(&cm->card, fd);
2886 log_debug_errno(r, "grdrm: %s/%s: cannot open: %m",
2887 session->name, cm->card.base.name);
2891 if (!paused && cm->card.base.enabled)
2892 grdrm_card_enable(&cm->card);
2897 static void managed_card_take_device(managed_card *cm) {
2898 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2899 grdev_session *session = cm->card.base.session;
2902 r = sd_bus_message_new_method_call(session->context->sysbus,
2904 "org.freedesktop.login1",
2906 "org.freedesktop.login1.Session",
2911 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2915 r = sd_bus_call_async(session->context->sysbus,
2916 &cm->slot_take_device,
2918 managed_card_take_device_fn,
2924 cm->requested = true;
2928 log_debug_errno(r, "grdrm: %s/%s: cannot send TakeDevice request: %m",
2929 session->name, cm->card.base.name);
2932 static void managed_card_release_device(managed_card *cm) {
2933 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2934 grdev_session *session = cm->card.base.session;
2938 * If TakeDevice() is pending or was successful, make sure to
2939 * release the device again. We don't care for return-values,
2940 * so send it without waiting or callbacks.
2941 * If a failed TakeDevice() is pending, but someone else took
2942 * the device on the same bus-connection, we might incorrectly
2943 * release their device. This is an unlikely race, though.
2944 * Furthermore, you really shouldn't have two users of the
2945 * controller-API on the same session, on the same devices, *AND* on
2946 * the same bus-connection. So we don't care for that race..
2949 grdrm_card_close(&cm->card);
2950 cm->requested = false;
2952 if (!cm->acquired && !cm->slot_take_device)
2955 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2956 cm->acquired = false;
2958 r = sd_bus_message_new_method_call(session->context->sysbus,
2960 "org.freedesktop.login1",
2962 "org.freedesktop.login1.Session",
2965 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2967 r = sd_bus_send(session->context->sysbus, m, NULL);
2970 if (r < 0 && r != -ENOTCONN)
2971 log_debug_errno(r, "grdrm: %s/%s: cannot send ReleaseDevice: %m",
2972 session->name, cm->card.base.name);
2975 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2976 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2977 char name[GRDRM_CARD_NAME_MAX];
2982 assert_return(session, -EINVAL);
2983 assert_return(session->managed, -EINVAL);
2984 assert_return(session->context->sysbus, -EINVAL);
2985 assert_return(ud, -EINVAL);
2987 devnum = udev_device_get_devnum(ud);
2991 grdrm_name(name, devnum);
2993 cm = new0(managed_card, 1);
2997 basecard = &cm->card.base;
2998 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2999 cm->devnum = devnum;
3001 r = managed_card_setup_bus(cm);
3005 r = grdrm_card_add(&cm->card, name);
3009 managed_card_take_device(cm);
3017 static void managed_card_free(grdev_card *basecard) {
3018 managed_card *cm = managed_card_from_base(basecard);
3020 assert(!basecard->enabled);
3022 managed_card_release_device(cm);
3023 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
3024 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
3025 grdrm_card_destroy(&cm->card);
3029 static const grdev_card_vtable managed_card_vtable = {
3030 .free = managed_card_free,
3031 .enable = managed_card_enable,
3032 .disable = managed_card_disable,
3033 .commit = grdrm_card_commit,
3034 .restore = grdrm_card_restore,
3038 * Generic Constructor
3039 * Instead of relying on the caller to choose between managed and unmanaged
3040 * DRM devices, the grdev_drm_new() constructor does that for you (by
3041 * looking at session->managed).
3044 bool grdev_is_drm_card(grdev_card *basecard) {
3045 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
3046 basecard->vtable == &managed_card_vtable);
3049 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
3050 char name[GRDRM_CARD_NAME_MAX];
3052 assert_return(session, NULL);
3053 assert_return(devnum != 0, NULL);
3055 grdrm_name(name, devnum);
3056 return grdev_find_card(session, name);
3059 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
3060 assert_return(session, -EINVAL);
3061 assert_return(ud, -EINVAL);
3063 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
3066 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
3067 const char *p, *action;
3072 assert(grdev_is_drm_card(basecard));
3075 card = grdrm_card_from_base(basecard);
3077 action = udev_device_get_action(ud);
3078 if (!action || streq(action, "add") || streq(action, "remove")) {
3079 /* If we get add/remove events on DRM nodes without devnum, we
3080 * got hotplugged DRM objects so refresh the device. */
3081 devnum = udev_device_get_devnum(ud);
3083 card->hotplug = true;
3084 grdrm_card_hotplug(card);
3086 } else if (streq_ptr(action, "change")) {
3087 /* A change event with HOTPLUG=1 is sent whenever a connector
3088 * changed state. Refresh the device to update our state. */
3089 p = udev_device_get_property_value(ud, "HOTPLUG");
3090 if (streq_ptr(p, "1")) {
3091 card->hotplug = true;
3092 grdrm_card_hotplug(card);