[PATCH 3/3] Make consistent use of fbOffset and share fb mappings.

Owain G. Ainsworth zerooa at googlemail.com
Sun Apr 18 20:05:36 PDT 2010


What we were doing previously was mapping the framebuffer for zaphod for
only this driver instances chunk, however, fbOffset was (rightly) set to
the offset into the whole framebuffer we were using.

Since in some cases we did operations on the FB virtual address +
fbOffset (for example zeroing the framebuffer on entervt) we were
actually pissing all over ourselves in those cases.

Fix this by implementing shared fb mappings like we do for MMIO already,
and whenever we wish to refer to our area of FB space we always use
fbOffset. Fixes zaphod for some users on r600 chipsets, my 4870 is still
behaving strangely on screen 0, but I suspect that is another bug.

Once calculation (in PreInitAccel) is now wrong because of this, however
dri on zaphod does now happen so this is irrelavent, add a comment to
that effect.
---
 src/radeon_cursor.c |    4 ++--
 src/radeon_driver.c |   45 ++++++++++++++++++++++++++++++++-------------
 src/radeon_probe.h  |    1 +
 3 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 4a171ff..538c8b2 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -343,7 +343,7 @@ radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
     ScrnInfoPtr pScrn = crtc->scrn;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    uint32_t *pixels = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+    uint32_t *pixels = (uint32_t *)(pointer)(info->FB + pScrn->fbOffset + radeon_crtc->cursor_offset);
     int            pixel, i;
     CURSOR_SWAPPING_DECL_MMIO
 
@@ -386,7 +386,7 @@ radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     CURSOR_SWAPPING_DECL_MMIO
-    uint32_t *d = (uint32_t *)(pointer)(info->FB + radeon_crtc->cursor_offset);
+    uint32_t *d = (uint32_t *)(pointer)(info->FB + pScrn->fbOffset + radeon_crtc->cursor_offset);
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index f59d3d5..e138492 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -238,7 +238,7 @@ radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
     stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
     *size = stride;
 
-    return ((uint8_t *)info->FB + row * stride + offset);
+    return ((uint8_t *)info->FB + pScrn->fbOffset + row * stride + offset);
 }
 static Bool
 RADEONCreateScreenResources (ScreenPtr pScreen)
@@ -402,6 +402,9 @@ void RADEONFreeRec(ScrnInfoPtr pScrn)
  */
 static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 {
+#ifdef XSERVER_LIBPCIACCESS
+    int err;
+#endif
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
@@ -418,15 +421,15 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pScrn)
 			       info->MMIOAddr,
 			       info->MMIOSize);
 
-    if (!info->MMIO) return FALSE;
+    if (!info->MMIO)
+        return FALSE;
 #else
 
-    void** result = (void**)&info->MMIO;
-    int err = pci_device_map_range(info->PciInfo,
+    err = pci_device_map_range(info->PciInfo,
 				   info->MMIOAddr,
 				   info->MMIOSize,
 				   PCI_DEV_MAP_FLAG_WRITABLE,
-				   result);
+				   &info->MMIO);
 
     if (err) {
 	xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
@@ -473,6 +476,12 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
     int err;
 #endif
     RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    if (pRADEONEnt->FB) {
+        info->FB = pRADEONEnt->FB;
+        return TRUE;
+    }
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Map: 0x%016llx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
@@ -505,6 +514,7 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 
 #endif
 
+    pRADEONEnt->FB = info->FB;
     return TRUE;
 }
 
@@ -512,6 +522,13 @@ static Bool RADEONMapFB(ScrnInfoPtr pScrn)
 static Bool RADEONUnmapFB(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    if (info->IsPrimary || info->IsSecondary) {
+      /* never unmap on zaphod */
+      info->FB = NULL;
+      return TRUE;
+    }
 
 #ifndef XSERVER_LIBPCIACCESS
     xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
@@ -519,6 +536,7 @@ static Bool RADEONUnmapFB(ScrnInfoPtr pScrn)
     pci_device_unmap_range(info->PciInfo, info->FB, info->FbMapSize);
 #endif
 
+    pRADEONEnt->FB = NULL;
     info->FB = NULL;
     return TRUE;
 }
@@ -1766,23 +1784,21 @@ static Bool RADEONPreInitVRAM(ScrnInfoPtr pScrn)
     xf86DrvMsg(pScrn->scrnIndex, from,
 	       "Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR");
 
+    /* Do this before we truncate since we only map fb once */
+    info->FbMapSize  = (pScrn->videoRam & ~1023) * 1024;
+
     if (info->IsPrimary) {
 	pScrn->videoRam /= 2;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "Using %dk of videoram for primary head\n",
 		   pScrn->videoRam);
-    }
-    
-    if (info->IsSecondary) {
+    } else if (info->IsSecondary) {
 	pScrn->videoRam /= 2;
-	info->LinearAddr += pScrn->videoRam * 1024;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "Using %dk of videoram for secondary head\n",
 		   pScrn->videoRam);
     }
-
     pScrn->videoRam  &= ~1023;
-    info->FbMapSize  = pScrn->videoRam * 1024;
 
     /* if the card is PCI Express reserve the last 32k for the gart table */
 #ifdef XF86DRI
@@ -2134,7 +2150,9 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn)
 #if defined(USE_EXA) && defined(USE_XAA)
     char *optstr;
 #endif
+#ifdef XF86DRI /* zaphod FbMapSize is wrong, but no dri then */
     int maxy = info->FbMapSize / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes);
+#endif
 
     if (!(info->accel_state = xcalloc(1, sizeof(struct radeon_accel_state)))) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
@@ -3420,7 +3438,8 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
     pScrn->fbOffset    = info->dri->frontOffset;
 #endif
 
-    if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
+    if (info->IsSecondary)
+        pScrn->fbOffset = pScrn->videoRam * 1024;
 #ifdef XF86DRI
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		   "RADEONScreenInit %lx %ld %d\n",
@@ -3661,7 +3680,7 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
 
     if (info->r600_shadow_fb == FALSE) {
 	/* Init fb layer */
-	if (!fbScreenInit(pScreen, info->FB,
+	if (!fbScreenInit(pScreen, info->FB + pScrn->fbOffset,
 			  pScrn->virtualX, pScrn->virtualY,
 			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
 			  pScrn->bitsPerPixel))
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index dc02bdf..405f5b4 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -638,6 +638,7 @@ typedef struct
     RADEONSaveRec     SavedReg;         /* Original (text) mode              */
 
     void              *MMIO;            /* Map of MMIO region                */
+    void              *FB;              /* Map of FB region                  */
     int fd;                             /* for sharing across zaphod heads   */
 } RADEONEntRec, *RADEONEntPtr;
 
-- 
1.6.5.7



More information about the xorg-driver-ati mailing list