[Xf86-video-armsoc] [RFC] Dynamically detect which drmmode driver to use

Heiko Stübner heiko at sntech.de
Wed Jul 22 15:40:35 PDT 2015


From: Daniel Drake <drake at endlessm.com>

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(-)

diff --git a/configure.ac b/configure.ac
index eeffd92..f476653 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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)
diff --git a/src/Makefile.am b/src/Makefile.am
index e9fe871..75bdc51 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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_ at drmmode@/drmmode_ at drmmode@.c
+DRMMODE_SRCS = drmmode_exynos/drmmode_exynos.c \
+	drmmode_pl111/drmmode_pl111.c
 
 armsoc_drv_la_SOURCES = \
          drmmode_display.c \
diff --git a/src/armsoc_driver.c b/src/armsoc_driver.c
index cbb982b..64f4d21 100644
--- a/src/armsoc_driver.c
+++ b/src/armsoc_driver.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;
 
diff --git a/src/drmmode_driver.h b/src/drmmode_driver.h
index aa31d2b..9497216 100644
--- a/src/drmmode_driver.h
+++ b/src/drmmode_driver.h
@@ -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
diff --git a/src/drmmode_exynos/drmmode_exynos.c b/src/drmmode_exynos/drmmode_exynos.c
index 5985cfd..f9f9911 100644
--- a/src/drmmode_exynos/drmmode_exynos.c
+++ b/src/drmmode_exynos/drmmode_exynos.c
@@ -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;
-}
diff --git a/src/drmmode_pl111/drmmode_pl111.c b/src/drmmode_pl111/drmmode_pl111.c
index 7b52168..f825951 100644
--- a/src/drmmode_pl111/drmmode_pl111.c
+++ b/src/drmmode_pl111/drmmode_pl111.c
@@ -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;
-}
diff --git a/src/drmmode_template/drmmode_template.c b/src/drmmode_template/drmmode_template.c
index 3330a58..72888d6 100644
--- a/src/drmmode_template/drmmode_template.c
+++ b/src/drmmode_template/drmmode_template.c
@@ -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;
-}
-
-- 
2.1.4




More information about the Xf86-video-armsoc mailing list