diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 51e56270e..ebaab00a1 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -815,16 +815,39 @@ void xf86platformVTProbe(void) void xf86platformPrimary(void) { - /* use the first platform device as a fallback */ - if (primaryBus.type == BUS_NONE) { - xf86Msg(X_INFO, "no primary bus or device found\n"); + struct xf86_platform_device *dev; + struct OdevAttributes *attribs; + int i; - if (xf86_num_platform_devices > 0) { - primaryBus.id.plat = &xf86_platform_devices[0]; + /* only deal when no primary device has been detected */ + if (primaryBus.type != BUS_NONE) + return; + + /* set it to the first platform device detected with output connector capabilities */ + for (i = 0; i < xf86_num_platform_devices; i++) { + dev = &xf86_platform_devices[i]; + attribs = xf86_platform_device_odev_attributes(dev); + + if (attribs->num_connectors > 0) { + primaryBus.id.plat = dev; primaryBus.type = BUS_PLATFORM; - xf86Msg(X_NONE, "\tfalling back to %s\n", primaryBus.id.plat->attribs->syspath); + xf86Msg(X_INFO, "Choose %s as primary device\n", attribs->syspath); + return; } } + + /* finally, use the first platform device as a fallback */ + xf86Msg(X_INFO, "no primary bus or device found\n"); + + if (xf86_num_platform_devices > 0) { + dev = &xf86_platform_devices[0]; + attribs = xf86_platform_device_odev_attributes(dev); + + primaryBus.id.plat = dev; + primaryBus.type = BUS_PLATFORM; + + xf86Msg(X_NONE, "\tfalling back to %s\n", attribs->syspath); + } } #endif diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h index cd616ea85..1e71274a9 100644 --- a/hw/xfree86/common/xf86platformBus.h +++ b/hw/xfree86/common/xf86platformBus.h @@ -81,19 +81,21 @@ xf86_platform_odev_attributes(int index) */ /* path to kernel device node - Linux e.g. /dev/dri/card0 */ -#define ODEV_ATTRIB_PATH 1 +#define ODEV_ATTRIB_PATH 1 /* system device path - Linux e.g. /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/drm/card1 */ -#define ODEV_ATTRIB_SYSPATH 2 +#define ODEV_ATTRIB_SYSPATH 2 /* DRI-style bus id */ -#define ODEV_ATTRIB_BUSID 3 +#define ODEV_ATTRIB_BUSID 3 /* Server managed FD */ -#define ODEV_ATTRIB_FD 4 +#define ODEV_ATTRIB_FD 4 /* Major number of the device node pointed to by ODEV_ATTRIB_PATH */ -#define ODEV_ATTRIB_MAJOR 5 +#define ODEV_ATTRIB_MAJOR 5 /* Minor number of the device node pointed to by ODEV_ATTRIB_PATH */ -#define ODEV_ATTRIB_MINOR 6 +#define ODEV_ATTRIB_MINOR 6 /* kernel driver name */ -#define ODEV_ATTRIB_DRIVER 7 +#define ODEV_ATTRIB_DRIVER 7 +/* Amount of display connectors */ +#define ODEV_ATTRIB_NUM_CONNECTORS 8 /* Protect against a mismatch attribute type by generating a compiler * error using a negative array size when an incorrect attribute is @@ -127,7 +129,7 @@ _xf86_get_platform_device_attrib(struct xf86_platform_device *device, int attrib #define xf86_get_platform_device_attrib(device, attrib) _xf86_get_platform_device_attrib(device,attrib,_ODEV_ATTRIB_STRING_CHECK(attrib)) -#define _ODEV_ATTRIB_IS_INT(x) ((x) == ODEV_ATTRIB_FD || (x) == ODEV_ATTRIB_MAJOR || (x) == ODEV_ATTRIB_MINOR) +#define _ODEV_ATTRIB_IS_INT(x) ((x) == ODEV_ATTRIB_FD || (x) == ODEV_ATTRIB_MAJOR || (x) == ODEV_ATTRIB_MINOR || (x) == ODEV_ATTRIB_NUM_CONNECTORS) #define _ODEV_ATTRIB_INT_DEFAULT(x) ((x) == ODEV_ATTRIB_FD ? -1 : 0) #define _ODEV_ATTRIB_DEFAULT_CHECK(x,def) (_ODEV_ATTRIB_INT_DEFAULT(x) == (def)) #define _ODEV_ATTRIB_INT_CHECK(x,def) ((int (*)[_ODEV_ATTRIB_IS_INT(x)*_ODEV_ATTRIB_DEFAULT_CHECK(x,def)-1]) 0) @@ -142,6 +144,8 @@ _xf86_get_platform_device_int_attrib(struct xf86_platform_device *device, int at return xf86_platform_device_odev_attributes(device)->major; case ODEV_ATTRIB_MINOR: return xf86_platform_device_odev_attributes(device)->minor; + case ODEV_ATTRIB_NUM_CONNECTORS: + return xf86_platform_device_odev_attributes(device)->num_connectors; default: assert(FALSE); return 0; diff --git a/hw/xfree86/os-support/shared/drm_platform.c b/hw/xfree86/os-support/shared/drm_platform.c index 90013573c..f6cd9762e 100644 --- a/hw/xfree86/os-support/shared/drm_platform.c +++ b/hw/xfree86/os-support/shared/drm_platform.c @@ -5,6 +5,7 @@ #ifdef XSERVER_PLATFORM_BUS #include +#include #include #include #include @@ -20,6 +21,22 @@ #include "hotplug.h" #include "systemd-logind.h" +static int +CountConnectors(int fd) +{ + int connectors = 0; + drmModeResPtr res; + + res = drmModeGetResources(fd); + if (!res) + return 0; + + connectors = res->count_connectors; + drmModeFreeResources(res); + + return connectors; +} + static Bool get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) { @@ -66,6 +83,10 @@ get_drm_info(struct OdevAttributes *attribs, char *path, int delayed_index) xf86_platform_odev_attributes(delayed_index)->driver = XNFstrdup(v->name); drmFreeVersion(v); + xf86_platform_odev_attributes(delayed_index)->num_connectors = CountConnectors(fd); + xf86DrvMsg(-1, X_DEBUG, "%s has %d connectors\n", + path, xf86_platform_odev_attributes(delayed_index)->num_connectors); + out: if (!server_fd) close(fd); diff --git a/include/hotplug.h b/include/hotplug.h index 6fe76c806..f6b07c4b8 100644 --- a/include/hotplug.h +++ b/include/hotplug.h @@ -35,7 +35,7 @@ extern _X_EXPORT void config_fini(void); /* Bump this each time you add something to the struct * so that drivers can easily tell what is available */ -#define ODEV_ATTRIBUTES_VERSION 1 +#define ODEV_ATTRIBUTES_VERSION 2 struct OdevAttributes { /* path to kernel device node - Linux e.g. /dev/dri/card0 */ @@ -58,6 +58,9 @@ struct OdevAttributes { /* kernel driver name */ char *driver; + + /* Amount of display connectors */ + int num_connectors; }; /* Note starting with xserver 1.16 this function never fails */