[PATCH xserver 2/2] modesetting: Load on GPU-s with 0 outputs

Hans de Goede hdegoede at redhat.com
Thu Jun 16 13:37:52 UTC 2016


In newer laptops with switchable graphics, the GPU may have 0 outputs,
in this case the modesetting driver should still load if the GPU is
SourceOffload capable, so that it can be used as an offload source provider.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 hw/xfree86/drivers/modesetting/driver.c          | 29 ++++++++++++++++++------
 hw/xfree86/drivers/modesetting/drmmode_display.c |  6 ++---
 2 files changed, 24 insertions(+), 11 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index d786b3e..9c78087 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -214,14 +214,26 @@ open_hw(const char *dev)
 }
 
 static int
-check_outputs(int fd)
+check_outputs(int fd, int *count)
 {
     drmModeResPtr res = drmModeGetResources(fd);
     int ret;
 
     if (!res)
         return FALSE;
+
+    if (count)
+        *count = res->count_connectors;
+
     ret = res->count_connectors > 0;
+#if defined DRM_CAP_PRIME && GLAMOR_HAS_GBM_LINEAR
+    if (ret == FALSE) {
+        uint64_t value = 0;
+        if (drmGetCap(fd, DRM_CAP_PRIME, &value) == 0 &&
+                (value & DRM_PRIME_CAP_EXPORT))
+            ret = TRUE;
+    }
+#endif
     drmModeFreeResources(res);
     return ret;
 }
@@ -236,13 +248,13 @@ probe_hw(const char *dev, struct xf86_platform_device *platform_dev)
         fd = xf86_platform_device_odev_attributes(platform_dev)->fd;
         if (fd == -1)
             return FALSE;
-        return check_outputs(fd);
+        return check_outputs(fd, NULL);
     }
 #endif
 
     fd = open_hw(dev);
     if (fd != -1) {
-        int ret = check_outputs(fd);
+        int ret = check_outputs(fd, NULL);
 
         close(fd);
         return ret;
@@ -285,7 +297,7 @@ probe_hw_pci(const char *dev, struct pci_device *pdev)
     devid = ms_DRICreatePCIBusID(pdev);
 
     if (id && devid && !strcmp(id, devid))
-        ret = check_outputs(fd);
+        ret = check_outputs(fd, NULL);
 
     close(fd);
     free(id);
@@ -783,7 +795,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
     EntityInfoPtr pEnt;
     uint64_t value = 0;
     int ret;
-    int bppflags;
+    int bppflags, connector_count;
     int defaultdepth, defaultbpp;
 
     if (pScrn->numEntities != 1)
@@ -820,6 +832,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
         return FALSE;
     ms->drmmode.fd = ms->fd;
 
+    if (!check_outputs(ms->fd, &connector_count))
+        return FALSE;
+
     drmmode_get_default_bpp(pScrn, &ms->drmmode, &defaultdepth, &defaultbpp);
     if (defaultdepth == 24 && defaultbpp == 24)
         bppflags = SupportConvert32to24 | Support24bppFb;
@@ -899,7 +914,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
 #ifdef DRM_CAP_PRIME
     ret = drmGetCap(ms->fd, DRM_CAP_PRIME, &value);
     if (ret == 0) {
-        if (value & DRM_PRIME_CAP_IMPORT) {
+        if (connector_count && (value & DRM_PRIME_CAP_IMPORT)) {
             pScrn->capabilities |= RR_Capability_SinkOutput;
             if (ms->drmmode.glamor)
                 pScrn->capabilities |= RR_Capability_SinkOffload;
@@ -927,7 +942,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
         }
     }
 
-    if (pScrn->modes == NULL) {
+    if (!(pScrn->is_gpu && connector_count == 0) && pScrn->modes == NULL) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
         return FALSE;
     }
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 7e5901a..f220100 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -1692,10 +1692,8 @@ static Bool
 drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
 {
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    drmmode_crtc_private_ptr
-        drmmode_crtc = xf86_config->crtc[0]->driver_private;
-    drmmode_ptr drmmode = drmmode_crtc->drmmode;
+    modesettingPtr ms = modesettingPTR(scrn);
+    drmmode_ptr drmmode = &ms->drmmode;
     drmmode_bo old_front;
     ScreenPtr screen = xf86ScrnToScreen(scrn);
     uint32_t old_fb_id;
-- 
2.7.4



More information about the xorg-devel mailing list