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(grdrm_crtc *crtc) {
1087 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1088 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1089 grdrm_card *card = crtc->object.card;
1098 assert(crtc->object.assigned);
1102 /* If a crtc is not assigned any connector, we want any
1103 * previous setup to be cleared, so make sure the CRTC is
1104 * disabled. Otherwise, there might be content on the CRTC
1105 * while we run, which is not what we want.
1106 * If you want to avoid modesets on specific CRTCs, you should
1107 * still keep their assignment, but never enable the resulting
1108 * pipe. This way, we wouldn't touch it at all. */
1109 if (!crtc->applied) {
1110 crtc->applied = true;
1111 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1114 log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1115 card->base.name, crtc->object.id);
1117 grdrm_card_async(card, r);
1121 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1122 card->base.name, crtc->object.id);
1128 /* we always fully ignore disabled pipes */
1129 if (!pipe->base.enabled)
1132 assert(crtc->set.n_connectors > 0);
1134 if (pipe->base.flip)
1135 slot = &pipe->base.back;
1136 else if (!crtc->applied)
1137 slot = &pipe->base.front;
1144 fb = fb_from_base(*slot);
1146 if (crtc->applied || grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode)) {
1147 cnt = ++pipe->counter ? : ++pipe->counter;
1148 page_flip.fb_id = fb->id;
1149 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1150 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1152 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1155 log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1156 card->base.name, crtc->object.id);
1158 if (grdrm_card_async(card, r))
1161 /* fall through to deep modeset */
1163 if (!crtc->applied) {
1164 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1165 card->base.name, crtc->object.id);
1166 crtc->applied = true;
1169 pipe->base.flipping = true;
1170 pipe->counter = cnt;
1174 if (!pipe->base.back) {
1175 for (i = 0; i < pipe->base.max_fbs; ++i) {
1176 if (!pipe->base.fbs[i])
1179 fb = fb_from_base(pipe->base.fbs[i]);
1180 if (&fb->base == pipe->base.front)
1185 pipe->base.back = &fb->base;
1192 if (!crtc->applied) {
1193 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1194 set_crtc.count_connectors = crtc->set.n_connectors;
1195 set_crtc.fb_id = fb->id;
1198 set_crtc.mode_valid = 1;
1199 set_crtc.mode = crtc->set.mode;
1201 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1204 log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1205 card->base.name, crtc->object.id);
1207 grdrm_card_async(card, r);
1211 if (!crtc->applied) {
1212 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1213 card->base.name, crtc->object.id);
1214 crtc->applied = true;
1218 pipe->base.front = &fb->base;
1221 pipe->base.flipping = false;
1223 if (!pipe->base.back) {
1224 for (i = 0; i < pipe->base.max_fbs; ++i) {
1225 if (!pipe->base.fbs[i])
1228 fb = fb_from_base(pipe->base.fbs[i]);
1229 if (&fb->base == pipe->base.front)
1233 pipe->base.back = &fb->base;
1239 pipe->base.flip = false;
1242 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1243 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1244 grdrm_card *card = crtc->object.card;
1250 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1251 set_crtc.count_connectors = crtc->old.n_connectors;
1252 set_crtc.fb_id = crtc->old.fb;
1253 set_crtc.x = crtc->old.fb_x;
1254 set_crtc.y = crtc->old.fb_y;
1255 set_crtc.gamma_size = crtc->old.gamma;
1256 set_crtc.mode_valid = crtc->old.mode_set;
1257 set_crtc.mode = crtc->old.mode;
1259 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1262 log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1263 card->base.name, crtc->object.id);
1265 grdrm_card_async(card, r);
1270 ++crtc->pipe->counter;
1271 crtc->pipe->base.front = NULL;
1272 crtc->pipe->base.flipping = false;
1275 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1278 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1279 bool flipped = false;
1281 grdrm_fb *back = NULL;
1291 /* We got a page-flip event. To be safe, we reset all FBs on the same
1292 * pipe that have smaller flipids than the flip we got as we know they
1293 * are executed in order. We need to do this to guarantee
1294 * queue-overflows or other missed events don't cause starvation.
1295 * Furthermore, if we find the exact FB this event is for, *and* this
1296 * is the most recent event, we mark it as front FB and raise a
1299 for (i = 0; i < pipe->base.max_fbs; ++i) {
1302 if (!pipe->base.fbs[i])
1305 fb = fb_from_base(pipe->base.fbs[i]);
1306 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1307 pipe->base.front = &fb->base;
1311 if (counter - fb->flipid < UINT16_MAX) {
1314 } else if (fb->flipid == 0) {
1319 if (!pipe->base.back)
1320 pipe->base.back = &back->base;
1323 crtc->pipe->base.flipping = false;
1324 grdev_pipe_frame(&pipe->base);
1332 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1333 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1334 struct drm_mode_create_dumb create_dumb = { };
1335 struct drm_mode_map_dumb map_dumb = { };
1336 struct drm_mode_fb_cmd2 add_fb = { };
1340 assert_return(out, -EINVAL);
1341 assert_return(card, -EINVAL);
1343 fb = new0(grdrm_fb, 1);
1347 /* TODO: we should choose a compatible format of the previous CRTC
1348 * setting to allow page-flip to it. Only choose fallback if the
1349 * previous setting was crap (non xrgb32'ish). */
1352 fb->base.format = DRM_FORMAT_XRGB8888;
1353 fb->base.width = mode->hdisplay;
1354 fb->base.height = mode->vdisplay;
1356 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1357 fb->base.maps[i] = MAP_FAILED;
1359 create_dumb.width = fb->base.width;
1360 create_dumb.height = fb->base.height;
1361 create_dumb.bpp = 32;
1363 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1366 log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1367 card->base.name, fb->base.width, fb->base.height);
1371 fb->handles[0] = create_dumb.handle;
1372 fb->base.strides[0] = create_dumb.pitch;
1373 fb->sizes[0] = create_dumb.size;
1375 map_dumb.handle = fb->handles[0];
1377 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1380 log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1381 card->base.name, fb->base.width, fb->base.height);
1385 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1386 if (fb->base.maps[0] == MAP_FAILED) {
1388 log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1389 card->base.name, fb->base.width, fb->base.height);
1393 memzero(fb->base.maps[0], fb->sizes[0]);
1395 add_fb.width = fb->base.width;
1396 add_fb.height = fb->base.height;
1397 add_fb.pixel_format = fb->base.format;
1399 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1400 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1401 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1403 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1406 log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1407 card->base.name, fb->base.width, fb->base.height);
1411 fb->id = add_fb.fb_id;
1418 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1426 if (fb->id > 0 && fb->card->fd >= 0)
1427 ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1429 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1430 struct drm_mode_destroy_dumb destroy_dumb = { };
1432 if (fb->base.maps[i] != MAP_FAILED)
1433 munmap(fb->base.maps[i], fb->sizes[i]);
1435 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1436 destroy_dumb.handle = fb->handles[i];
1437 ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1450 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1451 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1452 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1455 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1456 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1457 grdrm_card *card = crtc->object.card;
1458 char name[GRDRM_PIPE_NAME_MAX];
1462 assert_return(crtc, -EINVAL);
1463 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1465 pipe = new0(grdrm_pipe, 1);
1469 basepipe = &pipe->base;
1470 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1472 pipe->base.width = mode->hdisplay;
1473 pipe->base.height = mode->vdisplay;
1475 grdrm_pipe_name(name, crtc);
1476 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1486 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1487 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1492 for (i = 0; i < pipe->base.max_fbs; ++i)
1493 if (pipe->base.fbs[i])
1494 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1499 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1500 .free = grdrm_pipe_free,
1507 static void grdrm_name(char *out, dev_t devnum) {
1508 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1509 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1512 static void grdrm_card_print(grdrm_card *card) {
1513 grdrm_object *object;
1515 grdrm_encoder *encoder;
1516 grdrm_connector *connector;
1522 log_debug("grdrm: %s: state dump", card->base.name);
1524 log_debug(" crtcs:");
1525 HASHMAP_FOREACH(object, card->object_map, iter) {
1526 if (object->type != GRDRM_TYPE_CRTC)
1529 crtc = crtc_from_object(object);
1530 log_debug(" (id: %u index: %d)", object->id, object->index);
1532 if (crtc->kern.mode_set)
1533 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1535 log_debug(" mode: <none>");
1538 log_debug(" encoders:");
1539 HASHMAP_FOREACH(object, card->object_map, iter) {
1540 if (object->type != GRDRM_TYPE_ENCODER)
1543 encoder = encoder_from_object(object);
1544 log_debug(" (id: %u index: %d)", object->id, object->index);
1546 if (encoder->kern.used_crtc)
1547 log_debug(" crtc: %u", encoder->kern.used_crtc);
1549 log_debug(" crtc: <none>");
1551 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1556 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1557 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1559 log_debug(" possible crtcs:%s", buf);
1563 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1568 for (i = 0; i < encoder->kern.n_clones; ++i)
1569 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1571 log_debug(" possible clones:%s", buf);
1576 log_debug(" connectors:");
1577 HASHMAP_FOREACH(object, card->object_map, iter) {
1578 if (object->type != GRDRM_TYPE_CONNECTOR)
1581 connector = connector_from_object(object);
1582 log_debug(" (id: %u index: %d)", object->id, object->index);
1583 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1584 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1585 connector->kern.mm_width, connector->kern.mm_height);
1587 if (connector->kern.used_encoder)
1588 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1590 log_debug(" encoder: <none>");
1592 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1597 for (i = 0; i < connector->kern.n_encoders; ++i)
1598 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1600 log_debug(" possible encoders:%s", buf);
1604 for (i = 0; i < connector->kern.n_modes; ++i) {
1605 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1606 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1610 log_debug(" planes:");
1611 HASHMAP_FOREACH(object, card->object_map, iter) {
1612 if (object->type != GRDRM_TYPE_PLANE)
1615 plane = plane_from_object(object);
1616 log_debug(" (id: %u index: %d)", object->id, object->index);
1617 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1619 if (plane->kern.used_crtc)
1620 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1622 log_debug(" crtc: <none>");
1624 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1629 for (i = 0; i < plane->kern.n_crtcs; ++i)
1630 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1632 log_debug(" possible crtcs:%s", buf);
1636 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1641 for (i = 0; i < plane->kern.n_formats; ++i)
1642 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1644 log_debug(" possible formats:%s", buf);
1650 static int grdrm_card_resync(grdrm_card *card) {
1651 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1652 uint32_t allocated = 0;
1653 grdrm_object *object;
1660 card->async_hotplug = false;
1663 /* mark existing objects for possible removal */
1664 HASHMAP_FOREACH(object, card->object_map, iter)
1665 object->present = false;
1667 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1668 struct drm_mode_get_plane_res pres;
1669 struct drm_mode_card_res res;
1672 if (allocated < card->max_ids) {
1675 free(connector_ids);
1677 crtc_ids = new0(uint32_t, card->max_ids);
1678 encoder_ids = new0(uint32_t, card->max_ids);
1679 connector_ids = new0(uint32_t, card->max_ids);
1680 plane_ids = new0(uint32_t, card->max_ids);
1682 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1685 allocated = card->max_ids;
1689 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1690 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1691 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1692 res.count_crtcs = allocated;
1693 res.count_encoders = allocated;
1694 res.count_connectors = allocated;
1696 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1699 log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
1704 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1705 pres.count_planes = allocated;
1707 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1710 log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
1714 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1715 MAX(res.count_connectors, pres.count_planes));
1716 if (max > allocated) {
1719 n = ALIGN_POWER2(max);
1720 if (!n || n > UINT16_MAX) {
1721 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
1725 /* retry with resized buffers */
1730 /* mark available objects as present */
1732 for (i = 0; i < res.count_crtcs; ++i) {
1733 object = grdrm_find_object(card, crtc_ids[i]);
1734 if (object && object->type == GRDRM_TYPE_CRTC) {
1735 object->present = true;
1741 for (i = 0; i < res.count_encoders; ++i) {
1742 object = grdrm_find_object(card, encoder_ids[i]);
1743 if (object && object->type == GRDRM_TYPE_ENCODER) {
1744 object->present = true;
1750 for (i = 0; i < res.count_connectors; ++i) {
1751 object = grdrm_find_object(card, connector_ids[i]);
1752 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1753 object->present = true;
1755 connector_ids[i] = 0;
1759 for (i = 0; i < pres.count_planes; ++i) {
1760 object = grdrm_find_object(card, plane_ids[i]);
1761 if (object && object->type == GRDRM_TYPE_PLANE) {
1762 object->present = true;
1768 /* drop removed objects */
1770 HASHMAP_FOREACH(object, card->object_map, iter)
1771 if (!object->present)
1772 grdrm_object_free(object);
1774 /* add new objects */
1776 card->n_crtcs = res.count_crtcs;
1777 for (i = 0; i < res.count_crtcs; ++i) {
1778 if (crtc_ids[i] < 1)
1781 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1786 card->n_encoders = res.count_encoders;
1787 for (i = 0; i < res.count_encoders; ++i) {
1788 if (encoder_ids[i] < 1)
1791 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1796 card->n_connectors = res.count_connectors;
1797 for (i = 0; i < res.count_connectors; ++i) {
1798 if (connector_ids[i] < 1)
1801 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1806 card->n_planes = pres.count_planes;
1807 for (i = 0; i < pres.count_planes; ++i) {
1808 if (plane_ids[i] < 1)
1811 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1816 /* re-sync objects after object_map is synced */
1818 HASHMAP_FOREACH(object, card->object_map, iter) {
1819 switch (object->type) {
1820 case GRDRM_TYPE_CRTC:
1821 r = grdrm_crtc_resync(crtc_from_object(object));
1823 case GRDRM_TYPE_ENCODER:
1824 r = grdrm_encoder_resync(encoder_from_object(object));
1826 case GRDRM_TYPE_CONNECTOR:
1827 r = grdrm_connector_resync(connector_from_object(object));
1829 case GRDRM_TYPE_PLANE:
1830 r = grdrm_plane_resync(plane_from_object(object));
1833 assert_not_reached("grdrm: invalid object type");
1840 if (card->async_hotplug)
1844 /* if modeset objects change during sync, start over */
1845 if (card->async_hotplug) {
1846 card->async_hotplug = false;
1850 /* cache crtc/connector relationship */
1851 HASHMAP_FOREACH(object, card->object_map, iter) {
1852 grdrm_connector *connector;
1853 grdrm_encoder *encoder;
1856 if (object->type != GRDRM_TYPE_CONNECTOR)
1859 connector = connector_from_object(object);
1860 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1863 object = grdrm_find_object(card, connector->kern.used_encoder);
1864 if (!object || object->type != GRDRM_TYPE_ENCODER)
1867 encoder = encoder_from_object(object);
1868 if (encoder->kern.used_crtc < 1)
1871 object = grdrm_find_object(card, encoder->kern.used_crtc);
1872 if (!object || object->type != GRDRM_TYPE_CRTC)
1875 crtc = crtc_from_object(object);
1876 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1877 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1880 /* cache old crtc settings for later restore */
1881 HASHMAP_FOREACH(object, card->object_map, iter) {
1884 if (object->type != GRDRM_TYPE_CRTC)
1887 crtc = crtc_from_object(object);
1889 /* Save data if it is the first time we refresh the CRTC. This data can
1890 * be used optionally to restore any previous configuration. For
1891 * instance, it allows us to restore VT configurations after we close
1892 * our session again. */
1893 if (!crtc->old.set) {
1894 crtc->old.fb = crtc->kern.used_fb;
1895 crtc->old.fb_x = crtc->kern.fb_offset_x;
1896 crtc->old.fb_y = crtc->kern.fb_offset_y;
1897 crtc->old.gamma = crtc->kern.gamma_size;
1898 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1899 if (crtc->old.n_connectors)
1900 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1901 crtc->old.mode_set = crtc->kern.mode_set;
1902 crtc->old.mode = crtc->kern.mode;
1903 crtc->old.set = true;
1907 /* everything synced */
1911 if (tries >= GRDRM_MAX_TRIES) {
1913 * Ugh! We were unable to sync the DRM card state due to heavy
1914 * hotplugging. This should never happen, so print a debug
1915 * message and bail out. The next uevent will trigger
1919 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
1926 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
1927 grdrm_card *card = crtc->object.card;
1928 grdrm_encoder *encoder;
1929 grdrm_object *object;
1932 if (crtc->object.assigned || connector->object.assigned)
1934 if (connector->kern.connection != 1)
1937 for (i = 0; i < connector->kern.n_encoders; ++i) {
1938 object = grdrm_find_object(card, connector->kern.encoders[i]);
1939 if (!object || object->type != GRDRM_TYPE_ENCODER)
1942 encoder = encoder_from_object(object);
1943 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
1944 if (encoder->kern.crtcs[j] == crtc->object.id) {
1945 grdrm_crtc_assign(crtc, connector);
1954 static void grdrm_card_configure(grdrm_card *card) {
1956 * Modeset Configuration
1957 * This is where we update our modeset configuration and assign
1958 * connectors to CRTCs. This means, each connector that we want to
1959 * enable needs a CRTC, disabled (or unavailable) connectors are left
1960 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
1962 * Sounds trivial, but there're several caveats:
1964 * * Multiple connectors can be driven by the same CRTC. This is
1965 * known as 'hardware clone mode'. Advantage over software clone
1966 * mode is that only a single CRTC is needed to drive multiple
1967 * displays. However, few hardware supports this and it's a huge
1968 * headache to configure on dynamic demands. Therefore, we only
1969 * support it if configured statically beforehand.
1971 * * CRTCs are not created equal. Some might be much more poweful
1972 * than others, including more advanced plane support. So far, our
1973 * CRTC selection is random. You need to supply static
1974 * configuration if you want special setups. So far, there is no
1975 * proper way to do advanced CRTC selection on dynamic demands. It
1976 * is not really clear which demands require what CRTC, so, like
1977 * everyone else, we do random CRTC selection unless explicitly
1980 * * Each Connector has a list of possible encoders that can drive
1981 * it, and each encoder has a list of possible CRTCs. If this graph
1982 * is a tree, assignment is trivial. However, if not, we cannot
1983 * reliably decide on configurations beforehand. The encoder is
1984 * always selected by the kernel, so we have to actually set a mode
1985 * to know which encoder is used. There is no way to ask the kernel
1986 * whether a given configuration is possible. This will change with
1987 * atomic-modesetting, but until then, we keep our configurations
1988 * simple and assume they work all just fine. If one fails
1989 * unexpectedly, we print a warning and disable it.
1991 * Configuring a card consists of several steps:
1993 * 1) First of all, we apply any user-configuration. If a user wants
1994 * a fixed configuration, we apply it and preserve it.
1995 * So far, we don't support user configuration files, so this step
1998 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
1999 * might only support limited configurations or require special
2000 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2002 * So far, we don't support this as there is no known quirk, so
2003 * this step is skipped.
2005 * 3) As deep modesets are expensive, we try to avoid them if
2006 * possible. Therefore, we read the current configuration from the
2007 * kernel and try to preserve it, if compatible with our demands.
2008 * If not, we break it and reassign it in a following step.
2010 * 4) The main step involves configuring all remaining objects. By
2011 * default, all available connectors are enabled, except for those
2012 * disabled by user-configuration. We lookup a suitable CRTC for
2013 * each connector and assign them. As there might be more
2014 * connectors than CRTCs, we apply some ordering so users can
2015 * select which connectors are more important right now.
2016 * So far, we only apply the default ordering, more might be added
2020 grdrm_object *object;
2024 /* clear assignments */
2025 HASHMAP_FOREACH(object, card->object_map, i)
2026 object->assigned = false;
2028 /* preserve existing configurations */
2029 HASHMAP_FOREACH(object, card->object_map, i) {
2030 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2033 crtc = crtc_from_object(object);
2035 if (crtc->applied) {
2036 /* If our mode is set, preserve it. If no connector is
2037 * set, modeset either failed or the pipe is unused. In
2038 * both cases, leave it alone. It might be tried again
2039 * below in case there're remaining connectors.
2040 * Otherwise, try restoring the assignments. If they
2041 * are no longer valid, leave the pipe untouched. */
2043 if (crtc->set.n_connectors < 1)
2046 assert(crtc->set.n_connectors == 1);
2048 object = grdrm_find_object(card, crtc->set.connectors[0]);
2049 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2052 card_configure_crtc(crtc, connector_from_object(object));
2053 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2054 /* If our mode is not set on the pipe, we know the kern
2055 * information is valid. Try keeping it. If it's not
2056 * possible, leave the pipe untouched for later
2059 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2060 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2063 card_configure_crtc(crtc, connector_from_object(object));
2067 /* assign remaining objects */
2068 HASHMAP_FOREACH(object, card->object_map, i) {
2069 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2072 crtc = crtc_from_object(object);
2074 HASHMAP_FOREACH(object, card->object_map, j) {
2075 if (object->type != GRDRM_TYPE_CONNECTOR)
2078 if (card_configure_crtc(crtc, connector_from_object(object)))
2082 if (!crtc->object.assigned)
2083 grdrm_crtc_assign(crtc, NULL);
2086 /* expose configuration */
2087 HASHMAP_FOREACH(object, card->object_map, i) {
2088 if (object->type != GRDRM_TYPE_CRTC)
2091 grdrm_crtc_expose(crtc_from_object(object));
2095 static void grdrm_card_hotplug(grdrm_card *card) {
2099 assert(!card->ready);
2101 r = grdrm_card_resync(card);
2103 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2104 card->base.session->name, card->base.name, strerror(-r));
2108 grdev_session_pin(card->base.session);
2110 grdrm_card_print(card);
2111 grdrm_card_configure(card);
2114 grdev_session_unpin(card->base.session);
2117 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2118 grdrm_card *card = userdata;
2119 struct drm_event_vblank *vblank;
2120 struct drm_event *event;
2121 uint32_t id, counter;
2122 grdrm_object *object;
2126 if (revents & (EPOLLHUP | EPOLLERR)) {
2127 /* Immediately close device on HUP; no need to flush pending
2128 * data.. there're no events we care about here. */
2129 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2130 grdrm_card_close(card);
2134 if (revents & (EPOLLIN)) {
2135 l = read(card->fd, buf, sizeof(buf));
2137 if (errno == EAGAIN || errno == EINTR)
2140 log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2141 grdrm_card_close(card);
2143 } else if ((size_t)l < sizeof(*event)) {
2144 log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l);
2148 for (i = 0; i < l; i += event->length) {
2149 event = (void*)&buf[i];
2151 if (i + event->length > l) {
2152 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2156 switch (event->type) {
2157 case DRM_EVENT_FLIP_COMPLETE:
2158 vblank = (void*)event;
2159 if (event->length < sizeof(*vblank)) {
2160 log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2164 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2165 object = grdrm_find_object(card, id);
2166 if (!object || object->type != GRDRM_TYPE_CRTC)
2169 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2178 static int grdrm_card_add(grdrm_card *card, const char *name) {
2180 assert(card->fd < 0);
2182 card->object_map = hashmap_new(&trivial_hash_ops);
2183 if (!card->object_map)
2186 return grdev_card_add(&card->base, name);
2189 static void grdrm_card_destroy(grdrm_card *card) {
2191 assert(!card->running);
2192 assert(card->fd < 0);
2193 assert(hashmap_size(card->object_map) == 0);
2195 hashmap_free(card->object_map);
2198 static void grdrm_card_commit(grdev_card *basecard) {
2199 grdrm_card *card = grdrm_card_from_base(basecard);
2200 grdrm_object *object;
2203 HASHMAP_FOREACH(object, card->object_map, iter) {
2207 if (object->type != GRDRM_TYPE_CRTC)
2210 grdrm_crtc_commit(crtc_from_object(object));
2214 static void grdrm_card_restore(grdev_card *basecard) {
2215 grdrm_card *card = grdrm_card_from_base(basecard);
2216 grdrm_object *object;
2219 HASHMAP_FOREACH(object, card->object_map, iter) {
2223 if (object->type != GRDRM_TYPE_CRTC)
2226 grdrm_crtc_restore(crtc_from_object(object));
2230 static void grdrm_card_enable(grdrm_card *card) {
2233 if (card->fd < 0 || card->running)
2236 /* ignore cards without DUMB_BUFFER capability */
2237 if (!card->cap_dumb)
2240 assert(card->fd_src);
2242 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2244 card->running = true;
2245 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2246 grdrm_card_hotplug(card);
2249 static void grdrm_card_disable(grdrm_card *card) {
2250 grdrm_object *object;
2255 if (card->fd < 0 || !card->running)
2258 assert(card->fd_src);
2260 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2262 card->running = false;
2263 card->ready = false;
2264 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2266 /* stop all pipes */
2267 HASHMAP_FOREACH(object, card->object_map, iter) {
2270 if (object->type != GRDRM_TYPE_CRTC)
2273 crtc = crtc_from_object(object);
2274 crtc->applied = false;
2276 grdev_pipe_ready(&crtc->pipe->base, false);
2280 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2281 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2282 _cleanup_close_ int fd = dev_fd;
2283 struct drm_get_cap cap;
2287 assert(dev_fd >= 0);
2288 assert(card->fd != dev_fd);
2290 pin = grdev_session_pin(card->base.session);
2291 grdrm_card_close(card);
2293 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2295 r = fd_nonblock(fd, true);
2299 r = fd_cloexec(fd, true);
2303 flags = fcntl(fd, F_GETFL, 0);
2306 if ((flags & O_ACCMODE) != O_RDWR)
2309 r = sd_event_add_io(card->base.session->context->event,
2312 EPOLLHUP | EPOLLERR | EPOLLIN,
2318 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2323 /* cache DUMB_BUFFER capability */
2324 cap.capability = DRM_CAP_DUMB_BUFFER;
2326 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2327 card->cap_dumb = r >= 0 && cap.value;
2329 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2330 card->base.session->name, card->base.name, strerror(-r));
2331 else if (!card->cap_dumb)
2332 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2333 card->base.session->name, card->base.name);
2335 /* cache TIMESTAMP_MONOTONIC capability */
2336 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2338 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2339 card->cap_monotonic = r >= 0 && cap.value;
2341 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2342 card->base.session->name, card->base.name, strerror(-r));
2343 else if (!card->cap_monotonic)
2344 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2345 card->base.session->name, card->base.name);
2350 static void grdrm_card_close(grdrm_card *card) {
2351 grdrm_object *object;
2356 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2358 grdrm_card_disable(card);
2360 card->fd_src = sd_event_source_unref(card->fd_src);
2361 card->fd = safe_close(card->fd);
2363 grdev_session_pin(card->base.session);
2364 while ((object = hashmap_first(card->object_map)))
2365 grdrm_object_free(object);
2366 grdev_session_unpin(card->base.session);
2369 static bool grdrm_card_async(grdrm_card *card, int r) {
2372 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2373 * (or we did something terribly wrong). Immediately disable
2374 * the card, so we stop all pipes and wait to be activated
2376 grdrm_card_disable(card);
2379 /* DRM objects can be hotplugged at any time. If an object is
2380 * removed that we use, we remember that state so a following
2381 * call can test for this.
2382 * Note that we also get a uevent as followup, this will resync
2383 * the whole device. */
2384 card->async_hotplug = true;
2388 return !card->ready;
2393 * The unmanaged DRM card opens the device node for a given DRM device
2394 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2395 * the device only if we really require it and releases it as soon as we're
2396 * disabled or closed.
2397 * The unmanaged element can be used in all situations where you have direct
2398 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2399 * outside of user sessions and in emergency situations where logind is not
2403 static void unmanaged_card_enable(grdev_card *basecard) {
2404 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2407 if (cu->card.fd < 0) {
2408 /* try open on activation if it failed during allocation */
2409 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2411 /* not fatal; simply ignore the device */
2412 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2413 basecard->session->name, basecard->name, cu->devnode);
2417 /* we might already be DRM-Master by open(); that's fine */
2419 r = grdrm_card_open(&cu->card, fd);
2421 log_debug("grdrm: %s/%s: cannot open: %s",
2422 basecard->session->name, basecard->name, strerror(-r));
2427 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2429 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2430 basecard->session->name, basecard->name);
2434 grdrm_card_enable(&cu->card);
2437 static void unmanaged_card_disable(grdev_card *basecard) {
2438 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2440 grdrm_card_disable(&cu->card);
2443 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2444 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2445 char name[GRDRM_CARD_NAME_MAX];
2447 const char *devnode;
2451 assert_return(session, -EINVAL);
2452 assert_return(ud, -EINVAL);
2454 devnode = udev_device_get_devnode(ud);
2455 devnum = udev_device_get_devnum(ud);
2456 if (!devnode || devnum == 0)
2459 grdrm_name(name, devnum);
2461 cu = new0(unmanaged_card, 1);
2465 basecard = &cu->card.base;
2466 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2468 cu->devnode = strdup(devnode);
2472 r = grdrm_card_add(&cu->card, name);
2476 /* try to open but ignore errors */
2477 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2479 /* not fatal; allow uaccess based control on activation */
2480 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2481 basecard->session->name, basecard->name, cu->devnode);
2483 /* We might get DRM-Master implicitly on open(); drop it immediately
2484 * so we acquire it only once we're actually enabled. */
2485 ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2487 r = grdrm_card_open(&cu->card, fd);
2489 log_debug("grdrm: %s/%s: cannot open: %s",
2490 basecard->session->name, basecard->name, strerror(-r));
2499 static void unmanaged_card_free(grdev_card *basecard) {
2500 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2502 assert(!basecard->enabled);
2504 grdrm_card_close(&cu->card);
2505 grdrm_card_destroy(&cu->card);
2510 static const grdev_card_vtable unmanaged_card_vtable = {
2511 .free = unmanaged_card_free,
2512 .enable = unmanaged_card_enable,
2513 .disable = unmanaged_card_disable,
2514 .commit = grdrm_card_commit,
2515 .restore = grdrm_card_restore,
2520 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2521 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2522 * logind passes us a file-descriptor whenever our session is activated. Thus,
2523 * we don't need access to the device node directly.
2524 * Furthermore, whenever the session is put asleep, logind revokes the
2525 * file-descriptor so we loose access to the device.
2526 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2527 * you run inside a user session with exclusive device access.
2530 static void managed_card_enable(grdev_card *card) {
2531 managed_card *cm = managed_card_from_base(card);
2533 /* If the device is manually re-enabled, we try to resume our card
2534 * management. Note that we have no control over DRM-Master and the fd,
2535 * so we have to take over the state from the last logind event. */
2538 grdrm_card_enable(&cm->card);
2541 static void managed_card_disable(grdev_card *card) {
2542 managed_card *cm = managed_card_from_base(card);
2544 /* If the device is manually disabled, we keep the FD but put our card
2545 * management asleep. This way, we can wake up at any time, but don't
2546 * touch the device while asleep. */
2548 grdrm_card_disable(&cm->card);
2551 static int managed_card_pause_device_fn(sd_bus *bus,
2552 sd_bus_message *signal,
2554 sd_bus_error *ret_error) {
2555 managed_card *cm = userdata;
2556 grdev_session *session = cm->card.base.session;
2557 uint32_t major, minor;
2562 * We get PauseDevice() signals from logind whenever a device we
2563 * requested was, or is about to be, paused. Arguments are major/minor
2564 * number of the device and the mode of the operation.
2565 * In case the event is not about our device, we ignore it. Otherwise,
2566 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2567 * already handled an EACCES error from a modeset ioctl, in which case
2568 * we already disabled the device.
2570 * @mode can be one of the following:
2571 * "pause": The device is about to be paused. We must react
2572 * immediately and respond with PauseDeviceComplete(). Once
2573 * we replied, logind will pause the device. Note that
2574 * logind might apply any kind of timeout and force pause
2575 * the device if we don't respond in a timely manner. In
2576 * this case, we will receive a second PauseDevice event
2577 * with @mode set to "force" (or similar).
2578 * "force": The device was disabled forecfully by logind. DRM-Master
2579 * was already dropped. This is just an asynchronous
2580 * notification so we can put the device asleep (in case
2581 * we didn't already notice the dropped DRM-Master).
2582 * "gone": This is like "force" but is sent if the device was
2583 * paused due to a device-removal event.
2585 * We always handle PauseDevice signals as "force" as we properly
2586 * support asynchronously dropping DRM-Master, anyway. But in case
2587 * logind sent mode "pause", we also call PauseDeviceComplete() to
2588 * immediately acknowledge the request.
2591 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2593 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2594 session->name, cm->card.base.name);
2598 /* not our device? */
2599 if (makedev(major, minor) != cm->devnum)
2603 grdrm_card_disable(&cm->card);
2605 if (streq(mode, "pause")) {
2606 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2609 * Sending PauseDeviceComplete() is racy if logind triggers the
2610 * timeout. That is, if we take too long and logind pauses the
2611 * device by sending a forced PauseDevice, our
2612 * PauseDeviceComplete call will be stray. That's fine, though.
2613 * logind ignores such stray calls. Only if logind also sent a
2614 * further PauseDevice() signal, it might match our call
2615 * incorrectly to the newer PauseDevice(). That's fine, too, as
2616 * we handle that event asynchronously, anyway. Therefore,
2617 * whatever happens, we're fine. Yay!
2620 r = sd_bus_message_new_method_call(session->context->sysbus,
2622 "org.freedesktop.login1",
2624 "org.freedesktop.login1.Session",
2625 "PauseDeviceComplete");
2627 r = sd_bus_message_append(m, "uu", major, minor);
2629 r = sd_bus_send(session->context->sysbus, m, NULL);
2633 log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2634 session->name, cm->card.base.name, strerror(-r));
2640 static int managed_card_resume_device_fn(sd_bus *bus,
2641 sd_bus_message *signal,
2643 sd_bus_error *ret_error) {
2644 managed_card *cm = userdata;
2645 grdev_session *session = cm->card.base.session;
2646 uint32_t major, minor;
2650 * We get ResumeDevice signals whenever logind resumed a previously
2651 * paused device. The arguments contain the major/minor number of the
2652 * related device and a new file-descriptor for the freshly opened
2654 * If the signal is not about our device, we simply ignore it.
2655 * Otherwise, we immediately resume the device. Note that we drop the
2656 * new file-descriptor as we already have one from TakeDevice(). logind
2657 * preserves the file-context across pause/resume for DRM but only
2658 * drops/acquires DRM-Master accordingly. This way, our context (like
2659 * DRM-FBs and BOs) is preserved.
2662 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2664 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2665 session->name, cm->card.base.name);
2669 /* not our device? */
2670 if (makedev(major, minor) != cm->devnum)
2673 if (cm->card.fd < 0) {
2674 /* This shouldn't happen. We should already own an FD from
2675 * TakeDevice(). However, lets be safe and use this FD in case
2676 * we really don't have one. There is no harm in doing this
2677 * and our code works fine this way. */
2678 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2680 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2681 session->name, cm->card.base.name);
2685 r = grdrm_card_open(&cm->card, fd);
2687 log_debug("grdrm: %s/%s: cannot open: %s",
2688 session->name, cm->card.base.name, strerror(-r));
2694 if (cm->card.base.enabled)
2695 grdrm_card_enable(&cm->card);
2700 static int managed_card_setup_bus(managed_card *cm) {
2701 grdev_session *session = cm->card.base.session;
2702 _cleanup_free_ char *match = NULL;
2705 match = strjoin("type='signal',"
2706 "sender='org.freedesktop.login1',"
2707 "interface='org.freedesktop.login1.Session',"
2708 "member='PauseDevice',"
2709 "path='", session->path, "'",
2714 r = sd_bus_add_match(session->context->sysbus,
2715 &cm->slot_pause_device,
2717 managed_card_pause_device_fn,
2723 match = strjoin("type='signal',"
2724 "sender='org.freedesktop.login1',"
2725 "interface='org.freedesktop.login1.Session',"
2726 "member='ResumeDevice',"
2727 "path='", session->path, "'",
2732 r = sd_bus_add_match(session->context->sysbus,
2733 &cm->slot_resume_device,
2735 managed_card_resume_device_fn,
2743 static int managed_card_take_device_fn(sd_bus *bus,
2744 sd_bus_message *reply,
2746 sd_bus_error *ret_error) {
2747 managed_card *cm = userdata;
2748 grdev_session *session = cm->card.base.session;
2751 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2753 if (sd_bus_message_is_method_error(reply, NULL)) {
2754 const sd_bus_error *error = sd_bus_message_get_error(reply);
2756 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2757 session->name, cm->card.base.name, error->name, error->message);
2761 cm->acquired = true;
2763 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2765 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2766 session->name, cm->card.base.name);
2770 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2772 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2773 session->name, cm->card.base.name);
2777 r = grdrm_card_open(&cm->card, fd);
2779 log_debug("grdrm: %s/%s: cannot open: %s",
2780 session->name, cm->card.base.name, strerror(-r));
2784 if (!paused && cm->card.base.enabled)
2785 grdrm_card_enable(&cm->card);
2790 static void managed_card_take_device(managed_card *cm) {
2791 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2792 grdev_session *session = cm->card.base.session;
2795 r = sd_bus_message_new_method_call(session->context->sysbus,
2797 "org.freedesktop.login1",
2799 "org.freedesktop.login1.Session",
2804 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2808 r = sd_bus_call_async(session->context->sysbus,
2809 &cm->slot_take_device,
2811 managed_card_take_device_fn,
2817 cm->requested = true;
2821 log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2822 session->name, cm->card.base.name, strerror(-r));
2825 static void managed_card_release_device(managed_card *cm) {
2826 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2827 grdev_session *session = cm->card.base.session;
2831 * If TakeDevice() is pending or was successful, make sure to
2832 * release the device again. We don't care for return-values,
2833 * so send it without waiting or callbacks.
2834 * If a failed TakeDevice() is pending, but someone else took
2835 * the device on the same bus-connection, we might incorrectly
2836 * release their device. This is an unlikely race, though.
2837 * Furthermore, you really shouldn't have two users of the
2838 * controller-API on the same session, on the same devices, *AND* on
2839 * the same bus-connection. So we don't care for that race..
2842 grdrm_card_close(&cm->card);
2843 cm->requested = false;
2845 if (!cm->acquired && !cm->slot_take_device)
2848 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2849 cm->acquired = false;
2851 r = sd_bus_message_new_method_call(session->context->sysbus,
2853 "org.freedesktop.login1",
2855 "org.freedesktop.login1.Session",
2858 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2860 r = sd_bus_send(session->context->sysbus, m, NULL);
2863 if (r < 0 && r != -ENOTCONN)
2864 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2865 session->name, cm->card.base.name, strerror(-r));
2868 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2869 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2870 char name[GRDRM_CARD_NAME_MAX];
2875 assert_return(session, -EINVAL);
2876 assert_return(session->managed, -EINVAL);
2877 assert_return(session->context->sysbus, -EINVAL);
2878 assert_return(ud, -EINVAL);
2880 devnum = udev_device_get_devnum(ud);
2884 grdrm_name(name, devnum);
2886 cm = new0(managed_card, 1);
2890 basecard = &cm->card.base;
2891 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2892 cm->devnum = devnum;
2894 r = managed_card_setup_bus(cm);
2898 r = grdrm_card_add(&cm->card, name);
2902 managed_card_take_device(cm);
2910 static void managed_card_free(grdev_card *basecard) {
2911 managed_card *cm = managed_card_from_base(basecard);
2913 assert(!basecard->enabled);
2915 managed_card_release_device(cm);
2916 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
2917 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
2918 grdrm_card_destroy(&cm->card);
2922 static const grdev_card_vtable managed_card_vtable = {
2923 .free = managed_card_free,
2924 .enable = managed_card_enable,
2925 .disable = managed_card_disable,
2926 .commit = grdrm_card_commit,
2927 .restore = grdrm_card_restore,
2931 * Generic Constructor
2932 * Instead of relying on the caller to choose between managed and unmanaged
2933 * DRM devices, the grdev_drm_new() constructor does that for you (by
2934 * looking at session->managed).
2937 bool grdev_is_drm_card(grdev_card *basecard) {
2938 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
2939 basecard->vtable == &managed_card_vtable);
2942 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
2943 char name[GRDRM_CARD_NAME_MAX];
2945 assert_return(session, NULL);
2946 assert_return(devnum != 0, NULL);
2948 grdrm_name(name, devnum);
2949 return grdev_find_card(session, name);
2952 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2953 assert_return(session, -EINVAL);
2954 assert_return(ud, -EINVAL);
2956 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);