summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel@collabora.com>2019-07-20 09:41:23 -0300
committerEzequiel Garcia <ezequiel@collabora.com>2019-07-30 11:07:03 -0300
commitf632b23a528ed6b4e1fddd774db005c30ab65568 (patch)
tree226882275b78abe3552ba0b4702b53ad16cc1abb
parente888ea1d233b2639b87a68e099d18d4e919905df (diff)
drm: Find a proper modeset device, is none is provided
Instead of having a fixed /dev/dri/card0 default, iterate over primary devices until one with modeset capabilities is found. This is quite useful when a render-only driver (such as lima or panfrost) was registered before the modeset driver, taking over /dev/dri/card0. While here, add a warning for devices explicitly set via -D, by checking if they look like a modeset device. Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
-rw-r--r--drm-common.c60
-rw-r--r--kmscube.c2
2 files changed, 58 insertions, 4 deletions
diff --git a/drm-common.c b/drm-common.c
index 3fa56e8..b9d61c1 100644
--- a/drm-common.c
+++ b/drm-common.c
@@ -27,6 +27,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include "common.h"
#include "drm-common.h"
@@ -160,21 +161,74 @@ static uint32_t find_crtc_for_connector(const struct drm *drm, const drmModeRes
return -1;
}
+static int get_resources(int fd, drmModeRes **resources)
+{
+ *resources = drmModeGetResources(fd);
+ if (*resources == NULL)
+ return -1;
+ return 0;
+}
+
+#define MAX_DRM_DEVICES 64
+
+static int find_drm_device(drmModeRes **resources)
+{
+ drmDevicePtr devices[MAX_DRM_DEVICES] = { NULL };
+ int num_devices, fd = -1;
+
+ num_devices = drmGetDevices2(0, devices, MAX_DRM_DEVICES);
+ if (num_devices < 0) {
+ printf("drmGetDevices2 failed: %s\n", strerror(-num_devices));
+ return -1;
+ }
+
+ for (int i = 0; i < num_devices; i++) {
+ drmDevicePtr device = devices[i];
+ int ret;
+
+ if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY)))
+ continue;
+ /* OK, it's a primary device. If we can get the
+ * drmModeResources, it means it's also a
+ * KMS-capable device.
+ */
+ fd = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR);
+ if (fd < 0)
+ continue;
+ ret = get_resources(fd, resources);
+ if (!ret)
+ break;
+ close(fd);
+ fd = -1;
+ }
+ drmFreeDevices(devices, num_devices);
+
+ if (fd < 0)
+ printf("no drm device found!\n");
+ return fd;
+}
+
int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh)
{
drmModeRes *resources;
drmModeConnector *connector = NULL;
drmModeEncoder *encoder = NULL;
- int i, area;
+ int i, ret, area;
- drm->fd = open(device, O_RDWR);
+ if (device) {
+ drm->fd = open(device, O_RDWR);
+ ret = get_resources(drm->fd, &resources);
+ if (ret < 0 && errno == EOPNOTSUPP)
+ printf("%s does not look like a modeset device\n", device);
+ } else {
+ drm->fd = find_drm_device(&resources);
+ }
if (drm->fd < 0) {
printf("could not open drm device\n");
return -1;
}
- resources = drmModeGetResources(drm->fd);
if (!resources) {
printf("drmModeGetResources failed: %s\n", strerror(errno));
return -1;
diff --git a/kmscube.c b/kmscube.c
index 81803be..90de638 100644
--- a/kmscube.c
+++ b/kmscube.c
@@ -76,7 +76,7 @@ static void usage(const char *name)
int main(int argc, char *argv[])
{
- const char *device = "/dev/dri/card0";
+ const char *device = NULL;
const char *video = NULL;
char mode_str[DRM_DISPLAY_MODE_LEN] = "";
char *p;