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)
349 if (a->vrefresh != b->vrefresh)
359 grdrm_object *grdrm_find_object(grdrm_card *card, uint32_t id) {
360 assert_return(card, NULL);
362 return id > 0 ? hashmap_get(card->object_map, UINT32_TO_PTR(id)) : NULL;
365 int grdrm_object_add(grdrm_object *object) {
369 assert(object->card);
370 assert(object->id > 0);
371 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
372 assert(object->free_fn);
374 if (object->index >= 32)
375 log_debug("grdrm: %s: object index exceeds 32bit masks: type=%u, index=%" PRIu32,
376 object->card->base.name, object->type, object->index);
378 r = hashmap_put(object->card->object_map, UINT32_TO_PTR(object->id), object);
385 grdrm_object *grdrm_object_free(grdrm_object *object) {
389 assert(object->card);
390 assert(object->id > 0);
391 assert(IN_SET(object->type, GRDRM_TYPE_CRTC, GRDRM_TYPE_ENCODER, GRDRM_TYPE_CONNECTOR, GRDRM_TYPE_PLANE));
392 assert(object->free_fn);
394 hashmap_remove_value(object->card->object_map, UINT32_TO_PTR(object->id), object);
396 object->free_fn(object);
404 static void plane_free(grdrm_object *object) {
405 grdrm_plane *plane = plane_from_object(object);
407 free(plane->kern.formats);
408 free(plane->kern.crtcs);
412 int grdrm_plane_new(grdrm_plane **out, grdrm_card *card, uint32_t id, uint32_t index) {
413 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
419 plane = new0(grdrm_plane, 1);
423 object = &plane->object;
424 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_PLANE, plane_free);
426 plane->kern.max_crtcs = 32;
427 plane->kern.crtcs = new0(uint32_t, plane->kern.max_crtcs);
428 if (!plane->kern.crtcs)
431 plane->kern.max_formats = 32;
432 plane->kern.formats = new0(uint32_t, plane->kern.max_formats);
433 if (!plane->kern.formats)
436 r = grdrm_object_add(object);
446 static int grdrm_plane_resync(grdrm_plane *plane) {
447 grdrm_card *card = plane->object.card;
453 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
454 struct drm_mode_get_plane res;
455 grdrm_object *object;
456 bool resized = false;
460 res.plane_id = plane->object.id;
461 res.format_type_ptr = PTR_TO_UINT64(plane->kern.formats);
462 res.count_format_types = plane->kern.max_formats;
464 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANE, &res);
468 card->async_hotplug = true;
470 log_debug("grdrm: %s: plane %u removed during resync", card->base.name, plane->object.id);
472 log_debug("grdrm: %s: cannot retrieve plane %u: %m", card->base.name, plane->object.id);
478 plane->kern.n_crtcs = 0;
479 memzero(plane->kern.crtcs, sizeof(uint32_t) * plane->kern.max_crtcs);
481 HASHMAP_FOREACH(object, card->object_map, iter) {
482 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
484 if (!(res.possible_crtcs & (1 << object->index)))
486 if (plane->kern.n_crtcs >= 32) {
487 log_debug("grdrm: %s: possible_crtcs of plane %" PRIu32 " exceeds 32bit mask",
488 card->base.name, plane->object.id);
492 plane->kern.crtcs[plane->kern.n_crtcs++] = object->id;
495 if (res.count_format_types > plane->kern.max_formats) {
498 max = ALIGN_POWER2(res.count_format_types);
499 if (!max || max > UINT16_MAX) {
500 log_debug("grdrm: %s: excessive plane resource limit: %" PRIu32, card->base.name, max);
504 t = realloc(plane->kern.formats, sizeof(*t) * max);
508 plane->kern.formats = t;
509 plane->kern.max_formats = max;
516 plane->kern.n_formats = res.count_format_types;
517 plane->kern.used_crtc = res.crtc_id;
518 plane->kern.used_fb = res.fb_id;
519 plane->kern.gamma_size = res.gamma_size;
524 if (tries >= GRDRM_MAX_TRIES) {
525 log_debug("grdrm: %s: plane %u not settled for retrieval", card->base.name, plane->object.id);
536 static void connector_free(grdrm_object *object) {
537 grdrm_connector *connector = connector_from_object(object);
539 free(connector->kern.prop_values);
540 free(connector->kern.prop_ids);
541 free(connector->kern.modes);
542 free(connector->kern.encoders);
546 int grdrm_connector_new(grdrm_connector **out, grdrm_card *card, uint32_t id, uint32_t index) {
547 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
548 grdrm_connector *connector;
553 connector = new0(grdrm_connector, 1);
557 object = &connector->object;
558 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CONNECTOR, connector_free);
560 connector->kern.max_encoders = 32;
561 connector->kern.encoders = new0(uint32_t, connector->kern.max_encoders);
562 if (!connector->kern.encoders)
565 connector->kern.max_modes = 32;
566 connector->kern.modes = new0(struct drm_mode_modeinfo, connector->kern.max_modes);
567 if (!connector->kern.modes)
570 connector->kern.max_props = 32;
571 connector->kern.prop_ids = new0(uint32_t, connector->kern.max_props);
572 connector->kern.prop_values = new0(uint64_t, connector->kern.max_props);
573 if (!connector->kern.prop_ids || !connector->kern.prop_values)
576 r = grdrm_object_add(object);
586 static int grdrm_connector_resync(grdrm_connector *connector) {
587 grdrm_card *card = connector->object.card;
593 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
594 struct drm_mode_get_connector res;
595 bool resized = false;
599 res.connector_id = connector->object.id;
600 res.encoders_ptr = PTR_TO_UINT64(connector->kern.encoders);
601 res.props_ptr = PTR_TO_UINT64(connector->kern.prop_ids);
602 res.prop_values_ptr = PTR_TO_UINT64(connector->kern.prop_values);
603 res.count_encoders = connector->kern.max_encoders;
604 res.count_props = connector->kern.max_props;
606 /* Retrieve modes only if we have none. This avoids expensive
607 * EDID reads in the kernel, that can slow down resyncs
609 if (connector->kern.n_modes == 0) {
610 res.modes_ptr = PTR_TO_UINT64(connector->kern.modes);
611 res.count_modes = connector->kern.max_modes;
614 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCONNECTOR, &res);
618 card->async_hotplug = true;
620 log_debug("grdrm: %s: connector %u removed during resync", card->base.name, connector->object.id);
622 log_debug("grdrm: %s: cannot retrieve connector %u: %m", card->base.name, connector->object.id);
628 if (res.count_encoders > connector->kern.max_encoders) {
631 max = ALIGN_POWER2(res.count_encoders);
632 if (!max || max > UINT16_MAX) {
633 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
637 t = realloc(connector->kern.encoders, sizeof(*t) * max);
641 connector->kern.encoders = t;
642 connector->kern.max_encoders = max;
646 if (res.count_modes > connector->kern.max_modes) {
647 struct drm_mode_modeinfo *t;
649 max = ALIGN_POWER2(res.count_modes);
650 if (!max || max > UINT16_MAX) {
651 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
655 t = realloc(connector->kern.modes, sizeof(*t) * max);
659 connector->kern.modes = t;
660 connector->kern.max_modes = max;
664 if (res.count_props > connector->kern.max_props) {
668 max = ALIGN_POWER2(res.count_props);
669 if (!max || max > UINT16_MAX) {
670 log_debug("grdrm: %s: excessive connector resource limit: %" PRIu32, card->base.name, max);
674 tids = realloc(connector->kern.prop_ids, sizeof(*tids) * max);
677 connector->kern.prop_ids = tids;
679 tvals = realloc(connector->kern.prop_values, sizeof(*tvals) * max);
682 connector->kern.prop_values = tvals;
684 connector->kern.max_props = max;
691 connector->kern.n_encoders = res.count_encoders;
692 connector->kern.n_modes = res.count_modes;
693 connector->kern.n_props = res.count_props;
694 connector->kern.type = res.connector_type;
695 connector->kern.type_id = res.connector_type_id;
696 connector->kern.used_encoder = res.encoder_id;
697 connector->kern.connection = res.connection;
698 connector->kern.mm_width = res.mm_width;
699 connector->kern.mm_height = res.mm_height;
700 connector->kern.subpixel = res.subpixel;
705 if (tries >= GRDRM_MAX_TRIES) {
706 log_debug("grdrm: %s: connector %u not settled for retrieval", card->base.name, connector->object.id);
717 static void encoder_free(grdrm_object *object) {
718 grdrm_encoder *encoder = encoder_from_object(object);
720 free(encoder->kern.clones);
721 free(encoder->kern.crtcs);
725 int grdrm_encoder_new(grdrm_encoder **out, grdrm_card *card, uint32_t id, uint32_t index) {
726 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
727 grdrm_encoder *encoder;
732 encoder = new0(grdrm_encoder, 1);
736 object = &encoder->object;
737 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_ENCODER, encoder_free);
739 encoder->kern.max_crtcs = 32;
740 encoder->kern.crtcs = new0(uint32_t, encoder->kern.max_crtcs);
741 if (!encoder->kern.crtcs)
744 encoder->kern.max_clones = 32;
745 encoder->kern.clones = new0(uint32_t, encoder->kern.max_clones);
746 if (!encoder->kern.clones)
749 r = grdrm_object_add(object);
759 static int grdrm_encoder_resync(grdrm_encoder *encoder) {
760 grdrm_card *card = encoder->object.card;
761 struct drm_mode_get_encoder res;
762 grdrm_object *object;
769 res.encoder_id = encoder->object.id;
771 r = ioctl(card->fd, DRM_IOCTL_MODE_GETENCODER, &res);
775 card->async_hotplug = true;
777 log_debug("grdrm: %s: encoder %u removed during resync", card->base.name, encoder->object.id);
779 log_debug("grdrm: %s: cannot retrieve encoder %u: %m", card->base.name, encoder->object.id);
785 encoder->kern.type = res.encoder_type;
786 encoder->kern.used_crtc = res.crtc_id;
788 encoder->kern.n_crtcs = 0;
789 memzero(encoder->kern.crtcs, sizeof(uint32_t) * encoder->kern.max_crtcs);
791 HASHMAP_FOREACH(object, card->object_map, iter) {
792 if (object->type != GRDRM_TYPE_CRTC || object->index >= 32)
794 if (!(res.possible_crtcs & (1 << object->index)))
796 if (encoder->kern.n_crtcs >= 32) {
797 log_debug("grdrm: %s: possible_crtcs exceeds 32bit mask", card->base.name);
801 encoder->kern.crtcs[encoder->kern.n_crtcs++] = object->id;
804 encoder->kern.n_clones = 0;
805 memzero(encoder->kern.clones, sizeof(uint32_t) * encoder->kern.max_clones);
807 HASHMAP_FOREACH(object, card->object_map, iter) {
808 if (object->type != GRDRM_TYPE_ENCODER || object->index >= 32)
810 if (!(res.possible_clones & (1 << object->index)))
812 if (encoder->kern.n_clones >= 32) {
813 log_debug("grdrm: %s: possible_encoders exceeds 32bit mask", card->base.name);
817 encoder->kern.clones[encoder->kern.n_clones++] = object->id;
827 static void crtc_free(grdrm_object *object) {
828 grdrm_crtc *crtc = crtc_from_object(object);
831 grdev_pipe_free(&crtc->pipe->base);
832 free(crtc->set.connectors);
833 free(crtc->old.connectors);
834 free(crtc->kern.used_connectors);
838 int grdrm_crtc_new(grdrm_crtc **out, grdrm_card *card, uint32_t id, uint32_t index) {
839 _cleanup_(grdrm_object_freep) grdrm_object *object = NULL;
845 crtc = new0(grdrm_crtc, 1);
849 object = &crtc->object;
850 *object = GRDRM_OBJECT_INIT(card, id, index, GRDRM_TYPE_CRTC, crtc_free);
852 crtc->kern.max_used_connectors = 32;
853 crtc->kern.used_connectors = new0(uint32_t, crtc->kern.max_used_connectors);
854 if (!crtc->kern.used_connectors)
857 crtc->old.connectors = new0(uint32_t, crtc->kern.max_used_connectors);
858 if (!crtc->old.connectors)
861 r = grdrm_object_add(object);
871 static int grdrm_crtc_resync(grdrm_crtc *crtc) {
872 grdrm_card *card = crtc->object.card;
873 struct drm_mode_crtc res = { .crtc_id = crtc->object.id };
878 /* make sure we can cache any combination later */
879 if (card->n_connectors > crtc->kern.max_used_connectors) {
882 max = ALIGN_POWER2(card->n_connectors);
886 t = realloc_multiply(crtc->kern.used_connectors, sizeof(*t), max);
890 crtc->kern.used_connectors = t;
891 crtc->kern.max_used_connectors = max;
893 if (!crtc->old.set) {
894 crtc->old.connectors = calloc(sizeof(*t), max);
895 if (!crtc->old.connectors)
900 /* GETCRTC doesn't return connectors. We have to read all
901 * encoder-state and deduce the setup ourselves.. */
902 crtc->kern.n_used_connectors = 0;
904 r = ioctl(card->fd, DRM_IOCTL_MODE_GETCRTC, &res);
908 card->async_hotplug = true;
910 log_debug("grdrm: %s: crtc %u removed during resync", card->base.name, crtc->object.id);
912 log_debug("grdrm: %s: cannot retrieve crtc %u: %m", card->base.name, crtc->object.id);
918 crtc->kern.used_fb = res.fb_id;
919 crtc->kern.fb_offset_x = res.x;
920 crtc->kern.fb_offset_y = res.y;
921 crtc->kern.gamma_size = res.gamma_size;
922 crtc->kern.mode_set = res.mode_valid;
923 crtc->kern.mode = res.mode;
928 static void grdrm_crtc_assign(grdrm_crtc *crtc, grdrm_connector *connector) {
929 uint32_t n_connectors;
933 assert(!crtc->object.assigned);
934 assert(!connector || !connector->object.assigned);
936 /* always mark both as assigned; even if assignments cannot be set */
937 crtc->object.assigned = true;
939 connector->object.assigned = true;
941 /* we will support hw clone mode in the future */
942 n_connectors = connector ? 1 : 0;
944 /* bail out if configuration is preserved */
945 if (crtc->set.n_connectors == n_connectors &&
946 (n_connectors == 0 || crtc->set.connectors[0] == connector->object.id))
949 crtc->applied = false;
950 crtc->set.n_connectors = 0;
952 if (n_connectors > crtc->set.max_connectors) {
955 max = ALIGN_POWER2(n_connectors);
961 t = realloc(crtc->set.connectors, sizeof(*t) * max);
967 crtc->set.connectors = t;
968 crtc->set.max_connectors = max;
972 struct drm_mode_modeinfo *m, *pref = NULL;
975 for (i = 0; i < connector->kern.n_modes; ++i) {
976 m = &connector->kern.modes[i];
978 /* ignore 3D modes by default */
979 if (m->flags & DRM_MODE_FLAG_3D_MASK)
987 /* use PREFERRED over non-PREFERRED */
988 if ((pref->type & DRM_MODE_TYPE_PREFERRED) &&
989 !(m->type & DRM_MODE_TYPE_PREFERRED))
992 /* use DRIVER over non-PREFERRED|DRIVER */
993 if ((pref->type & DRM_MODE_TYPE_DRIVER) &&
994 !(m->type & (DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED)))
997 /* always prefer higher resolution */
998 if (pref->hdisplay > m->hdisplay ||
999 (pref->hdisplay == m->hdisplay && pref->vdisplay > m->vdisplay))
1006 crtc->set.mode = *pref;
1007 crtc->set.n_connectors = 1;
1008 crtc->set.connectors[0] = connector->object.id;
1009 log_debug("grdrm: %s: assigned connector %" PRIu32 " to crtc %" PRIu32 " with mode %s",
1010 crtc->object.card->base.name, connector->object.id, crtc->object.id, pref->name);
1012 log_debug("grdrm: %s: connector %" PRIu32 " to be assigned but has no valid mode",
1013 crtc->object.card->base.name, connector->object.id);
1020 log_debug("grdrm: %s: cannot assign crtc %" PRIu32 ": %s",
1021 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1024 static void grdrm_crtc_expose(grdrm_crtc *crtc) {
1031 assert(crtc->object.assigned);
1033 if (crtc->set.n_connectors < 1) {
1035 grdev_pipe_free(&crtc->pipe->base);
1042 if (pipe->base.width != crtc->set.mode.hdisplay ||
1043 pipe->base.height != crtc->set.mode.vdisplay ||
1044 pipe->base.vrefresh != crtc->set.mode.vrefresh) {
1045 grdev_pipe_free(&pipe->base);
1052 pipe->base.front = NULL;
1053 pipe->base.back = NULL;
1054 for (i = 0; i < pipe->base.max_fbs; ++i) {
1055 fb = fb_from_base(pipe->base.fbs[i]);
1056 if (fb->id == crtc->kern.used_fb)
1057 pipe->base.front = &fb->base;
1058 else if (!fb->flipid)
1059 pipe->base.back = &fb->base;
1062 r = grdrm_pipe_new(&pipe, crtc, &crtc->set.mode, 2);
1064 log_debug("grdrm: %s: cannot create pipe for crtc %" PRIu32 ": %s",
1065 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1069 for (i = 0; i < pipe->base.max_fbs; ++i) {
1070 r = grdrm_fb_new(&fb, crtc->object.card, &crtc->set.mode);
1072 log_debug("grdrm: %s: cannot allocate framebuffer for crtc %" PRIu32 ": %s",
1073 crtc->object.card->base.name, crtc->object.id, strerror(-r));
1074 grdev_pipe_free(&pipe->base);
1078 pipe->base.fbs[i] = &fb->base;
1081 pipe->base.front = NULL;
1082 pipe->base.back = pipe->base.fbs[0];
1086 grdev_pipe_ready(&crtc->pipe->base, true);
1089 static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
1090 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1091 grdrm_card *card = crtc->object.card;
1092 grdrm_pipe *pipe = crtc->pipe;
1093 grdrm_fb *fb = fb_from_base(*slot);
1102 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
1103 set_crtc.count_connectors = crtc->set.n_connectors;
1104 set_crtc.fb_id = fb->id;
1107 set_crtc.mode_valid = 1;
1108 set_crtc.mode = crtc->set.mode;
1110 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1113 log_debug("grdrm: %s: cannot set crtc %" PRIu32 ": %m",
1114 card->base.name, crtc->object.id);
1116 grdrm_card_async(card, r);
1120 if (!crtc->applied) {
1121 log_debug("grdrm: %s: crtc %" PRIu32 " applied via deep modeset",
1122 card->base.name, crtc->object.id);
1123 crtc->applied = true;
1127 pipe->base.front = &fb->base;
1130 pipe->base.flipping = false;
1131 pipe->base.flip = false;
1133 /* We cannot schedule dummy page-flips on pipes, hence, the
1134 * application would have to schedule their own frame-timers.
1135 * To avoid duplicating that everywhere, we schedule our own
1136 * timer and raise a fake FRAME event when it fires. */
1137 grdev_pipe_schedule(&pipe->base, 1);
1139 if (!pipe->base.back) {
1140 for (i = 0; i < pipe->base.max_fbs; ++i) {
1141 if (!pipe->base.fbs[i])
1144 fb = fb_from_base(pipe->base.fbs[i]);
1145 if (&fb->base == pipe->base.front)
1149 pipe->base.back = &fb->base;
1155 static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb **slot) {
1156 struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
1157 grdrm_card *card = crtc->object.card;
1158 grdrm_pipe *pipe = crtc->pipe;
1159 grdrm_fb *fb = fb_from_base(*slot);
1169 if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
1172 cnt = ++pipe->counter ? : ++pipe->counter;
1173 page_flip.fb_id = fb->id;
1174 page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
1175 page_flip.user_data = grdrm_encode_vblank_data(crtc->object.id, cnt);
1177 r = ioctl(card->fd, DRM_IOCTL_MODE_PAGE_FLIP, &page_flip);
1180 /* Avoid excessive logging on EINVAL; it is currently not
1181 * possible to see whether cards support page-flipping, so
1182 * avoid logging on each frame. */
1184 log_debug("grdrm: %s: cannot schedule page-flip on crtc %" PRIu32 ": %m",
1185 card->base.name, crtc->object.id);
1187 if (grdrm_card_async(card, r))
1193 if (!crtc->applied) {
1194 log_debug("grdrm: %s: crtc %" PRIu32 " applied via page flip",
1195 card->base.name, crtc->object.id);
1196 crtc->applied = true;
1199 pipe->base.flipping = true;
1200 pipe->base.flip = false;
1201 pipe->counter = cnt;
1205 /* Raise fake FRAME event if it takes longer than 2
1206 * frames to receive the pageflip event. We assume the
1207 * queue ran over or some other error happened. */
1208 grdev_pipe_schedule(&pipe->base, 2);
1210 if (!pipe->base.back) {
1211 for (i = 0; i < pipe->base.max_fbs; ++i) {
1212 if (!pipe->base.fbs[i])
1215 fb = fb_from_base(pipe->base.fbs[i]);
1216 if (&fb->base == pipe->base.front)
1221 pipe->base.back = &fb->base;
1229 static void grdrm_crtc_commit(grdrm_crtc *crtc) {
1230 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1231 grdrm_card *card = crtc->object.card;
1237 assert(crtc->object.assigned);
1241 /* If a crtc is not assigned any connector, we want any
1242 * previous setup to be cleared, so make sure the CRTC is
1243 * disabled. Otherwise, there might be content on the CRTC
1244 * while we run, which is not what we want.
1245 * If you want to avoid modesets on specific CRTCs, you should
1246 * still keep their assignment, but never enable the resulting
1247 * pipe. This way, we wouldn't touch it at all. */
1248 if (!crtc->applied) {
1249 crtc->applied = true;
1250 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1253 log_debug("grdrm: %s: cannot shutdown crtc %" PRIu32 ": %m",
1254 card->base.name, crtc->object.id);
1256 grdrm_card_async(card, r);
1260 log_debug("grdrm: %s: crtc %" PRIu32 " applied via shutdown",
1261 card->base.name, crtc->object.id);
1267 /* we always fully ignore disabled pipes */
1268 if (!pipe->base.enabled)
1271 assert(crtc->set.n_connectors > 0);
1273 if (pipe->base.flip)
1274 slot = &pipe->base.back;
1275 else if (!crtc->applied)
1276 slot = &pipe->base.front;
1283 r = grdrm_crtc_commit_flip(crtc, slot);
1285 /* in case we couldn't page-flip, perform deep modeset */
1286 grdrm_crtc_commit_deep(crtc, slot);
1290 static void grdrm_crtc_restore(grdrm_crtc *crtc) {
1291 struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
1292 grdrm_card *card = crtc->object.card;
1298 set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->old.connectors);
1299 set_crtc.count_connectors = crtc->old.n_connectors;
1300 set_crtc.fb_id = crtc->old.fb;
1301 set_crtc.x = crtc->old.fb_x;
1302 set_crtc.y = crtc->old.fb_y;
1303 set_crtc.gamma_size = crtc->old.gamma;
1304 set_crtc.mode_valid = crtc->old.mode_set;
1305 set_crtc.mode = crtc->old.mode;
1307 r = ioctl(card->fd, DRM_IOCTL_MODE_SETCRTC, &set_crtc);
1310 log_debug("grdrm: %s: cannot restore crtc %" PRIu32 ": %m",
1311 card->base.name, crtc->object.id);
1313 grdrm_card_async(card, r);
1318 ++crtc->pipe->counter;
1319 crtc->pipe->base.front = NULL;
1320 crtc->pipe->base.flipping = false;
1323 log_debug("grdrm: %s: crtc %" PRIu32 " restored", card->base.name, crtc->object.id);
1326 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
1327 bool flipped = false;
1329 grdrm_fb *back = NULL;
1339 /* We got a page-flip event. To be safe, we reset all FBs on the same
1340 * pipe that have smaller flipids than the flip we got as we know they
1341 * are executed in order. We need to do this to guarantee
1342 * queue-overflows or other missed events don't cause starvation.
1343 * Furthermore, if we find the exact FB this event is for, *and* this
1344 * is the most recent event, we mark it as front FB and raise a
1347 for (i = 0; i < pipe->base.max_fbs; ++i) {
1350 if (!pipe->base.fbs[i])
1353 fb = fb_from_base(pipe->base.fbs[i]);
1354 if (counter != 0 && counter == pipe->counter && fb->flipid == counter) {
1355 pipe->base.front = &fb->base;
1359 if (counter - fb->flipid < UINT16_MAX) {
1362 } else if (fb->flipid == 0) {
1367 if (!pipe->base.back)
1368 pipe->base.back = &back->base;
1371 crtc->pipe->base.flipping = false;
1372 grdev_pipe_frame(&pipe->base);
1380 static int grdrm_fb_new(grdrm_fb **out, grdrm_card *card, const struct drm_mode_modeinfo *mode) {
1381 _cleanup_(grdrm_fb_freep) grdrm_fb *fb = NULL;
1382 struct drm_mode_create_dumb create_dumb = { };
1383 struct drm_mode_map_dumb map_dumb = { };
1384 struct drm_mode_fb_cmd2 add_fb = { };
1388 assert_return(out, -EINVAL);
1389 assert_return(card, -EINVAL);
1391 fb = new0(grdrm_fb, 1);
1395 /* TODO: we should choose a compatible format of the previous CRTC
1396 * setting to allow page-flip to it. Only choose fallback if the
1397 * previous setting was crap (non xrgb32'ish). */
1400 fb->base.format = DRM_FORMAT_XRGB8888;
1401 fb->base.width = mode->hdisplay;
1402 fb->base.height = mode->vdisplay;
1404 for (i = 0; i < ELEMENTSOF(fb->base.maps); ++i)
1405 fb->base.maps[i] = MAP_FAILED;
1407 create_dumb.width = fb->base.width;
1408 create_dumb.height = fb->base.height;
1409 create_dumb.bpp = 32;
1411 r = ioctl(card->fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_dumb);
1414 log_debug("grdrm: %s: cannot create dumb buffer %" PRIu32 "x%" PRIu32": %m",
1415 card->base.name, fb->base.width, fb->base.height);
1419 fb->handles[0] = create_dumb.handle;
1420 fb->base.strides[0] = create_dumb.pitch;
1421 fb->sizes[0] = create_dumb.size;
1423 map_dumb.handle = fb->handles[0];
1425 r = ioctl(card->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_dumb);
1428 log_debug("grdrm: %s: cannot map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1429 card->base.name, fb->base.width, fb->base.height);
1433 fb->base.maps[0] = mmap(0, fb->sizes[0], PROT_WRITE, MAP_SHARED, card->fd, map_dumb.offset);
1434 if (fb->base.maps[0] == MAP_FAILED) {
1436 log_debug("grdrm: %s: cannot memory-map dumb buffer %" PRIu32 "x%" PRIu32": %m",
1437 card->base.name, fb->base.width, fb->base.height);
1441 memzero(fb->base.maps[0], fb->sizes[0]);
1443 add_fb.width = fb->base.width;
1444 add_fb.height = fb->base.height;
1445 add_fb.pixel_format = fb->base.format;
1447 memcpy(add_fb.handles, fb->handles, sizeof(fb->handles));
1448 memcpy(add_fb.pitches, fb->base.strides, sizeof(fb->base.strides));
1449 memcpy(add_fb.offsets, fb->offsets, sizeof(fb->offsets));
1451 r = ioctl(card->fd, DRM_IOCTL_MODE_ADDFB2, &add_fb);
1454 log_debug("grdrm: %s: cannot add framebuffer %" PRIu32 "x%" PRIu32": %m",
1455 card->base.name, fb->base.width, fb->base.height);
1459 fb->id = add_fb.fb_id;
1466 grdrm_fb *grdrm_fb_free(grdrm_fb *fb) {
1474 if (fb->id > 0 && fb->card->fd >= 0)
1475 ioctl(fb->card->fd, DRM_IOCTL_MODE_RMFB, fb->id);
1477 for (i = 0; i < ELEMENTSOF(fb->handles); ++i) {
1478 struct drm_mode_destroy_dumb destroy_dumb = { };
1480 if (fb->base.maps[i] != MAP_FAILED)
1481 munmap(fb->base.maps[i], fb->sizes[i]);
1483 if (fb->handles[i] > 0 && fb->card->fd >= 0) {
1484 destroy_dumb.handle = fb->handles[i];
1485 ioctl(fb->card->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_dumb);
1498 static void grdrm_pipe_name(char *out, grdrm_crtc *crtc) {
1499 /* @out must be at least of size GRDRM_PIPE_NAME_MAX */
1500 sprintf(out, "%s/%" PRIu32, crtc->object.card->base.name, crtc->object.id);
1503 static int grdrm_pipe_new(grdrm_pipe **out, grdrm_crtc *crtc, struct drm_mode_modeinfo *mode, size_t n_fbs) {
1504 _cleanup_(grdev_pipe_freep) grdev_pipe *basepipe = NULL;
1505 grdrm_card *card = crtc->object.card;
1506 char name[GRDRM_PIPE_NAME_MAX];
1510 assert_return(crtc, -EINVAL);
1511 assert_return(grdev_is_drm_card(&card->base), -EINVAL);
1513 pipe = new0(grdrm_pipe, 1);
1517 basepipe = &pipe->base;
1518 pipe->base = GRDEV_PIPE_INIT(&grdrm_pipe_vtable, &card->base);
1520 pipe->base.width = mode->hdisplay;
1521 pipe->base.height = mode->vdisplay;
1522 pipe->base.vrefresh = mode->vrefresh ? : 25;
1524 grdrm_pipe_name(name, crtc);
1525 r = grdev_pipe_add(&pipe->base, name, n_fbs);
1535 static void grdrm_pipe_free(grdev_pipe *basepipe) {
1536 grdrm_pipe *pipe = grdrm_pipe_from_base(basepipe);
1541 for (i = 0; i < pipe->base.max_fbs; ++i)
1542 if (pipe->base.fbs[i])
1543 grdrm_fb_free(fb_from_base(pipe->base.fbs[i]));
1548 static const grdev_pipe_vtable grdrm_pipe_vtable = {
1549 .free = grdrm_pipe_free,
1556 static void grdrm_name(char *out, dev_t devnum) {
1557 /* @out must be at least of size GRDRM_CARD_NAME_MAX */
1558 sprintf(out, "drm/%u:%u", major(devnum), minor(devnum));
1561 static void grdrm_card_print(grdrm_card *card) {
1562 grdrm_object *object;
1564 grdrm_encoder *encoder;
1565 grdrm_connector *connector;
1571 log_debug("grdrm: %s: state dump", card->base.name);
1573 log_debug(" crtcs:");
1574 HASHMAP_FOREACH(object, card->object_map, iter) {
1575 if (object->type != GRDRM_TYPE_CRTC)
1578 crtc = crtc_from_object(object);
1579 log_debug(" (id: %u index: %d)", object->id, object->index);
1581 if (crtc->kern.mode_set)
1582 log_debug(" mode: %dx%d", crtc->kern.mode.hdisplay, crtc->kern.mode.vdisplay);
1584 log_debug(" mode: <none>");
1587 log_debug(" encoders:");
1588 HASHMAP_FOREACH(object, card->object_map, iter) {
1589 if (object->type != GRDRM_TYPE_ENCODER)
1592 encoder = encoder_from_object(object);
1593 log_debug(" (id: %u index: %d)", object->id, object->index);
1595 if (encoder->kern.used_crtc)
1596 log_debug(" crtc: %u", encoder->kern.used_crtc);
1598 log_debug(" crtc: <none>");
1600 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_crtcs + 1);
1605 for (i = 0; i < encoder->kern.n_crtcs; ++i)
1606 p += sprintf(p, " %" PRIu32, encoder->kern.crtcs[i]);
1608 log_debug(" possible crtcs:%s", buf);
1612 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * encoder->kern.n_clones + 1);
1617 for (i = 0; i < encoder->kern.n_clones; ++i)
1618 p += sprintf(p, " %" PRIu32, encoder->kern.clones[i]);
1620 log_debug(" possible clones:%s", buf);
1625 log_debug(" connectors:");
1626 HASHMAP_FOREACH(object, card->object_map, iter) {
1627 if (object->type != GRDRM_TYPE_CONNECTOR)
1630 connector = connector_from_object(object);
1631 log_debug(" (id: %u index: %d)", object->id, object->index);
1632 log_debug(" type: %" PRIu32 "-%" PRIu32 " connection: %" PRIu32 " subpixel: %" PRIu32 " extents: %" PRIu32 "x%" PRIu32,
1633 connector->kern.type, connector->kern.type_id, connector->kern.connection, connector->kern.subpixel,
1634 connector->kern.mm_width, connector->kern.mm_height);
1636 if (connector->kern.used_encoder)
1637 log_debug(" encoder: %" PRIu32, connector->kern.used_encoder);
1639 log_debug(" encoder: <none>");
1641 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * connector->kern.n_encoders + 1);
1646 for (i = 0; i < connector->kern.n_encoders; ++i)
1647 p += sprintf(p, " %" PRIu32, connector->kern.encoders[i]);
1649 log_debug(" possible encoders:%s", buf);
1653 for (i = 0; i < connector->kern.n_modes; ++i) {
1654 struct drm_mode_modeinfo *mode = &connector->kern.modes[i];
1655 log_debug(" mode: %" PRIu32 "x%" PRIu32, mode->hdisplay, mode->vdisplay);
1659 log_debug(" planes:");
1660 HASHMAP_FOREACH(object, card->object_map, iter) {
1661 if (object->type != GRDRM_TYPE_PLANE)
1664 plane = plane_from_object(object);
1665 log_debug(" (id: %u index: %d)", object->id, object->index);
1666 log_debug(" gamma-size: %" PRIu32, plane->kern.gamma_size);
1668 if (plane->kern.used_crtc)
1669 log_debug(" crtc: %" PRIu32, plane->kern.used_crtc);
1671 log_debug(" crtc: <none>");
1673 buf = malloc((DECIMAL_STR_MAX(uint32_t) + 1) * plane->kern.n_crtcs + 1);
1678 for (i = 0; i < plane->kern.n_crtcs; ++i)
1679 p += sprintf(p, " %" PRIu32, plane->kern.crtcs[i]);
1681 log_debug(" possible crtcs:%s", buf);
1685 buf = malloc((DECIMAL_STR_MAX(unsigned int) + 3) * plane->kern.n_formats + 1);
1690 for (i = 0; i < plane->kern.n_formats; ++i)
1691 p += sprintf(p, " 0x%x", (unsigned int)plane->kern.formats[i]);
1693 log_debug(" possible formats:%s", buf);
1699 static int grdrm_card_resync(grdrm_card *card) {
1700 _cleanup_free_ uint32_t *crtc_ids = NULL, *encoder_ids = NULL, *connector_ids = NULL, *plane_ids = NULL;
1701 uint32_t allocated = 0;
1702 grdrm_object *object;
1709 card->async_hotplug = false;
1712 /* mark existing objects for possible removal */
1713 HASHMAP_FOREACH(object, card->object_map, iter)
1714 object->present = false;
1716 for (tries = 0; tries < GRDRM_MAX_TRIES; ++tries) {
1717 struct drm_mode_get_plane_res pres;
1718 struct drm_mode_card_res res;
1721 if (allocated < card->max_ids) {
1724 free(connector_ids);
1726 crtc_ids = new0(uint32_t, card->max_ids);
1727 encoder_ids = new0(uint32_t, card->max_ids);
1728 connector_ids = new0(uint32_t, card->max_ids);
1729 plane_ids = new0(uint32_t, card->max_ids);
1731 if (!crtc_ids || !encoder_ids || !connector_ids || !plane_ids)
1734 allocated = card->max_ids;
1738 res.crtc_id_ptr = PTR_TO_UINT64(crtc_ids);
1739 res.connector_id_ptr = PTR_TO_UINT64(connector_ids);
1740 res.encoder_id_ptr = PTR_TO_UINT64(encoder_ids);
1741 res.count_crtcs = allocated;
1742 res.count_encoders = allocated;
1743 res.count_connectors = allocated;
1745 r = ioctl(card->fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
1748 log_debug("grdrm: %s: cannot retrieve drm resources: %m", card->base.name);
1753 pres.plane_id_ptr = PTR_TO_UINT64(plane_ids);
1754 pres.count_planes = allocated;
1756 r = ioctl(card->fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &pres);
1759 log_debug("grdrm: %s: cannot retrieve drm plane-resources: %m", card->base.name);
1763 max = MAX(MAX(res.count_crtcs, res.count_encoders),
1764 MAX(res.count_connectors, pres.count_planes));
1765 if (max > allocated) {
1768 n = ALIGN_POWER2(max);
1769 if (!n || n > UINT16_MAX) {
1770 log_debug("grdrm: %s: excessive DRM resource limit: %" PRIu32, card->base.name, max);
1774 /* retry with resized buffers */
1779 /* mark available objects as present */
1781 for (i = 0; i < res.count_crtcs; ++i) {
1782 object = grdrm_find_object(card, crtc_ids[i]);
1783 if (object && object->type == GRDRM_TYPE_CRTC) {
1784 object->present = true;
1790 for (i = 0; i < res.count_encoders; ++i) {
1791 object = grdrm_find_object(card, encoder_ids[i]);
1792 if (object && object->type == GRDRM_TYPE_ENCODER) {
1793 object->present = true;
1799 for (i = 0; i < res.count_connectors; ++i) {
1800 object = grdrm_find_object(card, connector_ids[i]);
1801 if (object && object->type == GRDRM_TYPE_CONNECTOR) {
1802 object->present = true;
1804 connector_ids[i] = 0;
1808 for (i = 0; i < pres.count_planes; ++i) {
1809 object = grdrm_find_object(card, plane_ids[i]);
1810 if (object && object->type == GRDRM_TYPE_PLANE) {
1811 object->present = true;
1817 /* drop removed objects */
1819 HASHMAP_FOREACH(object, card->object_map, iter)
1820 if (!object->present)
1821 grdrm_object_free(object);
1823 /* add new objects */
1825 card->n_crtcs = res.count_crtcs;
1826 for (i = 0; i < res.count_crtcs; ++i) {
1827 if (crtc_ids[i] < 1)
1830 r = grdrm_crtc_new(NULL, card, crtc_ids[i], i);
1835 card->n_encoders = res.count_encoders;
1836 for (i = 0; i < res.count_encoders; ++i) {
1837 if (encoder_ids[i] < 1)
1840 r = grdrm_encoder_new(NULL, card, encoder_ids[i], i);
1845 card->n_connectors = res.count_connectors;
1846 for (i = 0; i < res.count_connectors; ++i) {
1847 if (connector_ids[i] < 1)
1850 r = grdrm_connector_new(NULL, card, connector_ids[i], i);
1855 card->n_planes = pres.count_planes;
1856 for (i = 0; i < pres.count_planes; ++i) {
1857 if (plane_ids[i] < 1)
1860 r = grdrm_plane_new(NULL, card, plane_ids[i], i);
1865 /* re-sync objects after object_map is synced */
1867 HASHMAP_FOREACH(object, card->object_map, iter) {
1868 switch (object->type) {
1869 case GRDRM_TYPE_CRTC:
1870 r = grdrm_crtc_resync(crtc_from_object(object));
1872 case GRDRM_TYPE_ENCODER:
1873 r = grdrm_encoder_resync(encoder_from_object(object));
1875 case GRDRM_TYPE_CONNECTOR:
1876 r = grdrm_connector_resync(connector_from_object(object));
1878 case GRDRM_TYPE_PLANE:
1879 r = grdrm_plane_resync(plane_from_object(object));
1882 assert_not_reached("grdrm: invalid object type");
1889 if (card->async_hotplug)
1893 /* if modeset objects change during sync, start over */
1894 if (card->async_hotplug) {
1895 card->async_hotplug = false;
1899 /* cache crtc/connector relationship */
1900 HASHMAP_FOREACH(object, card->object_map, iter) {
1901 grdrm_connector *connector;
1902 grdrm_encoder *encoder;
1905 if (object->type != GRDRM_TYPE_CONNECTOR)
1908 connector = connector_from_object(object);
1909 if (connector->kern.connection != 1 || connector->kern.used_encoder < 1)
1912 object = grdrm_find_object(card, connector->kern.used_encoder);
1913 if (!object || object->type != GRDRM_TYPE_ENCODER)
1916 encoder = encoder_from_object(object);
1917 if (encoder->kern.used_crtc < 1)
1920 object = grdrm_find_object(card, encoder->kern.used_crtc);
1921 if (!object || object->type != GRDRM_TYPE_CRTC)
1924 crtc = crtc_from_object(object);
1925 assert(crtc->kern.n_used_connectors < crtc->kern.max_used_connectors);
1926 crtc->kern.used_connectors[crtc->kern.n_used_connectors++] = connector->object.id;
1929 /* cache old crtc settings for later restore */
1930 HASHMAP_FOREACH(object, card->object_map, iter) {
1933 if (object->type != GRDRM_TYPE_CRTC)
1936 crtc = crtc_from_object(object);
1938 /* Save data if it is the first time we refresh the CRTC. This data can
1939 * be used optionally to restore any previous configuration. For
1940 * instance, it allows us to restore VT configurations after we close
1941 * our session again. */
1942 if (!crtc->old.set) {
1943 crtc->old.fb = crtc->kern.used_fb;
1944 crtc->old.fb_x = crtc->kern.fb_offset_x;
1945 crtc->old.fb_y = crtc->kern.fb_offset_y;
1946 crtc->old.gamma = crtc->kern.gamma_size;
1947 crtc->old.n_connectors = crtc->kern.n_used_connectors;
1948 if (crtc->old.n_connectors)
1949 memcpy(crtc->old.connectors, crtc->kern.used_connectors, sizeof(uint32_t) * crtc->old.n_connectors);
1950 crtc->old.mode_set = crtc->kern.mode_set;
1951 crtc->old.mode = crtc->kern.mode;
1952 crtc->old.set = true;
1956 /* everything synced */
1960 if (tries >= GRDRM_MAX_TRIES) {
1962 * Ugh! We were unable to sync the DRM card state due to heavy
1963 * hotplugging. This should never happen, so print a debug
1964 * message and bail out. The next uevent will trigger
1968 log_debug("grdrm: %s: hotplug-storm when syncing card", card->base.name);
1975 static bool card_configure_crtc(grdrm_crtc *crtc, grdrm_connector *connector) {
1976 grdrm_card *card = crtc->object.card;
1977 grdrm_encoder *encoder;
1978 grdrm_object *object;
1981 if (crtc->object.assigned || connector->object.assigned)
1983 if (connector->kern.connection != 1)
1986 for (i = 0; i < connector->kern.n_encoders; ++i) {
1987 object = grdrm_find_object(card, connector->kern.encoders[i]);
1988 if (!object || object->type != GRDRM_TYPE_ENCODER)
1991 encoder = encoder_from_object(object);
1992 for (j = 0; j < encoder->kern.n_crtcs; ++j) {
1993 if (encoder->kern.crtcs[j] == crtc->object.id) {
1994 grdrm_crtc_assign(crtc, connector);
2003 static void grdrm_card_configure(grdrm_card *card) {
2005 * Modeset Configuration
2006 * This is where we update our modeset configuration and assign
2007 * connectors to CRTCs. This means, each connector that we want to
2008 * enable needs a CRTC, disabled (or unavailable) connectors are left
2009 * alone in the dark. Once all CRTCs are assigned, the remaining CRTCs
2011 * Sounds trivial, but there're several caveats:
2013 * * Multiple connectors can be driven by the same CRTC. This is
2014 * known as 'hardware clone mode'. Advantage over software clone
2015 * mode is that only a single CRTC is needed to drive multiple
2016 * displays. However, few hardware supports this and it's a huge
2017 * headache to configure on dynamic demands. Therefore, we only
2018 * support it if configured statically beforehand.
2020 * * CRTCs are not created equal. Some might be much more poweful
2021 * than others, including more advanced plane support. So far, our
2022 * CRTC selection is random. You need to supply static
2023 * configuration if you want special setups. So far, there is no
2024 * proper way to do advanced CRTC selection on dynamic demands. It
2025 * is not really clear which demands require what CRTC, so, like
2026 * everyone else, we do random CRTC selection unless explicitly
2029 * * Each Connector has a list of possible encoders that can drive
2030 * it, and each encoder has a list of possible CRTCs. If this graph
2031 * is a tree, assignment is trivial. However, if not, we cannot
2032 * reliably decide on configurations beforehand. The encoder is
2033 * always selected by the kernel, so we have to actually set a mode
2034 * to know which encoder is used. There is no way to ask the kernel
2035 * whether a given configuration is possible. This will change with
2036 * atomic-modesetting, but until then, we keep our configurations
2037 * simple and assume they work all just fine. If one fails
2038 * unexpectedly, we print a warning and disable it.
2040 * Configuring a card consists of several steps:
2042 * 1) First of all, we apply any user-configuration. If a user wants
2043 * a fixed configuration, we apply it and preserve it.
2044 * So far, we don't support user configuration files, so this step
2047 * 2) Secondly, we need to apply any quirks from hwdb. Some hardware
2048 * might only support limited configurations or require special
2049 * CRTC/Connector mappings. We read this from hwdb and apply it, if
2051 * So far, we don't support this as there is no known quirk, so
2052 * this step is skipped.
2054 * 3) As deep modesets are expensive, we try to avoid them if
2055 * possible. Therefore, we read the current configuration from the
2056 * kernel and try to preserve it, if compatible with our demands.
2057 * If not, we break it and reassign it in a following step.
2059 * 4) The main step involves configuring all remaining objects. By
2060 * default, all available connectors are enabled, except for those
2061 * disabled by user-configuration. We lookup a suitable CRTC for
2062 * each connector and assign them. As there might be more
2063 * connectors than CRTCs, we apply some ordering so users can
2064 * select which connectors are more important right now.
2065 * So far, we only apply the default ordering, more might be added
2069 grdrm_object *object;
2073 /* clear assignments */
2074 HASHMAP_FOREACH(object, card->object_map, i)
2075 object->assigned = false;
2077 /* preserve existing configurations */
2078 HASHMAP_FOREACH(object, card->object_map, i) {
2079 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2082 crtc = crtc_from_object(object);
2084 if (crtc->applied) {
2085 /* If our mode is set, preserve it. If no connector is
2086 * set, modeset either failed or the pipe is unused. In
2087 * both cases, leave it alone. It might be tried again
2088 * below in case there're remaining connectors.
2089 * Otherwise, try restoring the assignments. If they
2090 * are no longer valid, leave the pipe untouched. */
2092 if (crtc->set.n_connectors < 1)
2095 assert(crtc->set.n_connectors == 1);
2097 object = grdrm_find_object(card, crtc->set.connectors[0]);
2098 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2101 card_configure_crtc(crtc, connector_from_object(object));
2102 } else if (crtc->kern.mode_set && crtc->kern.n_used_connectors != 1) {
2103 /* If our mode is not set on the pipe, we know the kern
2104 * information is valid. Try keeping it. If it's not
2105 * possible, leave the pipe untouched for later
2108 object = grdrm_find_object(card, crtc->kern.used_connectors[0]);
2109 if (!object || object->type != GRDRM_TYPE_CONNECTOR)
2112 card_configure_crtc(crtc, connector_from_object(object));
2116 /* assign remaining objects */
2117 HASHMAP_FOREACH(object, card->object_map, i) {
2118 if (object->type != GRDRM_TYPE_CRTC || object->assigned)
2121 crtc = crtc_from_object(object);
2123 HASHMAP_FOREACH(object, card->object_map, j) {
2124 if (object->type != GRDRM_TYPE_CONNECTOR)
2127 if (card_configure_crtc(crtc, connector_from_object(object)))
2131 if (!crtc->object.assigned)
2132 grdrm_crtc_assign(crtc, NULL);
2135 /* expose configuration */
2136 HASHMAP_FOREACH(object, card->object_map, i) {
2137 if (object->type != GRDRM_TYPE_CRTC)
2140 grdrm_crtc_expose(crtc_from_object(object));
2144 static void grdrm_card_hotplug(grdrm_card *card) {
2152 log_debug("grdrm: %s/%s: reconfigure card", card->base.session->name, card->base.name);
2154 card->ready = false;
2155 r = grdrm_card_resync(card);
2157 log_debug("grdrm: %s/%s: cannot re-sync card: %s",
2158 card->base.session->name, card->base.name, strerror(-r));
2162 grdev_session_pin(card->base.session);
2164 /* debug statement to print card information */
2166 grdrm_card_print(card);
2168 grdrm_card_configure(card);
2171 grdev_session_unpin(card->base.session);
2174 static int grdrm_card_io_fn(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2175 grdrm_card *card = userdata;
2176 struct drm_event_vblank *vblank;
2177 struct drm_event *event;
2178 uint32_t id, counter;
2179 grdrm_object *object;
2183 if (revents & (EPOLLHUP | EPOLLERR)) {
2184 /* Immediately close device on HUP; no need to flush pending
2185 * data.. there're no events we care about here. */
2186 log_debug("grdrm: %s/%s: HUP", card->base.session->name, card->base.name);
2187 grdrm_card_close(card);
2191 if (revents & (EPOLLIN)) {
2192 l = read(card->fd, buf, sizeof(buf));
2194 if (errno == EAGAIN || errno == EINTR)
2197 log_debug("grdrm: %s/%s: read error: %m", card->base.session->name, card->base.name);
2198 grdrm_card_close(card);
2200 } else if ((size_t)l < sizeof(*event)) {
2201 log_debug("grdrm: %s/%s: short read of %zd bytes", card->base.session->name, card->base.name, l);
2205 for (i = 0; i < l; i += event->length) {
2206 event = (void*)&buf[i];
2208 if (i + event->length > l) {
2209 log_debug("grdrm: %s/%s: truncated event", card->base.session->name, card->base.name);
2213 switch (event->type) {
2214 case DRM_EVENT_FLIP_COMPLETE:
2215 vblank = (void*)event;
2216 if (event->length < sizeof(*vblank)) {
2217 log_debug("grdrm: %s/%s: truncated vblank event", card->base.session->name, card->base.name);
2221 grdrm_decode_vblank_data(vblank->user_data, &id, &counter);
2222 object = grdrm_find_object(card, id);
2223 if (!object || object->type != GRDRM_TYPE_CRTC)
2226 grdrm_crtc_flip_complete(crtc_from_object(object), counter, vblank);
2235 static int grdrm_card_add(grdrm_card *card, const char *name) {
2237 assert(card->fd < 0);
2239 card->object_map = hashmap_new(&trivial_hash_ops);
2240 if (!card->object_map)
2243 return grdev_card_add(&card->base, name);
2246 static void grdrm_card_destroy(grdrm_card *card) {
2248 assert(!card->running);
2249 assert(card->fd < 0);
2250 assert(hashmap_size(card->object_map) == 0);
2252 hashmap_free(card->object_map);
2255 static void grdrm_card_commit(grdev_card *basecard) {
2256 grdrm_card *card = grdrm_card_from_base(basecard);
2257 grdrm_object *object;
2260 HASHMAP_FOREACH(object, card->object_map, iter) {
2264 if (object->type != GRDRM_TYPE_CRTC)
2267 grdrm_crtc_commit(crtc_from_object(object));
2271 static void grdrm_card_restore(grdev_card *basecard) {
2272 grdrm_card *card = grdrm_card_from_base(basecard);
2273 grdrm_object *object;
2276 HASHMAP_FOREACH(object, card->object_map, iter) {
2280 if (object->type != GRDRM_TYPE_CRTC)
2283 grdrm_crtc_restore(crtc_from_object(object));
2287 static void grdrm_card_enable(grdrm_card *card) {
2290 if (card->fd < 0 || card->running)
2293 /* ignore cards without DUMB_BUFFER capability */
2294 if (!card->cap_dumb)
2297 assert(card->fd_src);
2299 log_debug("grdrm: %s/%s: enable", card->base.session->name, card->base.name);
2301 card->running = true;
2302 sd_event_source_set_enabled(card->fd_src, SD_EVENT_ON);
2303 grdrm_card_hotplug(card);
2306 static void grdrm_card_disable(grdrm_card *card) {
2307 grdrm_object *object;
2312 if (card->fd < 0 || !card->running)
2315 assert(card->fd_src);
2317 log_debug("grdrm: %s/%s: disable", card->base.session->name, card->base.name);
2319 card->running = false;
2320 card->ready = false;
2321 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2323 /* stop all pipes */
2324 HASHMAP_FOREACH(object, card->object_map, iter) {
2327 if (object->type != GRDRM_TYPE_CRTC)
2330 crtc = crtc_from_object(object);
2331 crtc->applied = false;
2333 grdev_pipe_ready(&crtc->pipe->base, false);
2337 static int grdrm_card_open(grdrm_card *card, int dev_fd) {
2338 _cleanup_(grdev_session_unpinp) grdev_session *pin = NULL;
2339 _cleanup_close_ int fd = dev_fd;
2340 struct drm_get_cap cap;
2344 assert(dev_fd >= 0);
2345 assert(card->fd != dev_fd);
2347 pin = grdev_session_pin(card->base.session);
2348 grdrm_card_close(card);
2350 log_debug("grdrm: %s/%s: open", card->base.session->name, card->base.name);
2352 r = fd_nonblock(fd, true);
2356 r = fd_cloexec(fd, true);
2360 flags = fcntl(fd, F_GETFL, 0);
2363 if ((flags & O_ACCMODE) != O_RDWR)
2366 r = sd_event_add_io(card->base.session->context->event,
2369 EPOLLHUP | EPOLLERR | EPOLLIN,
2375 sd_event_source_set_enabled(card->fd_src, SD_EVENT_OFF);
2380 /* cache DUMB_BUFFER capability */
2381 cap.capability = DRM_CAP_DUMB_BUFFER;
2383 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2384 card->cap_dumb = r >= 0 && cap.value;
2386 log_debug("grdrm: %s/%s: cannot retrieve DUMB_BUFFER capability: %s",
2387 card->base.session->name, card->base.name, strerror(-r));
2388 else if (!card->cap_dumb)
2389 log_debug("grdrm: %s/%s: DUMB_BUFFER capability not supported",
2390 card->base.session->name, card->base.name);
2392 /* cache TIMESTAMP_MONOTONIC capability */
2393 cap.capability = DRM_CAP_TIMESTAMP_MONOTONIC;
2395 r = ioctl(card->fd, DRM_IOCTL_GET_CAP, &cap);
2396 card->cap_monotonic = r >= 0 && cap.value;
2398 log_debug("grdrm: %s/%s: cannot retrieve TIMESTAMP_MONOTONIC capability: %s",
2399 card->base.session->name, card->base.name, strerror(-r));
2400 else if (!card->cap_monotonic)
2401 log_debug("grdrm: %s/%s: TIMESTAMP_MONOTONIC is disabled globally, fix this NOW!",
2402 card->base.session->name, card->base.name);
2407 static void grdrm_card_close(grdrm_card *card) {
2408 grdrm_object *object;
2413 log_debug("grdrm: %s/%s: close", card->base.session->name, card->base.name);
2415 grdrm_card_disable(card);
2417 card->fd_src = sd_event_source_unref(card->fd_src);
2418 card->fd = safe_close(card->fd);
2420 grdev_session_pin(card->base.session);
2421 while ((object = hashmap_first(card->object_map)))
2422 grdrm_object_free(object);
2423 grdev_session_unpin(card->base.session);
2426 static bool grdrm_card_async(grdrm_card *card, int r) {
2429 /* If we get EACCES on runtime DRM calls, we lost DRM-Master
2430 * (or we did something terribly wrong). Immediately disable
2431 * the card, so we stop all pipes and wait to be activated
2433 grdrm_card_disable(card);
2436 /* DRM objects can be hotplugged at any time. If an object is
2437 * removed that we use, we remember that state so a following
2438 * call can test for this.
2439 * Note that we also get a uevent as followup, this will resync
2440 * the whole device. */
2441 card->async_hotplug = true;
2445 return !card->ready;
2450 * The unmanaged DRM card opens the device node for a given DRM device
2451 * directly (/dev/dri/cardX) and thus needs sufficient privileges. It opens
2452 * the device only if we really require it and releases it as soon as we're
2453 * disabled or closed.
2454 * The unmanaged element can be used in all situations where you have direct
2455 * access to DRM device nodes. Unlike managed DRM elements, it can be used
2456 * outside of user sessions and in emergency situations where logind is not
2460 static void unmanaged_card_enable(grdev_card *basecard) {
2461 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2464 if (cu->card.fd < 0) {
2465 /* try open on activation if it failed during allocation */
2466 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2468 /* not fatal; simply ignore the device */
2469 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2470 basecard->session->name, basecard->name, cu->devnode);
2474 /* we might already be DRM-Master by open(); that's fine */
2476 r = grdrm_card_open(&cu->card, fd);
2478 log_debug("grdrm: %s/%s: cannot open: %s",
2479 basecard->session->name, basecard->name, strerror(-r));
2484 r = ioctl(cu->card.fd, DRM_IOCTL_SET_MASTER, 0);
2486 log_debug("grdrm: %s/%s: cannot acquire DRM-Master: %m",
2487 basecard->session->name, basecard->name);
2491 grdrm_card_enable(&cu->card);
2494 static void unmanaged_card_disable(grdev_card *basecard) {
2495 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2497 grdrm_card_disable(&cu->card);
2500 static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2501 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2502 char name[GRDRM_CARD_NAME_MAX];
2504 const char *devnode;
2508 assert_return(session, -EINVAL);
2509 assert_return(ud, -EINVAL);
2511 devnode = udev_device_get_devnode(ud);
2512 devnum = udev_device_get_devnum(ud);
2513 if (!devnode || devnum == 0)
2516 grdrm_name(name, devnum);
2518 cu = new0(unmanaged_card, 1);
2522 basecard = &cu->card.base;
2523 cu->card = GRDRM_CARD_INIT(&unmanaged_card_vtable, session);
2525 cu->devnode = strdup(devnode);
2529 r = grdrm_card_add(&cu->card, name);
2533 /* try to open but ignore errors */
2534 fd = open(cu->devnode, O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
2536 /* not fatal; allow uaccess based control on activation */
2537 log_debug("grdrm: %s/%s: cannot open node %s: %m",
2538 basecard->session->name, basecard->name, cu->devnode);
2540 /* We might get DRM-Master implicitly on open(); drop it immediately
2541 * so we acquire it only once we're actually enabled. */
2542 ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2544 r = grdrm_card_open(&cu->card, fd);
2546 log_debug("grdrm: %s/%s: cannot open: %s",
2547 basecard->session->name, basecard->name, strerror(-r));
2556 static void unmanaged_card_free(grdev_card *basecard) {
2557 unmanaged_card *cu = unmanaged_card_from_base(basecard);
2559 assert(!basecard->enabled);
2561 grdrm_card_close(&cu->card);
2562 grdrm_card_destroy(&cu->card);
2567 static const grdev_card_vtable unmanaged_card_vtable = {
2568 .free = unmanaged_card_free,
2569 .enable = unmanaged_card_enable,
2570 .disable = unmanaged_card_disable,
2571 .commit = grdrm_card_commit,
2572 .restore = grdrm_card_restore,
2577 * The managed DRM card uses systemd-logind to acquire DRM devices. This
2578 * means, we do not open the device node /dev/dri/cardX directly. Instead,
2579 * logind passes us a file-descriptor whenever our session is activated. Thus,
2580 * we don't need access to the device node directly.
2581 * Furthermore, whenever the session is put asleep, logind revokes the
2582 * file-descriptor so we loose access to the device.
2583 * Managed DRM cards should be preferred over unmanaged DRM cards whenever
2584 * you run inside a user session with exclusive device access.
2587 static void managed_card_enable(grdev_card *card) {
2588 managed_card *cm = managed_card_from_base(card);
2590 /* If the device is manually re-enabled, we try to resume our card
2591 * management. Note that we have no control over DRM-Master and the fd,
2592 * so we have to take over the state from the last logind event. */
2595 grdrm_card_enable(&cm->card);
2598 static void managed_card_disable(grdev_card *card) {
2599 managed_card *cm = managed_card_from_base(card);
2601 /* If the device is manually disabled, we keep the FD but put our card
2602 * management asleep. This way, we can wake up at any time, but don't
2603 * touch the device while asleep. */
2605 grdrm_card_disable(&cm->card);
2608 static int managed_card_pause_device_fn(sd_bus *bus,
2609 sd_bus_message *signal,
2611 sd_bus_error *ret_error) {
2612 managed_card *cm = userdata;
2613 grdev_session *session = cm->card.base.session;
2614 uint32_t major, minor;
2619 * We get PauseDevice() signals from logind whenever a device we
2620 * requested was, or is about to be, paused. Arguments are major/minor
2621 * number of the device and the mode of the operation.
2622 * In case the event is not about our device, we ignore it. Otherwise,
2623 * we treat it as asynchronous DRM-DROP-MASTER. Note that we might have
2624 * already handled an EACCES error from a modeset ioctl, in which case
2625 * we already disabled the device.
2627 * @mode can be one of the following:
2628 * "pause": The device is about to be paused. We must react
2629 * immediately and respond with PauseDeviceComplete(). Once
2630 * we replied, logind will pause the device. Note that
2631 * logind might apply any kind of timeout and force pause
2632 * the device if we don't respond in a timely manner. In
2633 * this case, we will receive a second PauseDevice event
2634 * with @mode set to "force" (or similar).
2635 * "force": The device was disabled forecfully by logind. DRM-Master
2636 * was already dropped. This is just an asynchronous
2637 * notification so we can put the device asleep (in case
2638 * we didn't already notice the dropped DRM-Master).
2639 * "gone": This is like "force" but is sent if the device was
2640 * paused due to a device-removal event.
2642 * We always handle PauseDevice signals as "force" as we properly
2643 * support asynchronously dropping DRM-Master, anyway. But in case
2644 * logind sent mode "pause", we also call PauseDeviceComplete() to
2645 * immediately acknowledge the request.
2648 r = sd_bus_message_read(signal, "uus", &major, &minor, &mode);
2650 log_debug("grdrm: %s/%s: erroneous PauseDevice signal",
2651 session->name, cm->card.base.name);
2655 /* not our device? */
2656 if (makedev(major, minor) != cm->devnum)
2660 grdrm_card_disable(&cm->card);
2662 if (streq(mode, "pause")) {
2663 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2666 * Sending PauseDeviceComplete() is racy if logind triggers the
2667 * timeout. That is, if we take too long and logind pauses the
2668 * device by sending a forced PauseDevice, our
2669 * PauseDeviceComplete call will be stray. That's fine, though.
2670 * logind ignores such stray calls. Only if logind also sent a
2671 * further PauseDevice() signal, it might match our call
2672 * incorrectly to the newer PauseDevice(). That's fine, too, as
2673 * we handle that event asynchronously, anyway. Therefore,
2674 * whatever happens, we're fine. Yay!
2677 r = sd_bus_message_new_method_call(session->context->sysbus,
2679 "org.freedesktop.login1",
2681 "org.freedesktop.login1.Session",
2682 "PauseDeviceComplete");
2684 r = sd_bus_message_append(m, "uu", major, minor);
2686 r = sd_bus_send(session->context->sysbus, m, NULL);
2690 log_debug("grdrm: %s/%s: cannot send PauseDeviceComplete: %s",
2691 session->name, cm->card.base.name, strerror(-r));
2697 static int managed_card_resume_device_fn(sd_bus *bus,
2698 sd_bus_message *signal,
2700 sd_bus_error *ret_error) {
2701 managed_card *cm = userdata;
2702 grdev_session *session = cm->card.base.session;
2703 uint32_t major, minor;
2707 * We get ResumeDevice signals whenever logind resumed a previously
2708 * paused device. The arguments contain the major/minor number of the
2709 * related device and a new file-descriptor for the freshly opened
2711 * If the signal is not about our device, we simply ignore it.
2712 * Otherwise, we immediately resume the device. Note that we drop the
2713 * new file-descriptor as we already have one from TakeDevice(). logind
2714 * preserves the file-context across pause/resume for DRM but only
2715 * drops/acquires DRM-Master accordingly. This way, our context (like
2716 * DRM-FBs and BOs) is preserved.
2719 r = sd_bus_message_read(signal, "uuh", &major, &minor, &fd);
2721 log_debug("grdrm: %s/%s: erroneous ResumeDevice signal",
2722 session->name, cm->card.base.name);
2726 /* not our device? */
2727 if (makedev(major, minor) != cm->devnum)
2730 if (cm->card.fd < 0) {
2731 /* This shouldn't happen. We should already own an FD from
2732 * TakeDevice(). However, lets be safe and use this FD in case
2733 * we really don't have one. There is no harm in doing this
2734 * and our code works fine this way. */
2735 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2737 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2738 session->name, cm->card.base.name);
2742 r = grdrm_card_open(&cm->card, fd);
2744 log_debug("grdrm: %s/%s: cannot open: %s",
2745 session->name, cm->card.base.name, strerror(-r));
2751 if (cm->card.base.enabled)
2752 grdrm_card_enable(&cm->card);
2757 static int managed_card_setup_bus(managed_card *cm) {
2758 grdev_session *session = cm->card.base.session;
2759 _cleanup_free_ char *match = NULL;
2762 match = strjoin("type='signal',"
2763 "sender='org.freedesktop.login1',"
2764 "interface='org.freedesktop.login1.Session',"
2765 "member='PauseDevice',"
2766 "path='", session->path, "'",
2771 r = sd_bus_add_match(session->context->sysbus,
2772 &cm->slot_pause_device,
2774 managed_card_pause_device_fn,
2780 match = strjoin("type='signal',"
2781 "sender='org.freedesktop.login1',"
2782 "interface='org.freedesktop.login1.Session',"
2783 "member='ResumeDevice',"
2784 "path='", session->path, "'",
2789 r = sd_bus_add_match(session->context->sysbus,
2790 &cm->slot_resume_device,
2792 managed_card_resume_device_fn,
2800 static int managed_card_take_device_fn(sd_bus *bus,
2801 sd_bus_message *reply,
2803 sd_bus_error *ret_error) {
2804 managed_card *cm = userdata;
2805 grdev_session *session = cm->card.base.session;
2808 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2810 if (sd_bus_message_is_method_error(reply, NULL)) {
2811 const sd_bus_error *error = sd_bus_message_get_error(reply);
2813 log_debug("grdrm: %s/%s: TakeDevice failed: %s: %s",
2814 session->name, cm->card.base.name, error->name, error->message);
2818 cm->acquired = true;
2820 r = sd_bus_message_read(reply, "hb", &fd, &paused);
2822 log_debug("grdrm: %s/%s: erroneous TakeDevice reply",
2823 session->name, cm->card.base.name);
2827 fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
2829 log_debug("grdrm: %s/%s: cannot duplicate fd: %m",
2830 session->name, cm->card.base.name);
2834 r = grdrm_card_open(&cm->card, fd);
2836 log_debug("grdrm: %s/%s: cannot open: %s",
2837 session->name, cm->card.base.name, strerror(-r));
2841 if (!paused && cm->card.base.enabled)
2842 grdrm_card_enable(&cm->card);
2847 static void managed_card_take_device(managed_card *cm) {
2848 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2849 grdev_session *session = cm->card.base.session;
2852 r = sd_bus_message_new_method_call(session->context->sysbus,
2854 "org.freedesktop.login1",
2856 "org.freedesktop.login1.Session",
2861 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2865 r = sd_bus_call_async(session->context->sysbus,
2866 &cm->slot_take_device,
2868 managed_card_take_device_fn,
2874 cm->requested = true;
2878 log_debug("grdrm: %s/%s: cannot send TakeDevice request: %s",
2879 session->name, cm->card.base.name, strerror(-r));
2882 static void managed_card_release_device(managed_card *cm) {
2883 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2884 grdev_session *session = cm->card.base.session;
2888 * If TakeDevice() is pending or was successful, make sure to
2889 * release the device again. We don't care for return-values,
2890 * so send it without waiting or callbacks.
2891 * If a failed TakeDevice() is pending, but someone else took
2892 * the device on the same bus-connection, we might incorrectly
2893 * release their device. This is an unlikely race, though.
2894 * Furthermore, you really shouldn't have two users of the
2895 * controller-API on the same session, on the same devices, *AND* on
2896 * the same bus-connection. So we don't care for that race..
2899 grdrm_card_close(&cm->card);
2900 cm->requested = false;
2902 if (!cm->acquired && !cm->slot_take_device)
2905 cm->slot_take_device = sd_bus_slot_unref(cm->slot_take_device);
2906 cm->acquired = false;
2908 r = sd_bus_message_new_method_call(session->context->sysbus,
2910 "org.freedesktop.login1",
2912 "org.freedesktop.login1.Session",
2915 r = sd_bus_message_append(m, "uu", major(cm->devnum), minor(cm->devnum));
2917 r = sd_bus_send(session->context->sysbus, m, NULL);
2920 if (r < 0 && r != -ENOTCONN)
2921 log_debug("grdrm: %s/%s: cannot send ReleaseDevice: %s",
2922 session->name, cm->card.base.name, strerror(-r));
2925 static int managed_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
2926 _cleanup_(grdev_card_freep) grdev_card *basecard = NULL;
2927 char name[GRDRM_CARD_NAME_MAX];
2932 assert_return(session, -EINVAL);
2933 assert_return(session->managed, -EINVAL);
2934 assert_return(session->context->sysbus, -EINVAL);
2935 assert_return(ud, -EINVAL);
2937 devnum = udev_device_get_devnum(ud);
2941 grdrm_name(name, devnum);
2943 cm = new0(managed_card, 1);
2947 basecard = &cm->card.base;
2948 cm->card = GRDRM_CARD_INIT(&managed_card_vtable, session);
2949 cm->devnum = devnum;
2951 r = managed_card_setup_bus(cm);
2955 r = grdrm_card_add(&cm->card, name);
2959 managed_card_take_device(cm);
2967 static void managed_card_free(grdev_card *basecard) {
2968 managed_card *cm = managed_card_from_base(basecard);
2970 assert(!basecard->enabled);
2972 managed_card_release_device(cm);
2973 cm->slot_resume_device = sd_bus_slot_unref(cm->slot_resume_device);
2974 cm->slot_pause_device = sd_bus_slot_unref(cm->slot_pause_device);
2975 grdrm_card_destroy(&cm->card);
2979 static const grdev_card_vtable managed_card_vtable = {
2980 .free = managed_card_free,
2981 .enable = managed_card_enable,
2982 .disable = managed_card_disable,
2983 .commit = grdrm_card_commit,
2984 .restore = grdrm_card_restore,
2988 * Generic Constructor
2989 * Instead of relying on the caller to choose between managed and unmanaged
2990 * DRM devices, the grdev_drm_new() constructor does that for you (by
2991 * looking at session->managed).
2994 bool grdev_is_drm_card(grdev_card *basecard) {
2995 return basecard && (basecard->vtable == &unmanaged_card_vtable ||
2996 basecard->vtable == &managed_card_vtable);
2999 grdev_card *grdev_find_drm_card(grdev_session *session, dev_t devnum) {
3000 char name[GRDRM_CARD_NAME_MAX];
3002 assert_return(session, NULL);
3003 assert_return(devnum != 0, NULL);
3005 grdrm_name(name, devnum);
3006 return grdev_find_card(session, name);
3009 int grdev_drm_card_new(grdev_card **out, grdev_session *session, struct udev_device *ud) {
3010 assert_return(session, -EINVAL);
3011 assert_return(ud, -EINVAL);
3013 return session->managed ? managed_card_new(out, session, ud) : unmanaged_card_new(out, session, ud);
3016 void grdev_drm_card_hotplug(grdev_card *basecard, struct udev_device *ud) {
3017 const char *p, *action;
3022 assert(grdev_is_drm_card(basecard));
3025 card = grdrm_card_from_base(basecard);
3027 action = udev_device_get_action(ud);
3028 if (!action || streq(action, "add") || streq(action, "remove")) {
3029 /* If we get add/remove events on DRM nodes without devnum, we
3030 * got hotplugged DRM objects so refresh the device. */
3031 devnum = udev_device_get_devnum(ud);
3033 grdrm_card_hotplug(card);
3034 } else if (streq_ptr(action, "change")) {
3035 /* A change event with HOTPLUG=1 is sent whenever a connector
3036 * changed state. Refresh the device to update our state. */
3037 p = udev_device_get_property_value(ud, "HOTPLUG");
3038 if (streq_ptr(p, "1"))
3039 grdrm_card_hotplug(card);