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;
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)
357 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
358 assert_return(card, NULL);
360 return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
363 int grdrm_object_add(grdrm_object *object) {
367 assert(object->card);
368 assert(object->id > 0);
369 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
370 assert(object->free_fn);
372 if (object->index >= 32)
373 log_debug("grdrm: %s: object index exceeds 32bit masks: type=%u, index=%" PRIu32,
374 object->card->base.name, object->type, object->index);
376 r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
383 grdrm_object *grdrm_object_free(grdrm_object *object) {
387 assert(object->card);
388 assert(object->id > 0);
389 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
390 assert(object->free_fn);
392 hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
394 object->free_fn(object);
402 static void plane_free(grdrm_object *object) {
403 grdrm_plane *plane = plane_from_object(object);
405 free(plane->kern.formats);
406 free(plane->kern.crtcs);
410 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index) {
411 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
417 plane = new0(grdrm_plane, 1);
421 object = &plane->object;
422 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
424 plane->kern.max_crtcs = 32;
425 plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
426 if (!plane->kern.crtcs)
429 plane->kern.max_formats = 32;
430 plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
431 if (!plane->kern.formats)
434 r = grdrm_object_add(object);
444 static int grdrm_plane_resync(grdrm_plane *plane) {
445 grdrm_card *card = plane->object.card;
451 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
452 struct drm_mode_get_plane res;
453 grdrm_object *object;
454 bool resized = false;
458 res.plane_id = plane->object.id;
459 res.format_type_ptr = PTR_TO_UINT64(plane->kern.formats);
460 res.count_format_types = plane->kern.max_formats;
462 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
466 card->async_hotplug = true;
468 log_debug("grdrm: %s: plane %u removed during resync", card->base.name, plane->object.id);
470 log_debug("grdrm: %s: cannot retrieve plane %u: %m", card->base.name, plane->object.id);
476 plane->kern.n_crtcs = 0;
477 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
479 HASHMAP_FOREACH(object, card->object_map, iter) {
480 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
482 if (!(res.possible_crtcs & (1 << object->index)))
484 if (plane->kern.n_crtcs >= 32) {
485 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
486 card->base.name, plane->object.id);
490 plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
493 if (res.count_format_types > plane->kern.max_formats) {
496 max = ALIGN_POWER2(res.count_format_types);
497 if (!max || max > UINT16_MAX) {
498 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
502 t = realloc(plane->kern.formats, sizeof(*t) * max);
506 plane->kern.formats = t;
507 plane->kern.max_formats = max;
514 plane->kern.n_formats = res.count_format_types;
515 plane->kern.used_crtc = res.crtc_id;
516 plane->kern.used_fb = res.fb_id;
517 plane->kern.gamma_size = res.gamma_size;
522 if (tries >= GRDRM_MAX_TRIES) {
523 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
534 static void connector_free(grdrm_object *object) {
535 grdrm_connector *connector = connector_from_object(object);
537 free(connector->kern.prop_values);
538 free(connector->kern.prop_ids);
539 free(connector->kern.modes);
540 free(connector->kern.encoders);
544 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
545 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
546 grdrm_connector *connector;
551 connector = new0(grdrm_connector, 1);
555 object = &connector->object;
556 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
558 connector->kern.max_encoders = 32;
559 connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
560 if (!connector->kern.encoders)
563 connector->kern.max_modes = 32;
564 connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
565 if (!connector->kern.modes)
568 connector->kern.max_props = 32;
569 connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
570 connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
571 if (!connector->kern.prop_ids || !connector->kern.prop_values)
574 r = grdrm_object_add(object);
584 static int grdrm_connector_resync(grdrm_connector *connector) {
585 grdrm_card *card = connector->object.card;
591 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
592 struct drm_mode_get_connector res;
593 bool resized = false;
597 res.connector_id = connector->object.id;
598 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
599 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
600 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
601 res.count_encoders = connector->kern.max_encoders;
602 res.count_props = connector->kern.max_props;
604 /* Retrieve modes only if we have none. This avoids expensive
605 * EDID reads in the kernel, that can slow down resyncs
607 if (connector->kern.n_modes == 0) {
608 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
609 res.count_modes = connector->kern.max_modes;
612 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
616 card->async_hotplug = true;
618 log_debug("grdrm: %s: connector %u removed during resync", card->base.name, connector->object.id);
620 log_debug("grdrm: %s: cannot retrieve connector %u: %m", card->base.name, connector->object.id);
626 if (res.count_encoders > connector->kern.max_encoders) {
629 max = ALIGN_POWER2(res.count_encoders);
630 if (!max || max > UINT16_MAX) {
631 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
635 t = realloc(connector->kern.encoders, sizeof(*t) * max);
639 connector->kern.encoders = t;
640 connector->kern.max_encoders = max;
644 if (res.count_modes > connector->kern.max_modes) {
645 struct drm_mode_modeinfo *t;
647 max = ALIGN_POWER2(res.count_modes);
648 if (!max || max > UINT16_MAX) {
649 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
653 t = realloc(connector->kern.modes, sizeof(*t) * max);
657 connector->kern.modes = t;
658 connector->kern.max_modes = max;
662 if (res.count_props > connector->kern.max_props) {
666 max = ALIGN_POWER2(res.count_props);
667 if (!max || max > UINT16_MAX) {
668 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
672 tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
675 connector->kern.prop_ids = tids;
677 tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
680 connector->kern.prop_values = tvals;
682 connector->kern.max_props = max;
689 connector->kern.n_encoders = res.count_encoders;
690 connector->kern.n_modes = res.count_modes;
691 connector->kern.n_props = res.count_props;
692 connector->kern.type = res.connector_type;
693 connector->kern.type_id = res.connector_type_id;
694 connector->kern.used_encoder = res.encoder_id;
695 connector->kern.connection = res.connection;
696 connector->kern.mm_width = res.mm_width;
697 connector->kern.mm_height = res.mm_height;
698 connector->kern.subpixel = res.subpixel;
703 if (tries >= GRDRM_MAX_TRIES) {
704 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
715 static void encoder_free(grdrm_object *object) {
716 grdrm_encoder *encoder = encoder_from_object(object);
718 free(encoder->kern.clones);
719 free(encoder->kern.crtcs);
723 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
724 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
725 grdrm_encoder *encoder;
730 encoder = new0(grdrm_encoder, 1);
734 object = &encoder->object;
735 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
737 encoder->kern.max_crtcs = 32;
738 encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
739 if (!encoder->kern.crtcs)
742 encoder->kern.max_clones = 32;
743 encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
744 if (!encoder->kern.clones)
747 r = grdrm_object_add(object);
757 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
758 grdrm_card *card = encoder->object.card;
759 struct drm_mode_get_encoder res;
760 grdrm_object *object;
767 res.encoder_id = encoder->object.id;
769 r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
773 card->async_hotplug = true;
775 log_debug("grdrm: %s: encoder %u removed during resync", card->base.name, encoder->object.id);
777 log_debug("grdrm: %s: cannot retrieve encoder %u: %m", card->base.name, encoder->object.id);
783 encoder->kern.type = res.encoder_type;
784 encoder->kern.used_crtc = res.crtc_id;
786 encoder->kern.n_crtcs = 0;
787 memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
789 HASHMAP_FOREACH(object, card->object_map, iter) {
790 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
792 if (!(res.possible_crtcs & (1 << object->index)))
794 if (encoder->kern.n_crtcs >= 32) {
795 log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
799 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
802 encoder->kern.n_clones = 0;
803 memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
805 HASHMAP_FOREACH(object, card->object_map, iter) {
806 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
808 if (!(res.possible_clones & (1 << object->index)))
810 if (encoder->kern.n_clones >= 32) {
811 log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
815 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
825 static void crtc_free(grdrm_object *object) {
826 grdrm_crtc *crtc = crtc_from_object(object);
829 grdev_pipe_free(&crtc->pipe->base);
830 free(crtc->set.connectors);
831 free(crtc->old.connectors);
832 free(crtc->kern.used_connectors);
836 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
837 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
843 crtc = new0(grdrm_crtc, 1);
847 object = &crtc->object;
848 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
850 crtc->kern.max_used_connectors = 32;
851 crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
852 if (!crtc->kern.used_connectors)
855 crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
856 if (!crtc->old.connectors)
859 r = grdrm_object_add(object);
869 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
870 grdrm_card *card = crtc->object.card;
871 struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
876 /* make sure we can cache any combination later */
877 if (card->n_connectors > crtc->kern.max_used_connectors) {
880 max = ALIGN_POWER2(card->n_connectors);
884 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
888 crtc->kern.used_connectors = t;
889 crtc->kern.max_used_connectors = max;
891 if (!crtc->old.set) {
892 crtc->old.connectors = calloc(sizeof(*t), max);
893 if (!crtc->old.connectors)
898 /* GETCRTC doesn't return connectors. We have to read all
899 * encoder-state and deduce the setup ourselves.. */
900 crtc->kern.n_used_connectors = 0;
902 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
906 card->async_hotplug = true;
908 log_debug("grdrm: %s: crtc %u removed during resync", card->base.name, crtc->object.id);
910 log_debug("grdrm: %s: cannot retrieve crtc %u: %m", card->base.name, crtc->object.id);
916 crtc->kern.used_fb = res.fb_id;
917 crtc->kern.fb_offset_x = res.x;
918 crtc->kern.fb_offset_y = res.y;
919 crtc->kern.gamma_size = res.gamma_size;
920 crtc->kern.mode_set = res.mode_valid;
921 crtc->kern.mode = res.mode;
926 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
927 uint32_t n_connectors;
931 assert(!crtc->object.assigned);
932 assert(!connector || !connector->object.assigned);
934 /* always mark both as assigned; even if assignments cannot be set */
935 crtc->object.assigned = true;
937 connector->object.assigned = true;
939 /* we will support hw clone mode in the future */
940 n_connectors = connector ? 1 : 0;
942 /* bail out if configuration is preserved */
943 if (crtc->set.n_connectors == n_connectors &&
944 (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
947 crtc->applied = false;
948 crtc->set.n_connectors = 0;
950 if (n_connectors > crtc->set.max_connectors) {
953 max = ALIGN_POWER2(n_connectors);
959 t = realloc(crtc->set.connectors, sizeof(*t) * max);
965 crtc->set.connectors = t;
966 crtc->set.max_connectors = max;
970 struct drm_mode_modeinfo *m, *pref = NULL;
973 for (i = 0; i < connector->kern.n_modes; ++i) {
974 m = &connector->kern.modes[i];
976 /* ignore 3D modes by default */
977 if (m->flags & DRM_MODE_FLAG_3D_MASK)
985 /* use PREFERRED over non-PREFERRED */
986 if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
987 !(m->type & DRM_MODE_TYPE_PREFERRED))
990 /* use DRIVER over non-PREFERRED|DRIVER */
991 if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
992 !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
995 /* always prefer higher resolution */
996 if (pref->hdisplay > m->hdisplay ||
997 (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1004 crtc->set.mode = *pref;
1005 crtc->set.n_connectors = 1;
1006 crtc->set.connectors[0] = connector->object.id;
1007 log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1008 crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1010 log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1011 crtc->object.card->base.name, connector->object.id);
1018 log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1019 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1022 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1029 assert(crtc->object.assigned);
1031 if (crtc->set.n_connectors < 1) {
1033 grdev_pipe_free(&crtc->pipe->base);
1040 if (pipe->base.width != crtc->set.mode.hdisplay ||
1041 pipe->base.height != crtc->set.mode.vdisplay) {
1042 grdev_pipe_free(&pipe->base);
1049 pipe->base.front = NULL;
1050 pipe->base.back = NULL;
1051 for (i = 0; i < pipe->base.max_fbs; ++i) {
1052 fb = fb_from_base(pipe->base.fbs[i]);
1053 if (fb->id == crtc->kern.used_fb)
1054 pipe->base.front = &fb->base;
1055 else if (!fb->flipid)
1056 pipe->base.back = &fb->base;
1059 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1061 log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1062 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1066 for (i = 0; i < pipe->base.max_fbs; ++i) {
1067 r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1069 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1070 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1071 grdev_pipe_free(&pipe->base);
1075 pipe->base.fbs[i] = &fb->base;
1078 pipe->base.front = NULL;
1079 pipe->base.back = pipe->base.fbs[0];
1083 grdev_pipe_ready(&crtc->pipe->base, true);
1086 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
1087 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1088 grdrm_card *card = crtc->object.card;
1089 grdrm_pipe *pipe = crtc->pipe;
1090 grdrm_fb *fb = fb_from_base(*slot);
1099 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1100 set_crtc.count_connectors = crtc->set.n_connectors;
1101 set_crtc.fb_id = fb->id;
1104 set_crtc.mode_valid = 1;
1105 set_crtc.mode = crtc->set.mode;
1107 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1110 log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1111 card->base.name, crtc->object.id);
1113 grdrm_card_async(card, r);
1117 if (!crtc->applied) {
1118 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1119 card->base.name, crtc->object.id);
1120 crtc->applied = true;
1124 pipe->base.front = &fb->base;
1127 pipe->base.flipping = false;
1128 pipe->base.flip = false;
1130 if (!pipe->base.back) {
1131 for (i = 0; i < pipe->base.max_fbs; ++i) {
1132 if (!pipe->base.fbs[i])
1135 fb = fb_from_base(pipe->base.fbs[i]);
1136 if (&fb->base == pipe->base.front)
1140 pipe->base.back = &fb->base;
1146 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb **slot) {
1147 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1148 grdrm_card *card = crtc->object.card;
1149 grdrm_pipe *pipe = crtc->pipe;
1150 grdrm_fb *fb = fb_from_base(*slot);
1160 if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1163 cnt = ++pipe->counter ? : ++pipe->counter;
1164 page_flip.fb_id = fb->id;
1165 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1166 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1168 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1171 log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1172 card->base.name, crtc->object.id);
1174 if (grdrm_card_async(card, r))
1180 if (!crtc->applied) {
1181 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1182 card->base.name, crtc->object.id);
1183 crtc->applied = true;
1186 pipe->base.flipping = true;
1187 pipe->base.flip = false;
1188 pipe->counter = cnt;
1192 if (!pipe->base.back) {
1193 for (i = 0; i < pipe->base.max_fbs; ++i) {
1194 if (!pipe->base.fbs[i])
1197 fb = fb_from_base(pipe->base.fbs[i]);
1198 if (&fb->base == pipe->base.front)
1203 pipe->base.back = &fb->base;
1211 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1212 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1213 grdrm_card *card = crtc->object.card;
1219 assert(crtc->object.assigned);
1223 /* If a crtc is not assigned any connector, we want any
1224 * previous setup to be cleared, so make sure the CRTC is
1225 * disabled. Otherwise, there might be content on the CRTC
1226 * while we run, which is not what we want.
1227 * If you want to avoid modesets on specific CRTCs, you should
1228 * still keep their assignment, but never enable the resulting
1229 * pipe. This way, we wouldn't touch it at all. */
1230 if (!crtc->applied) {
1231 crtc->applied = true;
1232 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1235 log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1236 card->base.name, crtc->object.id);
1238 grdrm_card_async(card, r);
1242 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1243 card->base.name, crtc->object.id);
1249 /* we always fully ignore disabled pipes */
1250 if (!pipe->base.enabled)
1253 assert(crtc->set.n_connectors > 0);
1255 if (pipe->base.flip)
1256 slot = &pipe->base.back;
1257 else if (!crtc->applied)
1258 slot = &pipe->base.front;
1265 r = grdrm_crtc_commit_flip(crtc, slot);
1267 /* in case we couldn't page-flip, perform deep modeset */
1268 grdrm_crtc_commit_deep(crtc, slot);
1272 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1273 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1274 grdrm_card *card = crtc->object.card;
1280 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1281 set_crtc.count_connectors = crtc->old.n_connectors;
1282 set_crtc.fb_id = crtc->old.fb;
1283 set_crtc.x = crtc->old.fb_x;
1284 set_crtc.y = crtc->old.fb_y;
1285 set_crtc.gamma_size = crtc->old.gamma;
1286 set_crtc.mode_valid = crtc->old.mode_set;
1287 set_crtc.mode = crtc->old.mode;
1289 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1292 log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1293 card->base.name, crtc->object.id);
1295 grdrm_card_async(card, r);
1300 ++crtc->pipe->counter;
1301 crtc->pipe->base.front = NULL;
1302 crtc->pipe->base.flipping = false;
1305 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1308 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1309 bool flipped = false;
1311 grdrm_fb *back = NULL;
1321 /* We got a page-flip event. To be safe, we reset all FBs on the same
1322 * pipe that have smaller flipids than the flip we got as we know they
1323 * are executed in order. We need to do this to guarantee
1324 * queue-overflows or other missed events don't cause starvation.
1325 * Furthermore, if we find the exact FB this event is for, *and* this
1326 * is the most recent event, we mark it as front FB and raise a
1329 for (i = 0; i < pipe->base.max_fbs; ++i) {
1332 if (!pipe->base.fbs[i])
1335 fb = fb_from_base(pipe->base.fbs[i]);
1336 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1337 pipe->base.front = &fb->base;
1341 if (counter - fb->flipid < UINT16_MAX) {
1344 } else if (fb->flipid == 0) {
1349 if (!pipe->base.back)
1350 pipe->base.back = &back->base;
1353 crtc->pipe->base.flipping = false;
1354 grdev_pipe_frame(&pipe->base);
1362 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1363 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1364 struct drm_mode_create_dumb create_dumb = { };
1365 struct drm_mode_map_dumb map_dumb = { };
1366 struct drm_mode_fb_cmd2 add_fb = { };
1370 assert_return(out, -EINVAL);
1371 assert_return(card, -EINVAL);
1373 fb = new0(grdrm_fb, 1);
1377 /* TODO: we should choose a compatible format of the previous CRTC
1378 * setting to allow page-flip to it. Only choose fallback if the
1379 * previous setting was crap (non xrgb32'ish). */
1382 fb->base.format = DRM_FORMAT_XRGB8888;
1383 fb->base.width = mode->hdisplay;
1384 fb->base.height = mode->vdisplay;
1386 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1387 fb->base.maps[i] = MAP_FAILED;
1389 create_dumb.width = fb->base.width;
1390 create_dumb.height = fb->base.height;
1391 create_dumb.bpp = 32;
1393 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1396 log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1397 card->base.name, fb->base.width, fb->base.height);
1401 fb->handles[0] = create_dumb.handle;
1402 fb->base.strides[0] = create_dumb.pitch;
1403 fb->sizes[0] = create_dumb.size;
1405 map_dumb.handle = fb->handles[0];
1407 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1410 log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1411 card->base.name, fb->base.width, fb->base.height);
1415 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1416 if (fb->base.maps[0] == MAP_FAILED) {
1418 log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1419 card->base.name, fb->base.width, fb->base.height);
1423 memzero(fb->base.maps[0], fb->sizes[0]);
1425 add_fb.width = fb->base.width;
1426 add_fb.height = fb->base.height;
1427 add_fb.pixel_format = fb->base.format;
1429 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1430 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1431 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1433 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1436 log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1437 card->base.name, fb->base.width, fb->base.height);
1441 fb->id = add_fb.fb_id;
1448 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1456 if (fb->id > 0 && fb->card->fd >= 0)
1457 ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1459 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1460 struct drm_mode_destroy_dumb destroy_dumb = { };
1462 if (fb->base.maps[i] != MAP_FAILED)
1463 munmap(fb->base.maps[i], fb->sizes[i]);
1465 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1466 destroy_dumb.handle = fb->handles[i];
1467 ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1480 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1481 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1482 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1485 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1486 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1487 grdrm_card *card = crtc->object.card;
1488 char name[GRDRM_PIPE_NAME_MAX];
1492 assert_return(crtc, -EINVAL);
1493 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1495 pipe = new0(grdrm_pipe, 1);
1499 basepipe = &pipe->base;
1500 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1502 pipe->base.width = mode->hdisplay;
1503 pipe->base.height = mode->vdisplay;
1505 grdrm_pipe_name(name, crtc);
1506 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1516 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1517 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1522 for (i = 0; i < pipe->base.max_fbs; ++i)
1523 if (pipe->base.fbs[i])
1524 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1529 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1530 .free = grdrm_pipe_free,
1537 static void grdrm_name(char *out, dev_t devnum) {
1538 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1539 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1542 static void grdrm_card_print(grdrm_card *card) {
1543 grdrm_object *object;
1545 grdrm_encoder *encoder;
1546 grdrm_connector *connector;
1552 log_debug("grdrm: %s: state dump", card->base.name);
1554 log_debug(" crtcs:");
1555 HASHMAP_FOREACH(object, card->object_map, iter) {
1556 if (object->type != GRDRM_TYPE_CRTC)
1559 crtc = crtc_from_object(object);
1560 log_debug(" (id: %u index: %d)", object->id, object->index);
1562 if (crtc->kern.mode_set)
1563 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1565 log_debug(" mode: <none>");
1568 log_debug(" encoders:");
1569 HASHMAP_FOREACH(object, card->object_map, iter) {
1570 if (object->type != GRDRM_TYPE_ENCODER)
1573 encoder = encoder_from_object(object);
1574 log_debug(" (id: %u index: %d)", object->id, object->index);
1576 if (encoder->kern.used_crtc)
1577 log_debug(" crtc: %u", encoder->kern.used_crtc);
1579 log_debug(" crtc: <none>");
1581 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1586 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1587 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1589 log_debug(" possible crtcs:%s", buf);
1593 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1598 for (i = 0; i < encoder->kern.n_clones; ++i)
1599 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1601 log_debug(" possible clones:%s", buf);
1606 log_debug(" connectors:");
1607 HASHMAP_FOREACH(object, card->object_map, iter) {
1608 if (object->type != GRDRM_TYPE_CONNECTOR)
1611 connector = connector_from_object(object);
1612 log_debug(" (id: %u index: %d)", object->id, object->index);
1613 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1614 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1615 connector->kern.mm_width, connector->kern.mm_height);
1617 if (connector->kern.used_encoder)
1618 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1620 log_debug(" encoder: <none>");
1622 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1627 for (i = 0; i < connector->kern.n_encoders; ++i)
1628 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1630 log_debug(" possible encoders:%s", buf);
1634 for (i = 0; i < connector->kern.n_modes; ++i) {
1635 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1636 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1640 log_debug(" planes:");
1641 HASHMAP_FOREACH(object, card->object_map, iter) {
1642 if (object->type != GRDRM_TYPE_PLANE)
1645 plane = plane_from_object(object);
1646 log_debug(" (id: %u index: %d)", object->id, object->index);
1647 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1649 if (plane->kern.used_crtc)
1650 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1652 log_debug(" crtc: <none>");
1654 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1659 for (i = 0; i < plane->kern.n_crtcs; ++i)
1660 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1662 log_debug(" possible crtcs:%s", buf);
1666 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1671 for (i = 0; i < plane->kern.n_formats; ++i)
1672 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1674 log_debug(" possible formats:%s", buf);
1680 static int grdrm_card_resync(grdrm_card *card) {
1681 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1682 uint32_t allocated = 0;
1683 grdrm_object *object;
1690 card->async_hotplug = false;
1693 /* mark existing objects for possible removal */
1694 HASHMAP_FOREACH(object, card->object_map, iter)
1695 object->present = false;
1697 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1698 struct drm_mode_get_plane_res pres;
1699 struct drm_mode_card_res res;
1702 if (allocated < card->max_ids) {
1705 free(connector_ids);
1707 crtc_ids = new0(uint32_t, card->max_ids);
1708 encoder_ids = new0(uint32_t, card->max_ids);
1709 connector_ids = new0(uint32_t, card->max_ids);
1710 plane_ids = new0(uint32_t, card->max_ids);
1712 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1715 allocated = card->max_ids;
1719 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1720 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1721 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1722 res.count_crtcs = allocated;
1723 res.count_encoders = allocated;
1724 res.count_connectors = allocated;
1726 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1729 log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
1734 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1735 pres.count_planes = allocated;
1737 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1740 log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
1744 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1745 MAX(res.count_connectors, pres.count_planes));
1746 if (max > allocated) {
1749 n = ALIGN_POWER2(max);
1750 if (!n || n > UINT16_MAX) {
1751 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
1755 /* retry with resized buffers */
1760 /* mark available objects as present */
1762 for (i = 0; i < res.count_crtcs; ++i) {
1763 object = grdrm_find_object(card, crtc_ids[i]);
1764 if (object && object->type == GRDRM_TYPE_CRTC) {
1765 object->present = true;
1771 for (i = 0; i < res.count_encoders; ++i) {
1772 object = grdrm_find_object(card, encoder_ids[i]);
1773 if (object && object->type == GRDRM_TYPE_ENCODER) {
1774 object->present = true;
1780 for (i = 0; i < res.count_connectors; ++i) {
1781 object = grdrm_find_object(card, connector_ids[i]);
1782 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1783 object->present = true;
1785 connector_ids[i] = 0;
1789 for (i = 0; i < pres.count_planes; ++i) {
1790 object = grdrm_find_object(card, plane_ids[i]);
1791 if (object && object->type == GRDRM_TYPE_PLANE) {
1792 object->present = true;
1798 /* drop removed objects */
1800 HASHMAP_FOREACH(object, card->object_map, iter)
1801 if (!object->present)
1802 grdrm_object_free(object);
1804 /* add new objects */
1806 card->n_crtcs = res.count_crtcs;
1807 for (i = 0; i < res.count_crtcs; ++i) {
1808 if (crtc_ids[i] < 1)
1811 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1816 card->n_encoders = res.count_encoders;
1817 for (i = 0; i < res.count_encoders; ++i) {
1818 if (encoder_ids[i] < 1)
1821 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1826 card->n_connectors = res.count_connectors;
1827 for (i = 0; i < res.count_connectors; ++i) {
1828 if (connector_ids[i] < 1)
1831 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1836 card->n_planes = pres.count_planes;
1837 for (i = 0; i < pres.count_planes; ++i) {
1838 if (plane_ids[i] < 1)
1841 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1846 /* re-sync objects after object_map is synced */
1848 HASHMAP_FOREACH(object, card->object_map, iter) {
1849 switch (object->type) {
1850 case GRDRM_TYPE_CRTC:
1851 r = grdrm_crtc_resync(crtc_from_object(object));
1853 case GRDRM_TYPE_ENCODER:
1854 r = grdrm_encoder_resync(encoder_from_object(object));
1856 case GRDRM_TYPE_CONNECTOR:
1857 r = grdrm_connector_resync(connector_from_object(object));
1859 case GRDRM_TYPE_PLANE:
1860 r = grdrm_plane_resync(plane_from_object(object));
1863 assert_not_reached("grdrm: invalid object type");
1870 if (card->async_hotplug)
1874 /* if modeset objects change during sync, start over */
1875 if (card->async_hotplug) {
1876 card->async_hotplug = false;
1880 /* cache crtc/connector relationship */
1881 HASHMAP_FOREACH(object, card->object_map, iter) {
1882 grdrm_connector *connector;
1883 grdrm_encoder *encoder;
1886 if (object->type != GRDRM_TYPE_CONNECTOR)
1889 connector = connector_from_object(object);
1890 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1893 object = grdrm_find_object(card, connector->kern.used_encoder);
1894 if (!object || object->type != GRDRM_TYPE_ENCODER)
1897 encoder = encoder_from_object(object);
1898 if (encoder->kern.used_crtc < 1)
1901 object = grdrm_find_object(card, encoder->kern.used_crtc);
1902 if (!object || object->type != GRDRM_TYPE_CRTC)
1905 crtc = crtc_from_object(object);
1906 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1907 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1910 /* cache old crtc settings for later restore */
1911 HASHMAP_FOREACH(object, card->object_map, iter) {
1914 if (object->type != GRDRM_TYPE_CRTC)
1917 crtc = crtc_from_object(object);
1919 /* Save data if it is the first time we refresh the CRTC. This data can
1920 * be used optionally to restore any previous configuration. For
1921 * instance, it allows us to restore VT configurations after we close
1922 * our session again. */
1923 if (!crtc->old.set) {
1924 crtc->old.fb = crtc->kern.used_fb;
1925 crtc->old.fb_x = crtc->kern.fb_offset_x;
1926 crtc->old.fb_y = crtc->kern.fb_offset_y;
1927 crtc->old.gamma = crtc->kern.gamma_size;
1928 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1929 if (crtc->old.n_connectors)
1930 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1931 crtc->old.mode_set = crtc->kern.mode_set;
1932 crtc->old.mode = crtc->kern.mode;
1933 crtc->old.set = true;
1937 /* everything synced */
1941 if (tries >= GRDRM_MAX_TRIES) {
1943 * Ugh! We were unable to sync the DRM card state due to heavy
1944 * hotplugging. This should never happen, so print a debug
1945 * message and bail out. The next uevent will trigger
1949 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
1956 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
1957 grdrm_card *card = crtc->object.card;
1958 grdrm_encoder *encoder;
1959 grdrm_object *object;
1962 if (crtc->object.assigned || connector->object.assigned)
1964 if (connector->kern.connection != 1)
1967 for (i = 0; i < connector->kern.n_encoders; ++i) {
1968 object = grdrm_find_object(card, connector->kern.encoders[i]);
1969 if (!object || object->type != GRDRM_TYPE_ENCODER)
1972 encoder = encoder_from_object(object);
1973 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
1974 if (encoder->kern.crtcs[j] == crtc->object.id) {
1975 grdrm_crtc_assign(crtc, connector);
1984 static void grdrm_card_configure(grdrm_card *card) {
1986 * Modeset Configuration
1987 * This is where we update our modeset configuration and assign
1988 * connectors to CRTCs. This means, each connector that we want to
1989 * enable needs a CRTC, disabled (or unavailable) connectors are left
1990 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
1992 * Sounds trivial, but there're several caveats:
1994 * * Multiple connectors can be driven by the same CRTC. This is
1995 * known as 'hardware clone mode'. Advantage over software clone
1996 * mode is that only a single CRTC is needed to drive multiple
1997 * displays. However, few hardware supports this and it's a huge
1998 * headache to configure on dynamic demands. Therefore, we only
1999 * support it if configured statically beforehand.
2001 * * CRTCs are not created equal. Some might be much more poweful
2002 * than others, including more advanced plane support. So far, our
2003 * CRTC selection is random. You need to supply static
2004 * configuration if you want special setups. So far, there is no
2005 * proper way to do advanced CRTC selection on dynamic demands. It
2006 * is not really clear which demands require what CRTC, so, like
2007 * everyone else, we do random CRTC selection unless explicitly
2010 * * Each Connector has a list of possible encoders that can drive
2011 * it, and each encoder has a list of possible CRTCs. If this graph
2012 * is a tree, assignment is trivial. However, if not, we cannot
2013 * reliably decide on configurations beforehand. The encoder is
2014 * always selected by the kernel, so we have to actually set a mode
2015 * to know which encoder is used. There is no way to ask the kernel
2016 * whether a given configuration is possible. This will change with
2017 * atomic-modesetting, but until then, we keep our configurations
2018 * simple and assume they work all just fine. If one fails
2019 * unexpectedly, we print a warning and disable it.
2021 * Configuring a card consists of several steps:
2023 * 1) First of all, we apply any user-configuration. If a user wants
2024 * a fixed configuration, we apply it and preserve it.
2025 * So far, we don't support user configuration files, so this step
2028 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
2029 * might only support limited configurations or require special
2030 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2032 * So far, we don't support this as there is no known quirk, so
2033 * this step is skipped.
2035 * 3) As deep modesets are expensive, we try to avoid them if
2036 * possible. Therefore, we read the current configuration from the
2037 * kernel and try to preserve it, if compatible with our demands.
2038 * If not, we break it and reassign it in a following step.
2040 * 4) The main step involves configuring all remaining objects. By
2041 * default, all available connectors are enabled, except for those
2042 * disabled by user-configuration. We lookup a suitable CRTC for
2043 * each connector and assign them. As there might be more
2044 * connectors than CRTCs, we apply some ordering so users can
2045 * select which connectors are more important right now.
2046 * So far, we only apply the default ordering, more might be added
2050 grdrm_object *object;
2054 /* clear assignments */
2055 HASHMAP_FOREACH(object, card->object_map, i)
2056 object->assigned = false;
2058 /* preserve existing configurations */
2059 HASHMAP_FOREACH(object, card->object_map, i) {
2060 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2063 crtc = crtc_from_object(object);
2065 if (crtc->applied) {
2066 /* If our mode is set, preserve it. If no connector is
2067 * set, modeset either failed or the pipe is unused. In
2068 * both cases, leave it alone. It might be tried again
2069 * below in case there're remaining connectors.
2070 * Otherwise, try restoring the assignments. If they
2071 * are no longer valid, leave the pipe untouched. */
2073 if (crtc->set.n_connectors < 1)
2076 assert(crtc->set.n_connectors == 1);
2078 object = grdrm_find_object(card, crtc->set.connectors[0]);
2079 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2082 card_configure_crtc(crtc, connector_from_object(object));
2083 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2084 /* If our mode is not set on the pipe, we know the kern
2085 * information is valid. Try keeping it. If it's not
2086 * possible, leave the pipe untouched for later
2089 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2090 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2093 card_configure_crtc(crtc, connector_from_object(object));
2097 /* assign remaining objects */
2098 HASHMAP_FOREACH(object, card->object_map, i) {
2099 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2102 crtc = crtc_from_object(object);
2104 HASHMAP_FOREACH(object, card->object_map, j) {
2105 if (object->type != GRDRM_TYPE_CONNECTOR)
2108 if (card_configure_crtc(crtc, connector_from_object(object)))
2112 if (!crtc->object.assigned)
2113 grdrm_crtc_assign(crtc, NULL);
2116 /* expose configuration */
2117 HASHMAP_FOREACH(object, card->object_map, i) {
2118 if (object->type != GRDRM_TYPE_CRTC)
2121 grdrm_crtc_expose(crtc_from_object(object));
2125 static void grdrm_card_hotplug(grdrm_card *card) {
2133 card->ready = false;
2134 r = grdrm_card_resync(card);
2136 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2137 card->base.session->name, card->base.name, strerror(-r));
2141 grdev_session_pin(card->base.session);
2143 grdrm_card_print(card);
2144 grdrm_card_configure(card);
2147 grdev_session_unpin(card->base.session);
2150 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2151 grdrm_card *card = userdata;
2152 struct drm_event_vblank *vblank;
2153 struct drm_event *event;
2154 uint32_t id, counter;
2155 grdrm_object *object;
2159 if (revents & (EPOLLHUP | EPOLLERR)) {
2160 /* Immediately close device on HUP; no need to flush pending
2161 * data.. there're no events we care about here. */
2162 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2163 grdrm_card_close(card);
2167 if (revents & (EPOLLIN)) {
2168 l = read(card->fd, buf, sizeof(buf));
2170 if (errno == EAGAIN || errno == EINTR)
2173 log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2174 grdrm_card_close(card);
2176 } else if ((size_t)l < sizeof(*event)) {
2177 log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l);
2181 for (i = 0; i < l; i += event->length) {
2182 event = (void*)&buf[i];
2184 if (i + event->length > l) {
2185 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2189 switch (event->type) {
2190 case DRM_EVENT_FLIP_COMPLETE:
2191 vblank = (void*)event;
2192 if (event->length < sizeof(*vblank)) {
2193 log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2197 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2198 object = grdrm_find_object(card, id);
2199 if (!object || object->type != GRDRM_TYPE_CRTC)
2202 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2211 static int grdrm_card_add(grdrm_card *card, const char *name) {
2213 assert(card->fd < 0);
2215 card->object_map = hashmap_new(&trivial_hash_ops);
2216 if (!card->object_map)
2219 return grdev_card_add(&card->base, name);
2222 static void grdrm_card_destroy(grdrm_card *card) {
2224 assert(!card->running);
2225 assert(card->fd < 0);
2226 assert(hashmap_size(card->object_map) == 0);
2228 hashmap_free(card->object_map);
2231 static void grdrm_card_commit(grdev_card *basecard) {
2232 grdrm_card *card = grdrm_card_from_base(basecard);
2233 grdrm_object *object;
2236 HASHMAP_FOREACH(object, card->object_map, iter) {
2240 if (object->type != GRDRM_TYPE_CRTC)
2243 grdrm_crtc_commit(crtc_from_object(object));
2247 static void grdrm_card_restore(grdev_card *basecard) {
2248 grdrm_card *card = grdrm_card_from_base(basecard);
2249 grdrm_object *object;
2252 HASHMAP_FOREACH(object, card->object_map, iter) {
2256 if (object->type != GRDRM_TYPE_CRTC)
2259 grdrm_crtc_restore(crtc_from_object(object));
2263 static void grdrm_card_enable(grdrm_card *card) {
2266 if (card->fd < 0 || card->running)
2269 /* ignore cards without DUMB_BUFFER capability */
2270 if (!card->cap_dumb)
2273 assert(card->fd_src);
2275 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2277 card->running = true;
2278 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2279 grdrm_card_hotplug(card);
2282 static void grdrm_card_disable(grdrm_card *card) {
2283 grdrm_object *object;
2288 if (card->fd < 0 || !card->running)
2291 assert(card->fd_src);
2293 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2295 card->running = false;
2296 card->ready = false;
2297 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2299 /* stop all pipes */
2300 HASHMAP_FOREACH(object, card->object_map, iter) {
2303 if (object->type != GRDRM_TYPE_CRTC)
2306 crtc = crtc_from_object(object);
2307 crtc->applied = false;
2309 grdev_pipe_ready(&crtc->pipe->base, false);
2313 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2314 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2315 _cleanup_close_ int fd = dev_fd;
2316 struct drm_get_cap cap;
2320 assert(dev_fd >= 0);
2321 assert(card->fd != dev_fd);
2323 pin = grdev_session_pin(card->base.session);
2324 grdrm_card_close(card);
2326 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2328 r = fd_nonblock(fd, true);
2332 r = fd_cloexec(fd, true);
2336 flags = fcntl(fd, F_GETFL, 0);
2339 if ((flags & O_ACCMODE) != O_RDWR)
2342 r = sd_event_add_io(card->base.session->context->event,
2345 EPOLLHUP | EPOLLERR | EPOLLIN,
2351 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2356 /* cache DUMB_BUFFER capability */
2357 cap.capability = DRM_CAP_DUMB_BUFFER;
2359 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2360 card->cap_dumb = r >= 0 && cap.value;
2362 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2363 card->base.session->name, card->base.name, strerror(-r));
2364 else if (!card->cap_dumb)
2365 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2366 card->base.session->name, card->base.name);
2368 /* cache TIMESTAMP_MONOTONIC capability */
2369 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2371 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2372 card->cap_monotonic = r >= 0 && cap.value;
2374 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2375 card->base.session->name, card->base.name, strerror(-r));
2376 else if (!card->cap_monotonic)
2377 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2378 card->base.session->name, card->base.name);
2383 static void grdrm_card_close(grdrm_card *card) {
2384 grdrm_object *object;
2389 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2391 grdrm_card_disable(card);
2393 card->fd_src = sd_event_source_unref(card->fd_src);
2394 card->fd = safe_close(card->fd);
2396 grdev_session_pin(card->base.session);
2397 while ((object = hashmap_first(card->object_map)))
2398 grdrm_object_free(object);
2399 grdev_session_unpin(card->base.session);
2402 static bool grdrm_card_async(grdrm_card *card, int r) {
2405 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2406 * (or we did something terribly wrong). Immediately disable
2407 * the card, so we stop all pipes and wait to be activated
2409 grdrm_card_disable(card);
2412 /* DRM objects can be hotplugged at any time. If an object is
2413 * removed that we use, we remember that state so a following
2414 * call can test for this.
2415 * Note that we also get a uevent as followup, this will resync
2416 * the whole device. */
2417 card->async_hotplug = true;
2421 return !card->ready;
2426 * The unmanaged DRM card opens the device node for a given DRM device
2427 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2428 * the device only if we really require it and releases it as soon as we're
2429 * disabled or closed.
2430 * The unmanaged element can be used in all situations where you have direct
2431 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2432 * outside of user sessions and in emergency situations where logind is not
2436 static void unmanaged_card_enable(grdev_card *basecard) {
2437 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2440 if (cu->card.fd < 0) {
2441 /* try open on activation if it failed during allocation */
2442 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2444 /* not fatal; simply ignore the device */
2445 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2446 basecard->session->name, basecard->name, cu->devnode);
2450 /* we might already be DRM-Master by open(); that's fine */
2452 r = grdrm_card_open(&cu->card, fd);
2454 log_debug("grdrm: %s/%s: cannot open: %s",
2455 basecard->session->name, basecard->name, strerror(-r));
2460 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2462 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2463 basecard->session->name, basecard->name);
2467 grdrm_card_enable(&cu->card);
2470 static void unmanaged_card_disable(grdev_card *basecard) {
2471 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2473 grdrm_card_disable(&cu->card);
2476 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2477 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2478 char name[GRDRM_CARD_NAME_MAX];
2480 const char *devnode;
2484 assert_return(session, -EINVAL);
2485 assert_return(ud, -EINVAL);
2487 devnode = udev_device_get_devnode(ud);
2488 devnum = udev_device_get_devnum(ud);
2489 if (!devnode || devnum == 0)
2492 grdrm_name(name, devnum);
2494 cu = new0(unmanaged_card, 1);
2498 basecard = &cu->card.base;
2499 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2501 cu->devnode = strdup(devnode);
2505 r = grdrm_card_add(&cu->card, name);
2509 /* try to open but ignore errors */
2510 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2512 /* not fatal; allow uaccess based control on activation */
2513 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2514 basecard->session->name, basecard->name, cu->devnode);
2516 /* We might get DRM-Master implicitly on open(); drop it immediately
2517 * so we acquire it only once we're actually enabled. */
2518 ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2520 r = grdrm_card_open(&cu->card, fd);
2522 log_debug("grdrm: %s/%s: cannot open: %s",
2523 basecard->session->name, basecard->name, strerror(-r));
2532 static void unmanaged_card_free(grdev_card *basecard) {
2533 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2535 assert(!basecard->enabled);
2537 grdrm_card_close(&cu->card);
2538 grdrm_card_destroy(&cu->card);
2543 static const grdev_card_vtable unmanaged_card_vtable = {
2544 .free = unmanaged_card_free,
2545 .enable = unmanaged_card_enable,
2546 .disable = unmanaged_card_disable,
2547 .commit = grdrm_card_commit,
2548 .restore = grdrm_card_restore,
2553 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2554 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2555 * logind passes us a file-descriptor whenever our session is activated. Thus,
2556 * we don't need access to the device node directly.
2557 * Furthermore, whenever the session is put asleep, logind revokes the
2558 * file-descriptor so we loose access to the device.
2559 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2560 * you run inside a user session with exclusive device access.
2563 static void managed_card_enable(grdev_card *card) {
2564 managed_card *cm = managed_card_from_base(card);
2566 /* If the device is manually re-enabled, we try to resume our card
2567 * management. Note that we have no control over DRM-Master and the fd,
2568 * so we have to take over the state from the last logind event. */
2571 grdrm_card_enable(&cm->card);
2574 static void managed_card_disable(grdev_card *card) {
2575 managed_card *cm = managed_card_from_base(card);
2577 /* If the device is manually disabled, we keep the FD but put our card
2578 * management asleep. This way, we can wake up at any time, but don't
2579 * touch the device while asleep. */
2581 grdrm_card_disable(&cm->card);
2584 static int managed_card_pause_device_fn(sd_bus *bus,
2585 sd_bus_message *signal,
2587 sd_bus_error *ret_error) {
2588 managed_card *cm = userdata;
2589 grdev_session *session = cm->card.base.session;
2590 uint32_t major, minor;
2595 * We get PauseDevice() signals from logind whenever a device we
2596 * requested was, or is about to be, paused. Arguments are major/minor
2597 * number of the device and the mode of the operation.
2598 * In case the event is not about our device, we ignore it. Otherwise,
2599 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2600 * already handled an EACCES error from a modeset ioctl, in which case
2601 * we already disabled the device.
2603 * @mode can be one of the following:
2604 * "pause": The device is about to be paused. We must react
2605 * immediately and respond with PauseDeviceComplete(). Once
2606 * we replied, logind will pause the device. Note that
2607 * logind might apply any kind of timeout and force pause
2608 * the device if we don't respond in a timely manner. In
2609 * this case, we will receive a second PauseDevice event
2610 * with @mode set to "force" (or similar).
2611 * "force": The device was disabled forecfully by logind. DRM-Master
2612 * was already dropped. This is just an asynchronous
2613 * notification so we can put the device asleep (in case
2614 * we didn't already notice the dropped DRM-Master).
2615 * "gone": This is like "force" but is sent if the device was
2616 * paused due to a device-removal event.
2618 * We always handle PauseDevice signals as "force" as we properly
2619 * support asynchronously dropping DRM-Master, anyway. But in case
2620 * logind sent mode "pause", we also call PauseDeviceComplete() to
2621 * immediately acknowledge the request.
2624 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2626 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2627 session->name, cm->card.base.name);
2631 /* not our device? */
2632 if (makedev(major, minor) != cm->devnum)
2636 grdrm_card_disable(&cm->card);
2638 if (streq(mode, "pause")) {
2639 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2642 * Sending PauseDeviceComplete() is racy if logind triggers the
2643 * timeout. That is, if we take too long and logind pauses the
2644 * device by sending a forced PauseDevice, our
2645 * PauseDeviceComplete call will be stray. That's fine, though.
2646 * logind ignores such stray calls. Only if logind also sent a
2647 * further PauseDevice() signal, it might match our call
2648 * incorrectly to the newer PauseDevice(). That's fine, too, as
2649 * we handle that event asynchronously, anyway. Therefore,
2650 * whatever happens, we're fine. Yay!
2653 r = sd_bus_message_new_method_call(session->context->sysbus,
2655 "org.freedesktop.login1",
2657 "org.freedesktop.login1.Session",
2658 "PauseDeviceComplete");
2660 r = sd_bus_message_append(m, "uu", major, minor);
2662 r = sd_bus_send(session->context->sysbus, m, NULL);
2666 log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2667 session->name, cm->card.base.name, strerror(-r));
2673 static int managed_card_resume_device_fn(sd_bus *bus,
2674 sd_bus_message *signal,
2676 sd_bus_error *ret_error) {
2677 managed_card *cm = userdata;
2678 grdev_session *session = cm->card.base.session;
2679 uint32_t major, minor;
2683 * We get ResumeDevice signals whenever logind resumed a previously
2684 * paused device. The arguments contain the major/minor number of the
2685 * related device and a new file-descriptor for the freshly opened
2687 * If the signal is not about our device, we simply ignore it.
2688 * Otherwise, we immediately resume the device. Note that we drop the
2689 * new file-descriptor as we already have one from TakeDevice(). logind
2690 * preserves the file-context across pause/resume for DRM but only
2691 * drops/acquires DRM-Master accordingly. This way, our context (like
2692 * DRM-FBs and BOs) is preserved.
2695 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2697 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2698 session->name, cm->card.base.name);
2702 /* not our device? */
2703 if (makedev(major, minor) != cm->devnum)
2706 if (cm->card.fd < 0) {
2707 /* This shouldn't happen. We should already own an FD from
2708 * TakeDevice(). However, lets be safe and use this FD in case
2709 * we really don't have one. There is no harm in doing this
2710 * and our code works fine this way. */
2711 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2713 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2714 session->name, cm->card.base.name);
2718 r = grdrm_card_open(&cm->card, fd);
2720 log_debug("grdrm: %s/%s: cannot open: %s",
2721 session->name, cm->card.base.name, strerror(-r));
2727 if (cm->card.base.enabled)
2728 grdrm_card_enable(&cm->card);
2733 static int managed_card_setup_bus(managed_card *cm) {
2734 grdev_session *session = cm->card.base.session;
2735 _cleanup_free_ char *match = NULL;
2738 match = strjoin("type='signal',"
2739 "sender='org.freedesktop.login1',"
2740 "interface='org.freedesktop.login1.Session',"
2741 "member='PauseDevice',"
2742 "path='", session->path, "'",
2747 r = sd_bus_add_match(session->context->sysbus,
2748 &cm->slot_pause_device,
2750 managed_card_pause_device_fn,
2756 match = strjoin("type='signal',"
2757 "sender='org.freedesktop.login1',"
2758 "interface='org.freedesktop.login1.Session',"
2759 "member='ResumeDevice',"
2760 "path='", session->path, "'",
2765 r = sd_bus_add_match(session->context->sysbus,
2766 &cm->slot_resume_device,
2768 managed_card_resume_device_fn,
2776 static int managed_card_take_device_fn(sd_bus *bus,
2777 sd_bus_message *reply,
2779 sd_bus_error *ret_error) {
2780 managed_card *cm = userdata;
2781 grdev_session *session = cm->card.base.session;
2784 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2786 if (sd_bus_message_is_method_error(reply, NULL)) {
2787 const sd_bus_error *error = sd_bus_message_get_error(reply);
2789 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2790 session->name, cm->card.base.name, error->name, error->message);
2794 cm->acquired = true;
2796 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2798 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2799 session->name, cm->card.base.name);
2803 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2805 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2806 session->name, cm->card.base.name);
2810 r = grdrm_card_open(&cm->card, fd);
2812 log_debug("grdrm: %s/%s: cannot open: %s",
2813 session->name, cm->card.base.name, strerror(-r));
2817 if (!paused && cm->card.base.enabled)
2818 grdrm_card_enable(&cm->card);
2823 static void managed_card_take_device(managed_card *cm) {
2824 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2825 grdev_session *session = cm->card.base.session;
2828 r = sd_bus_message_new_method_call(session->context->sysbus,
2830 "org.freedesktop.login1",
2832 "org.freedesktop.login1.Session",
2837 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2841 r = sd_bus_call_async(session->context->sysbus,
2842 &cm->slot_take_device,
2844 managed_card_take_device_fn,
2850 cm->requested = true;
2854 log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2855 session->name, cm->card.base.name, strerror(-r));
2858 static void managed_card_release_device(managed_card *cm) {
2859 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2860 grdev_session *session = cm->card.base.session;
2864 * If TakeDevice() is pending or was successful, make sure to
2865 * release the device again. We don't care for return-values,
2866 * so send it without waiting or callbacks.
2867 * If a failed TakeDevice() is pending, but someone else took
2868 * the device on the same bus-connection, we might incorrectly
2869 * release their device. This is an unlikely race, though.
2870 * Furthermore, you really shouldn't have two users of the
2871 * controller-API on the same session, on the same devices, *AND* on
2872 * the same bus-connection. So we don't care for that race..
2875 grdrm_card_close(&cm->card);
2876 cm->requested = false;
2878 if (!cm->acquired && !cm->slot_take_device)
2881 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2882 cm->acquired = false;
2884 r = sd_bus_message_new_method_call(session->context->sysbus,
2886 "org.freedesktop.login1",
2888 "org.freedesktop.login1.Session",
2891 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2893 r = sd_bus_send(session->context->sysbus, m, NULL);
2896 if (r < 0 && r != -ENOTCONN)
2897 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2898 session->name, cm->card.base.name, strerror(-r));
2901 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2902 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2903 char name[GRDRM_CARD_NAME_MAX];
2908 assert_return(session, -EINVAL);
2909 assert_return(session->managed, -EINVAL);
2910 assert_return(session->context->sysbus, -EINVAL);
2911 assert_return(ud, -EINVAL);
2913 devnum = udev_device_get_devnum(ud);
2917 grdrm_name(name, devnum);
2919 cm = new0(managed_card, 1);
2923 basecard = &cm->card.base;
2924 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2925 cm->devnum = devnum;
2927 r = managed_card_setup_bus(cm);
2931 r = grdrm_card_add(&cm->card, name);
2935 managed_card_take_device(cm);
2943 static void managed_card_free(grdev_card *basecard) {
2944 managed_card *cm = managed_card_from_base(basecard);
2946 assert(!basecard->enabled);
2948 managed_card_release_device(cm);
2949 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
2950 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
2951 grdrm_card_destroy(&cm->card);
2955 static const grdev_card_vtable managed_card_vtable = {
2956 .free = managed_card_free,
2957 .enable = managed_card_enable,
2958 .disable = managed_card_disable,
2959 .commit = grdrm_card_commit,
2960 .restore = grdrm_card_restore,
2964 * Generic Constructor
2965 * Instead of relying on the caller to choose between managed and unmanaged
2966 * DRM devices, the grdev_drm_new() constructor does that for you (by
2967 * looking at session->managed).
2970 bool grdev_is_drm_card(grdev_card *basecard) {
2971 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
2972 basecard->vtable == &managed_card_vtable);
2975 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
2976 char name[GRDRM_CARD_NAME_MAX];
2978 assert_return(session, NULL);
2979 assert_return(devnum != 0, NULL);
2981 grdrm_name(name, devnum);
2982 return grdev_find_card(session, name);
2985 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2986 assert_return(session, -EINVAL);
2987 assert_return(ud, -EINVAL);
2989 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
2992 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
2993 const char *p, *action;
2998 assert(grdev_is_drm_card(basecard));
3001 card = grdrm_card_from_base(basecard);
3003 action = udev_device_get_action(ud);
3004 if (!action || streq(action, "add") || streq(action, "remove")) {
3005 /* If we get add/remove events on DRM nodes without devnum, we
3006 * got hotplugged DRM objects so refresh the device. */
3007 devnum = udev_device_get_devnum(ud);
3009 grdrm_card_hotplug(card);
3010 } else if (streq_ptr(action, "change")) {
3011 /* A change event with HOTPLUG=1 is sent whenever a connector
3012 * changed state. Refresh the device to update our state. */
3013 p = udev_device_get_property_value(ud, "HOTPLUG");
3014 if (streq_ptr(p, "1"))
3015 grdrm_card_hotplug(card);