xf86-video-ati: Branch 'master' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Nov 7 16:49:43 UTC 2018


 src/drmmode_display.c |   69 ++++++++++++++++++++++++++++++++------------------
 src/drmmode_display.h |    2 -
 src/radeon.h          |    2 -
 src/radeon_kms.c      |   51 +++++++++++++++++-------------------
 src/radeon_probe.h    |    4 +-
 5 files changed, 73 insertions(+), 55 deletions(-)

New commits:
commit 5e6fa5c17a810127f0049816f20db6b871ca77e0
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Oct 24 18:22:05 2018 +0200

    Allow up to six instances in Zaphod mode
    
    Corresponding to up to six CRTCs being available in the hardware.
    
    (Ported from amdgpu commit c9d43c1deb9a9cfc41a8d6439caf46d12d220853)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 32ffe84e..fbdf5e6d 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 b1d5f5af..cde922c6 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 50c7137c..cd5efd53 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 be82f9ae..7cb29b91 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
commit c480fd066fe129fa6561fca8c09f037613b753e8
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Oct 24 18:19:42 2018 +0200

    Make wait_pending_flip / handle_deferred symmetric in set_mode_major
    
    We were always calling the latter, but not always the former, which
    could result in handling deferred DRM events prematurely.
    
    (Ported from amdgpu commit 955373a3e69baa241a1f267e96d04ddb902f689f)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 7493d636..32ffe84e 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -857,6 +857,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 	RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+	Bool handle_deferred = FALSE;
 	unsigned scanout_id = 0;
 	drmmode_ptr drmmode = drmmode_crtc->drmmode;
 	int saved_x, saved_y;
@@ -924,6 +925,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 		}
 
 		radeon_drm_wait_pending_flip(crtc);
+		handle_deferred = TRUE;
 
 		if (!drmmode_set_mode(crtc, fb, mode, x, y))
 			goto done;
@@ -983,7 +985,9 @@ done:
 		}
 	}
 
-	radeon_drm_queue_handle_deferred(crtc);
+	if (handle_deferred)
+		radeon_drm_queue_handle_deferred(crtc);
+
 	return ret;
 }
 
commit 86fe8d27b9a3f043e5288ce50eaf1f5fffd24516
Author: Michel Dänzer <michel.daenzer at amd.com>
Date:   Wed Oct 24 18:14:02 2018 +0200

    Handle pending scanout update in drmmode_crtc_scanout_free
    
    We have to wait for a pending scanout flip or abort a pending scanout
    update, otherwise the corresponding event handler will likely crash
    after drmmode_crtc_scanout_free cleaned up the data structures.
    
    Fixes crash after VT switch while dedicated scanout pixmaps are enabled
    for any CRTC.
    
    (Ported from amdgpu commit 0cd2c337d2c02b8ec2bd994d6124b4aaaad10741)

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 8445ef2a..7493d636 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -508,8 +508,17 @@ drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
 }
 
 void
-drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc)
+drmmode_crtc_scanout_free(xf86CrtcPtr crtc)
 {
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+	if (drmmode_crtc->scanout_update_pending) {
+		radeon_drm_wait_pending_flip(crtc);
+		radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending);
+		drmmode_crtc->scanout_update_pending = 0;
+		radeon_drm_queue_handle_deferred(crtc);
+	}
+
 	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
 				     &drmmode_crtc->scanout[0]);
 	drmmode_crtc_scanout_destroy(drmmode_crtc->drmmode,
@@ -967,9 +976,7 @@ done:
 		if (drmmode_crtc->scanout[scanout_id].pixmap &&
 		    fb != radeon_pixmap_get_fb(drmmode_crtc->
 					       scanout[scanout_id].pixmap)) {
-			radeon_drm_abort_entry(drmmode_crtc->scanout_update_pending);
-			drmmode_crtc->scanout_update_pending = 0;
-			drmmode_crtc_scanout_free(drmmode_crtc);
+			drmmode_crtc_scanout_free(crtc);
 		} else if (!drmmode_crtc->tear_free) {
 			drmmode_crtc_scanout_destroy(drmmode,
 						     &drmmode_crtc->scanout[1]);
@@ -1265,7 +1272,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 		}
 	}
 
-	drmmode_crtc_scanout_free(drmmode_crtc);
+	drmmode_crtc_scanout_free(crtc);
 	drmmode_crtc->prime_scanout_pixmap = NULL;
 
 	if (!ppix)
@@ -1280,7 +1287,7 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
 	    !drmmode_crtc_scanout_create(crtc, &drmmode_crtc->scanout[1],
 					 ppix->drawable.width,
 					 ppix->drawable.height)) {
-		drmmode_crtc_scanout_free(drmmode_crtc);
+		drmmode_crtc_scanout_free(crtc);
 		return FALSE;
 	}
 
@@ -2770,6 +2777,9 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 	if (info->dri2.pKernelDRMVersion->version_minor < 4 || !info->drmmode_inited)
 		return;
 
+	for (c = 0; c < config->num_crtc; c++)
+		drmmode_crtc_scanout_free(config->crtc[c]);
+
 	if (pRADEONEnt->fd_wakeup_registered == serverGeneration &&
 	    !--pRADEONEnt->fd_wakeup_ref) {
 #if HAVE_NOTIFY_FD
@@ -2780,9 +2790,6 @@ void drmmode_fini(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
 				drm_wakeup_handler, pScrn);
 #endif
 	}
-
-	for (c = 0; c < config->num_crtc; c++)
-		drmmode_crtc_scanout_free(config->crtc[c]->driver_private);
 }
 
 
diff --git a/src/drmmode_display.h b/src/drmmode_display.h
index bc66eda6..bfc13010 100644
--- a/src/drmmode_display.h
+++ b/src/drmmode_display.h
@@ -215,7 +215,7 @@ extern Bool drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn);
 
 extern void drmmode_crtc_scanout_destroy(drmmode_ptr drmmode,
 					 struct drmmode_scanout *scanout);
-void drmmode_crtc_scanout_free(drmmode_crtc_private_ptr drmmode_crtc);
+void drmmode_crtc_scanout_free(xf86CrtcPtr crtc);
 PixmapPtr drmmode_crtc_scanout_create(xf86CrtcPtr crtc,
 				      struct drmmode_scanout *scanout,
 				      int width, int height);
diff --git a/src/radeon_kms.c b/src/radeon_kms.c
index ae69f335..50c7137c 100644
--- a/src/radeon_kms.c
+++ b/src/radeon_kms.c
@@ -2614,7 +2614,7 @@ void RADEONLeaveVT_KMS(ScrnInfoPtr pScrn)
 				pixmap_unref_fb(drmmode_crtc->scanout[1].pixmap,
 						None, pRADEONEnt);
 			} else {
-			    drmmode_crtc_scanout_free(drmmode_crtc);
+			    drmmode_crtc_scanout_free(crtc);
 			}
 		    }
 		}


More information about the xorg-commit mailing list