From: Daniel Drake <drake@...>
By querying the DRM driver name from the kernel, we can dynamically
select the right backend. No need to enforce a specific backend at
compile time.
I've pulled this out of the xf86-video-armsoc fork from Endlessm [0]
which they seem to use on a Meson platform.
I really like that concept as deciding on the platform at compile
time is really cumbersome and having numerous binaries also wastes
space, especially as the actual per-soc code part is quite minimal.
I skimmed through the list archives but it doesn't look like this
change was discussed so far.
And I'm currently basing my rockchip support [1] on this too ;-) .
Heiko
[0] https://github.com/endlessm/xf86-video-armsoc
[1] https://github.com/mmind/xf86-video-armsoc/tree/devel/rockchip
configure.ac | 9 ---------
src/Makefile.am | 3 ++-
src/armsoc_driver.c | 30 +++++++++++++++++++++++++++++-
src/drmmode_driver.h | 6 +++++-
src/drmmode_exynos/drmmode_exynos.c | 6 +-----
src/drmmode_pl111/drmmode_pl111.c | 6 +-----
src/drmmode_template/drmmode_template.c | 6 ------
7 files changed, 38 insertions(+), 28 deletions(-)
@@ -58,15 +58,6 @@ AC_ARG_WITH(xorg-module-dir,
[moduledir="$withval"],
[moduledir="$libdir/xorg/modules"])
-AC_MSG_CHECKING([which DRM driver to use])
-AC_ARG_WITH(drmmode,
- AS_HELP_STRING([--with-drmmode],
- [Which DRM driver to use (see README)]),
- [drmmode=$withval],
- AC_MSG_FAILURE([You must specify which DRM driver to build for - see README]))
-AC_MSG_RESULT([$drmmode])
-AC_SUBST(drmmode)
-
# Checks for extensions
XORG_DRIVER_CHECK_EXT(RANDR, randrproto)
XORG_DRIVER_CHECK_EXT(RENDER, renderproto)
@@ -40,7 +40,8 @@ armsoc_drv_la_LTLIBRARIES = armsoc_drv.la
armsoc_drv_la_LDFLAGS = -module -avoid-version -no-undefined
armsoc_drv_la_LIBADD = @XORG_LIBS@
armsoc_drv_ladir = @moduledir@/drivers
-DRMMODE_SRCS = drmmode_@drmmode@/drmmode_@drmmode@.c
+DRMMODE_SRCS = drmmode_exynos/drmmode_exynos.c \
+ drmmode_pl111/drmmode_pl111.c
armsoc_drv_la_SOURCES = \
drmmode_display.c \
@@ -726,6 +726,34 @@ out:
return foundScreen;
}
+/* Find a drmmode driver with the same name as the underlying
+ * drm kernel driver */
+static struct drmmode_interface *get_drmmode_implementation(int drm_fd)
+{
+ drmVersionPtr version;
+ struct drmmode_interface *ret = NULL;
+ struct drmmode_interface *ifaces[] = {
+ &exynos_interface,
+ &pl111_interface,
+ };
+ int i;
+
+ version = drmGetVersion(drm_fd);
+ if (!version)
+ return NULL;
+
+ for (i = 0; i < ARRAY_SIZE(ifaces); i++) {
+ struct drmmode_interface *iface = ifaces[i];
+ if (strcmp(version->name, iface->driver_name) == 0) {
+ ret = iface;
+ break;
+ }
+ }
+
+ drmFreeVersion(version);
+ return ret;
+}
+
/**
* The driver's PreInit() function. Additional hardware probing is allowed
* now, including display configuration.
@@ -809,7 +837,7 @@ ARMSOCPreInit(ScrnInfoPtr pScrn, int flags)
goto fail;
pARMSOC->drmmode_interface =
- drmmode_interface_get_implementation(pARMSOC->drmFD);
+ get_drmmode_implementation(pARMSOC->drmFD);
if (!pARMSOC->drmmode_interface)
goto fail2;
@@ -38,6 +38,9 @@ enum hwcursor_api {
};
struct drmmode_interface {
+ /* Must match name used in the kernel driver */
+ const char *driver_name;
+
/* Boolean value indicating whether DRM page flip events should
* be requested and waited for during DRM_IOCTL_MODE_PAGE_FLIP.
*/
@@ -99,6 +102,7 @@ struct drmmode_interface {
int (*create_custom_gem)(int fd, struct armsoc_create_gem *create_gem);
};
-struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd);
+extern struct drmmode_interface exynos_interface;
+extern struct drmmode_interface pl111_interface;
#endif
@@ -145,6 +145,7 @@ static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
}
struct drmmode_interface exynos_interface = {
+ "exynos" /* name of drm driver */,
1 /* use_page_flip_events */,
1 /* use_early_display */,
CURSORW /* cursor width */,
@@ -155,8 +156,3 @@ struct drmmode_interface exynos_interface = {
0 /* vblank_query_supported */,
create_custom_gem /* create_custom_gem */,
};
-
-struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)
-{
- return &exynos_interface;
-}
@@ -106,6 +106,7 @@ static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem)
}
struct drmmode_interface pl111_interface = {
+ "pl111" /* name of drm driver */,
1 /* use_page_flip_events */,
1 /* use_early_display */,
CURSORW /* cursor width */,
@@ -116,8 +117,3 @@ struct drmmode_interface pl111_interface = {
0 /* vblank_query_supported */,
create_custom_gem /* create_custom_gem */,
};
-
-struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)
-{
- return &pl111_interface;
-}
@@ -63,9 +63,3 @@ struct drmmode_interface template_interface = {
0 /* vblank_query_supported */,
create_custom_gem /* create_custom_gem */,
};
-
-struct drmmode_interface *drmmode_interface_get_implementation(int drm_fd)
-{
- return &template_interface;
-}
-