Check kms device in find primary gpu 62/295662/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 12 Jul 2023 06:24:07 +0000 (15:24 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Wed, 12 Jul 2023 07:35:10 +0000 (16:35 +0900)
Change-Id: I4a8904d4e12062e8fb8f94b2276741230f2ec50a

src/tbm_backend_dumb.c

index b313a90..b3bbd2c 100644 (file)
@@ -46,6 +46,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <fcntl.h>
 #include <errno.h>
 #include <xf86drm.h>
+#include <xf86drmMode.h>
 #include <pthread.h>
 #include <hal-common.h>
 #include <hal-tbm-types.h>
@@ -147,83 +148,139 @@ static uint32_t tbm_dumb_color_format_list[TBM_COLOR_FORMAT_COUNT] = {
 };
 
 static int
-_tbm_dumb_open_drm()
+_tbm_dumb_is_kms(struct udev_device *device)
 {
-       struct udev *udev = NULL;
-       struct udev_enumerate *e = NULL;
-       struct udev_list_entry *entry = NULL;
-       struct udev_device *device = NULL, *drm_device = NULL, *pci = NULL;
-       const char *filepath, *id;
-       struct stat s;
-       int fd = -1;
-       int ret;
+       drmModeRes *res;
+       int fd = -1, id = -1;
+       const char *file_name;
+       const char *sys_num;
+
+       file_name = udev_device_get_devnode(device);
+       if (!file_name) return 0;
+
+       TBM_BACKEND_INFO("check kms device:%s", file_name);
+
+       sys_num = udev_device_get_sysnum(device);
+       if (!sys_num) return 0;
+
+       id = atoi(sys_num);
+       if (id < 0) return 0;
+
+       fd = open(file_name, O_RDWR | O_CLOEXEC);
+       if (fd < 0) {
+               TBM_BACKEND_ERR("Cannot open drm device(%s)", file_name);
+               return 0;
+       }
+
+       res = drmModeGetResources(fd);
+       if (!res) goto fail;
+
+       if ((res->count_crtcs <= 0) || (res->count_connectors <= 0) ||
+               (res->count_encoders <= 0))
+               goto fail;
+
+       close(fd);
+       drmModeFreeResources(res);
+
+       return 1;
+
+fail:
+       if (fd >= 0) close(fd);
+       if (res) drmModeFreeResources(res);
+
+       return 0;
+}
+
+static struct udev_device *
+_tbm_dumb_find_primary_gpu(void)
+{
+       struct udev *udev;
+       struct udev_enumerate *e;
+       struct udev_list_entry *entry;
+       const char *path, *id;
+       struct udev_device *device, *drm_device, *pci;
 
        udev = udev_new();
        if (!udev) {
-               TBM_BACKEND_ERR("udev_new() failed.\n");
-               return -1;
+               TBM_BACKEND_ERR("fail to initialize udev context\n");
+               return NULL;
        }
 
        e = udev_enumerate_new(udev);
        udev_enumerate_add_match_subsystem(e, "drm");
        udev_enumerate_add_match_sysname(e, "card[0-9]*");
-       udev_enumerate_scan_devices(e);
 
+       udev_enumerate_scan_devices(e);
        drm_device = NULL;
        udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e)) {
-               filepath = udev_list_entry_get_name(entry);
-               device = udev_device_new_from_syspath(udev, filepath);
+               int is_boot_vga;
+
+               path = udev_list_entry_get_name(entry);
+               device = udev_device_new_from_syspath(udev, path);
                if (!device)
                        continue;
 
-               pci = udev_device_get_parent_with_subsystem_devtype(device, "pci", NULL);
+               pci = udev_device_get_parent_with_subsystem_devtype(device,
+                                               "pci", NULL);
                if (pci) {
                        id = udev_device_get_sysattr_value(pci, "boot_vga");
-                       if (id && !strcmp(id, "1")) {
-                               if (drm_device)
-                               udev_device_unref(drm_device);
-                               drm_device = device;
-                               break;
-                       }
+                       if (id && !strcmp(id, "1"))
+                               is_boot_vga = 1;
                }
 
-               if (!drm_device)
-                       drm_device = device;
-               else
+               if (!is_boot_vga && drm_device) {
+                       udev_device_unref(device);
+                       continue;
+               }
+
+               if (!_tbm_dumb_is_kms(device)) {
                        udev_device_unref(device);
+                       continue;
+               }
+
+               if (is_boot_vga) {
+                       if (drm_device)
+                               udev_device_unref(drm_device);
+                       drm_device = device;
+                       break;
+               }
+
+               drm_device = device;
        }
 
        udev_enumerate_unref(e);
 
-       /* Get device file path. */
-       filepath = udev_device_get_devnode(drm_device);
-       if (!filepath) {
-               TBM_BACKEND_ERR("udev_device_get_devnode() failed.\n");
-               udev_device_unref(drm_device);
-               udev_unref(udev);
-               return -1;
+       return drm_device;
+}
+
+static int
+_tbm_dumb_open_drm(void)
+{
+       int fd = -1;
+       struct udev_device *drm_device = NULL;
+       const char *file_name;
+
+       drm_device = _tbm_dumb_find_primary_gpu();
+       if (!drm_device) {
+               TBM_BACKEND_ERR("fail to find drm device");
+               goto ret;
        }
 
-       /* Open DRM device file and check validity. */
-       fd = open(filepath, O_RDWR | O_CLOEXEC);
-       if (fd < 0) {
-               TBM_BACKEND_ERR("open(%s, O_RDWR | O_CLOEXEC) failed.\n");
-               udev_device_unref(drm_device);
-               udev_unref(udev);
-               return -1;
+       file_name = udev_device_get_devnode(drm_device);
+       if (!file_name) {
+               TBM_BACKEND_ERR("fail to get devnode");
+               goto ret;
        }
 
-       ret = fstat(fd, &s);
-       if (ret) {
-               TBM_BACKEND_ERR("fstat() failed %s.\n");
-               close(fd);
-               udev_device_unref(drm_device);
-               udev_unref(udev);
-               return -1;
+       fd = open(file_name, O_RDWR | O_CLOEXEC);
+       if (fd < 0) {
+               TBM_BACKEND_ERR("Cannot open drm device(%s)", file_name);
+               goto ret;
        }
 
-       udev_device_unref(drm_device);
-       udev_unref(udev);
+       TBM_BACKEND_INFO("open drm device (name:%s, fd:%d)", file_name, fd);
+ret:
+       if (drm_device) udev_device_unref(drm_device);
 
        return fd;
 }