OpenByFB is introduced to overcome GPU driver loading order issue on a device with multiple GPUs, e.g. Intel iGPU and Nvidia dGPU where the first drmfb kernel module loaded will become device file /dev/dri/card0 and the second will become /dev/dri/card1 The use case is to prefer Intel iGPU over dGPU, or viceversa, in a deterministic and reliable manner. OpenByFB function opens the DRM device with specified fb and node type, thus enabling gralloc to open the correct device node of the primary fb, regardless of the GPU driver loading order. Signed-off-by: Chih-Wei Huang <cwhuang@xxxxxxxxxxxx> --- core-symbols.txt | 1 + xf86drm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ xf86drm.h | 1 + 3 files changed, 44 insertions(+) diff --git a/core-symbols.txt b/core-symbols.txt index 1ff4ecaa..6bf8c70d 100644 --- a/core-symbols.txt +++ b/core-symbols.txt @@ -146,6 +146,7 @@ drmModeSetCursor2 drmModeSetPlane drmMsg drmOpen +drmOpenByFB drmOpenControl drmOpenOnce drmOpenOnceWithType diff --git a/xf86drm.c b/xf86drm.c index b49d42f7..229a54bf 100644 --- a/xf86drm.c +++ b/xf86drm.c @@ -793,6 +793,48 @@ drm_public int drmOpenRender(int minor) return drmOpenMinor(minor, 0, DRM_NODE_RENDER); } +/** + * Open the DRM device with specified type of specified framebuffer. + * + * Looks up the associated DRM device with specified type of the + * specified framebuffer and opens it. + * + * \param fb the index of framebuffer. + * \param type the device node type to open, PRIMARY, CONTROL or RENDER + * + * \return a file descriptor on success, or a negative value on error. + * + */ +drm_public int drmOpenByFB(int fb, int type) +{ +#ifdef __linux__ + DIR *sysdir; + struct dirent *ent; + char buf[64]; + const char *name = drmGetMinorName(type); + int fd = -1, len = strlen(name); + + snprintf(buf, sizeof(buf), "/sys/class/graphics/fb%d/device/drm", fb); + sysdir = opendir(buf); + if (!sysdir) + return -errno; + + while ((ent = readdir(sysdir))) { + if (!strncmp(ent->d_name, name, len)) { + snprintf(buf, sizeof(buf), "%s/%s", DRM_DIR_NAME, ent->d_name); + fd = open(buf, O_RDWR | O_CLOEXEC, 0); + break; + } + } + + closedir(sysdir); + return fd; +#else +#warning "Missing implementation of drmOpenByFB" + return -EINVAL; +#endif +} + /** * Free the version information returned by drmGetVersion(). * diff --git a/xf86drm.h b/xf86drm.h index 7b85079a..d45d696f 100644 --- a/xf86drm.h +++ b/xf86drm.h @@ -605,6 +605,7 @@ extern int drmOpenWithType(const char *name, const char *busid, extern int drmOpenControl(int minor); extern int drmOpenRender(int minor); +extern int drmOpenByFB(int fb, int type); extern int drmClose(int fd); extern drmVersionPtr drmGetVersion(int fd); extern drmVersionPtr drmGetLibVersion(int fd); -- 2.25.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel