summaryrefslogtreecommitdiff
path: root/src/armada_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/armada_module.c')
-rw-r--r--src/armada_module.c177
1 files changed, 167 insertions, 10 deletions
diff --git a/src/armada_module.c b/src/armada_module.c
index 8b50442..eef3c75 100644
--- a/src/armada_module.c
+++ b/src/armada_module.c
@@ -8,6 +8,15 @@
#include "config.h"
#endif
+#include <errno.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+#include "xf86.h"
+#ifdef XSERVER_PLATFORM_BUS
+#include "xf86platformBus.h"
+#endif
+
#include "armada_drm.h"
#include "armada_accel.h"
#include "common_drm.h"
@@ -17,6 +26,11 @@
#define ARMADA_NAME "armada"
#define ARMADA_DRIVER_NAME "armada"
+#define DRM_MODULE_NAMES "armada-drm", "imx-drm"
+#define DRM_DEFAULT_BUS_ID NULL
+
+static const char *drm_module_names[] = { DRM_MODULE_NAMES };
+
/* Supported "chipsets" */
static SymTabRec armada_chipsets[] = {
// { 0, "88AP16x" },
@@ -101,6 +115,16 @@ static void armada_identify(int flags)
ipu_chipsets);
}
+static void armada_init_screen(ScrnInfoPtr pScrn)
+{
+ pScrn->driverVersion = ARMADA_VERSION;
+ pScrn->driverName = ARMADA_DRIVER_NAME;
+ pScrn->name = ARMADA_NAME;
+ pScrn->Probe = NULL;
+
+ armada_drm_init_screen(pScrn);
+}
+
static Bool armada_probe(DriverPtr drv, int flags)
{
GDevPtr *devSections;
@@ -116,22 +140,38 @@ static Bool armada_probe(DriverPtr drv, int flags)
for (i = 0; i < numDevSections; i++) {
ScrnInfoPtr pScrn;
- int entity;
+ const char *busid = DRM_DEFAULT_BUS_ID;
+ int entity, fd, j;
+
+ if (devSections[i]->busID)
+ busid = devSections[i]->busID;
+
+ for (j = 0; j < ARRAY_SIZE(drm_module_names); j++) {
+ fd = drmOpen(drm_module_names[j], busid);
+ if (fd >= 0)
+ break;
+ }
+
+ if (fd < 0)
+ continue;
+
+ if (!common_drm_fd_is_master(fd))
+ continue;
entity = xf86ClaimNoSlot(drv, 0, devSections[i], TRUE);
+ common_alloc_dev(entity, fd, NULL, TRUE);
+
pScrn = xf86ConfigFbEntity(NULL, 0, entity,
NULL, NULL, NULL, NULL);
+ if (!pScrn)
+ continue;
- if (pScrn) {
- foundScreen = TRUE;
+ if (busid)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using BusID \"%s\"\n", busid);
- pScrn->driverVersion = ARMADA_VERSION;
- pScrn->driverName = ARMADA_DRIVER_NAME;
- pScrn->name = ARMADA_NAME;
- pScrn->Probe = NULL;
-
- armada_drm_init_screen(pScrn);
- }
+ foundScreen = TRUE;
+ armada_init_screen(pScrn);
}
free(devSections);
@@ -166,11 +206,125 @@ armada_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer ptr)
flag = (CARD32*)ptr;
(*flag) = 0;
return TRUE;
+#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
+ case SUPPORTS_SERVER_FDS:
+ return TRUE;
+#endif
default:
return FALSE;
}
}
+#ifdef XSERVER_PLATFORM_BUS
+static Bool armada_is_kms(int fd)
+{
+ drmVersionPtr version;
+ drmModeResPtr res;
+ Bool has_connectors;
+
+ version = drmGetVersion(fd);
+ if (!version)
+ return FALSE;
+ drmFreeVersion(version);
+
+ res = drmModeGetResources(fd);
+ if (!res)
+ return FALSE;
+
+ has_connectors = res->count_connectors > 0;
+ drmModeFreeResources(res);
+
+ return has_connectors;
+}
+
+static struct common_drm_device *armada_create_dev(int entity_num,
+ struct xf86_platform_device *dev)
+{
+ struct common_drm_device *drm_dev;
+ const char *path;
+ Bool ddx_managed_master;
+ int fd, our_fd = -1;
+
+ path = xf86_get_platform_device_attrib(dev, ODEV_ATTRIB_PATH);
+ if (!path)
+ goto err_free;
+
+#ifdef ODEV_ATTRIB_FD
+ fd = xf86_get_platform_device_int_attrib(dev, ODEV_ATTRIB_FD, -1);
+#else
+ fd = -1;
+#endif
+ if (fd != -1) {
+ ddx_managed_master = FALSE;
+ if (!armada_is_kms(fd))
+ goto err_free;
+ } else {
+ ddx_managed_master = TRUE;
+ our_fd = open(path, O_RDWR | O_NONBLOCK | O_CLOEXEC);
+ if (our_fd == -1)
+ goto err_free;
+
+ if (!armada_is_kms(our_fd)) {
+ close(our_fd);
+ goto err_free;
+ }
+
+ if (!common_drm_fd_is_master(our_fd)) {
+ close(our_fd);
+ goto err_free;
+ }
+
+ fd = our_fd;
+ }
+
+ /* If we're running unprivileged, don't drop master status */
+ if (geteuid())
+ ddx_managed_master = FALSE;
+
+ drm_dev = common_alloc_dev(entity_num, fd, path, ddx_managed_master);
+ if (!drm_dev && our_fd != -1)
+ close(our_fd);
+
+ return drm_dev;
+
+ err_free:
+ return NULL;
+}
+
+static int armada_create_screen(DriverPtr drv, int entity_num,
+ struct common_drm_device *drm_dev)
+{
+ ScrnInfoPtr pScrn;
+
+ pScrn = xf86AllocateScreen(drv, 0);
+ if (!pScrn)
+ return FALSE;
+
+ xf86AddEntityToScreen(pScrn, entity_num);
+
+ armada_init_screen(pScrn);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Added screen for KMS device %s\n", drm_dev->kms_path);
+
+ return TRUE;
+}
+
+static Bool armada_platform_probe(DriverPtr drv, int entity_num, int flags,
+ struct xf86_platform_device *dev, intptr_t match_data)
+{
+ struct common_drm_device *drm_dev;
+
+ drm_dev = common_entity_get_dev(entity_num);
+ if (!drm_dev)
+ drm_dev = armada_create_dev(entity_num, dev);
+ if (!drm_dev)
+ return FALSE;
+
+ return armada_create_screen(drv, entity_num, drm_dev);
+}
+#endif
+
_X_EXPORT DriverRec armada_driver = {
.driverVersion = ARMADA_VERSION,
.driverName = ARMADA_DRIVER_NAME,
@@ -178,6 +332,9 @@ _X_EXPORT DriverRec armada_driver = {
.Probe = armada_probe,
.AvailableOptions = armada_available_options,
.driverFunc = armada_driver_func,
+#ifdef XSERVER_PLATFORM_BUS
+ .platformProbe = armada_platform_probe,
+#endif
};
#ifdef XFree86LOADER