[PATCH xf86-video-ati 3/3] Allow up to six instances in Zaphod mode

Michel Dänzer michel at daenzer.net
Wed Oct 24 16:40:19 UTC 2018


From: Michel Dänzer <michel.daenzer at amd.com>

Corresponding to up to six CRTCs being available in the hardware.

(Ported from amdgpu commit c9d43c1deb9a9cfc41a8d6439caf46d12d220853)

Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
 src/drmmode_display.c | 38 ++++++++++++++++++++-------------
 src/radeon.h          |  2 +-
 src/radeon_kms.c      | 49 ++++++++++++++++++++-----------------------
 src/radeon_probe.h    |  4 ++--
 4 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 32ffe84ed..fbdf5e6d1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -2060,9 +2060,7 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_r
 			if (!RADEONZaphodStringMatches(pScrn, s, name))
 				goto out_free_encoders;
 		} else {
-			if (!info->IsSecondary && (num != 0))
-				goto out_free_encoders;
-			else if (info->IsSecondary && (num != 1))
+			if (info->instance_id != num)
 				goto out_free_encoders;
 		}
 	}
@@ -2680,6 +2678,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	int i, num_dvi = 0, num_hdmi = 0;
 	drmModeResPtr mode_res;
 	unsigned int crtcs_needed = 0;
+	unsigned int crtcs_got = 0;
 	char *bus_id_string, *provider_name;
 
 	xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
@@ -2718,16 +2717,26 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
 	drmmode->count_crtcs = mode_res->count_crtcs;
 	xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width, mode_res->max_height);
 
-	for (i = 0; i < mode_res->count_crtcs; i++)
+	for (i = 0; i < mode_res->count_crtcs; i++) {
 		if (!xf86IsEntityShared(pScrn->entityList[0]) ||
-		    (crtcs_needed && !(pRADEONEnt->assigned_crtcs & (1 << i))))
-			crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
+		    (crtcs_got < crtcs_needed &&
+		     !(pRADEONEnt->assigned_crtcs & (1 << i))))
+			crtcs_got += drmmode_crtc_init(pScrn, drmmode, mode_res, i);
+	}
 
 	/* All ZaphodHeads outputs provided with matching crtcs? */
-	if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
+	if (crtcs_got < crtcs_needed) {
+		if (crtcs_got == 0) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   "No ZaphodHeads CRTC available, needed %u\n",
+				   crtcs_needed);
+			return FALSE;
+		}
+
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 			   "%d ZaphodHeads crtcs unavailable. Some outputs will stay off.\n",
 			   crtcs_needed);
+	}
 
 	/* workout clones */
 	drmmode_clones_init(pScrn, drmmode, mode_res);
@@ -3170,13 +3179,14 @@ restart_destroy:
 
 	/* find new output ids we don't have outputs for */
 	for (i = 0; i < mode_res->count_connectors; i++) {
-		if (drmmode_find_output(pRADEONEnt->primary_scrn,
-					mode_res->connectors[i],
-					&num_dvi, &num_hdmi) ||
-		    (pRADEONEnt->secondary_scrn &&
-		     drmmode_find_output(pRADEONEnt->secondary_scrn,
-					 mode_res->connectors[i],
-					 &num_dvi, &num_hdmi)))
+		for (j = 0; j < pRADEONEnt->num_scrns; j++) {
+			if (drmmode_find_output(pRADEONEnt->scrn[j],
+						mode_res->connectors[i],
+						&num_dvi, &num_hdmi))
+				break;
+		}
+
+		if (j < pRADEONEnt->num_scrns)
 			continue;
 
 		if (drmmode_output_init(scrn, drmmode, mode_res, i, &num_dvi,
diff --git a/src/radeon.h b/src/radeon.h
index b1d5f5af4..cde922c63 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -560,7 +560,7 @@ typedef struct {
     /* Number of SW cursors currently visible on this screen */
     int sprites_visible;
 
-    Bool              IsSecondary;
+    int instance_id;
 
     Bool              r600_shadow_fb;
     void *fb_shadow;
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index 50c7137c4..cd5efd530 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -202,6 +202,10 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
     if (!pScrn)
 	return;
 
+    pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
+    pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex);
+    pRADEONEnt = pPriv->ptr;
+
     info = RADEONPTR(pScrn);
     if (info) {
 	if (info->fbcon_pixmap)
@@ -217,15 +221,12 @@ static void RADEONFreeRec(ScrnInfoPtr pScrn)
 	    gbm_device_destroy(info->gbm);
 #endif
 
-	pEnt = info->pEnt;
+	pRADEONEnt->scrn[info->instance_id] = NULL;
+	pRADEONEnt->num_scrns--;
 	free(pScrn->driverPrivate);
 	pScrn->driverPrivate = NULL;
-    } else {
-	pEnt = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
     }
 
-    pPriv = xf86GetEntityPrivate(pEnt->index, gRADEONEntityIndex);
-    pRADEONEnt = pPriv->ptr;
     if (pRADEONEnt->fd > 0) {
         DevUnion *pPriv;
         RADEONEntPtr pRADEONEnt;
@@ -1689,7 +1690,6 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
     RADEONInfoPtr     info;
     RADEONEntPtr pRADEONEnt;
     MessageType from;
-    DevUnion* pPriv;
     Gamma  zeros = { 0.0, 0.0, 0.0 };
     uint32_t tiling = 0;
     int cpp;
@@ -1700,10 +1700,23 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONPreInit_KMS\n");
     if (pScrn->numEntities != 1) return FALSE;
+
+    pRADEONEnt = xf86GetEntityPrivate(pScrn->entityList[0],
+				      getRADEONEntityIndex())->ptr;
+    if (pRADEONEnt->num_scrns == ARRAY_SIZE(pRADEONEnt->scrn)) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Only up to %u Zaphod instances supported\n",
+		   (unsigned)ARRAY_SIZE(pRADEONEnt->scrn));
+	return FALSE;
+    }
+    
     if (!RADEONGetRec(pScrn)) return FALSE;
 
     info               = RADEONPTR(pScrn);
-    info->IsSecondary  = FALSE;
+
+    info->instance_id = pRADEONEnt->num_scrns++;
+    pRADEONEnt->scrn[info->instance_id] = pScrn;
+
     info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
     if (info->pEnt->location.type != BUS_PCI
 #ifdef XSERVER_PLATFORM_BUS
@@ -1712,27 +1725,11 @@ Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
         )
         return FALSE;
 
-    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
-				 getRADEONEntityIndex());
-    pRADEONEnt = pPriv->ptr;
-
-    if(xf86IsEntityShared(pScrn->entityList[0]))
-    {
-        if(xf86IsPrimInitDone(pScrn->entityList[0]))
-        {
-            info->IsSecondary = TRUE;
-        }
-        else
-        {
-            xf86SetPrimInitDone(pScrn->entityList[0]);
-        }
+    if (xf86IsEntityShared(pScrn->entityList[0]) &&
+	info->instance_id == 0) {
+	xf86SetPrimInitDone(pScrn->entityList[0]);
     }
 
-    if (info->IsSecondary)
-	pRADEONEnt->secondary_scrn = pScrn;
-    else
-	pRADEONEnt->primary_scrn = pScrn;
-
     info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
     pScrn->monitor     = pScrn->confScreen->monitor;
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index be82f9aea..7cb29b916 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -140,8 +140,8 @@ typedef struct
     unsigned long     fd_wakeup_registered; /* server generation for which fd has been registered for wakeup handling */
     int fd_wakeup_ref;
     unsigned int assigned_crtcs;
-    ScrnInfoPtr primary_scrn;
-    ScrnInfoPtr secondary_scrn;
+    unsigned int num_scrns;
+    ScrnInfoPtr scrn[6];
 #ifdef XSERVER_PLATFORM_BUS
     struct xf86_platform_device *platform_dev;
 #endif
-- 
2.19.1



More information about the amd-gfx mailing list