Xorg 7.0-rc1 and EXA (radeon 9200)

Benjamin Herrenschmidt benh at kernel.crashing.org
Mon Oct 24 15:34:17 PDT 2005


On Mon, 2005-10-24 at 23:32 +0000, morgoth6 at box43.pl wrote:
> Hell[o]
> 
> > No, GNOME is usually snappy here, running xcompmgr -a.
> 
> Also any GTK+ apps are deam slow under KDE for example. Hmmm weird ... anyway any progress with this DRM patch ?
> 
> > Sounds like SW cursor is being used instead of HW cursor. There's a
> > known issue where the radeon driver with EXA sometimes (in particular
> > after a VT switch) drops back from HW cursor to SW cursor, without any
> > sign of it in the log file.
> 
> Is there a way to verify which cursor mode is used in a moment ?

Does this work for you ?

diff -urN xc-COMMIT/programs/Xserver/hw/xfree86/drivers/ati/radeon.h xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
--- xc-COMMIT/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-10-10 15:42:37.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-10-24 10:41:14.000000000 +1000
@@ -146,10 +146,16 @@
     CARD32            cap0_trig_cntl;
     CARD32            cap1_trig_cntl;
     CARD32            bus_cntl;
-    CARD32            surface_cntl;
     CARD32            bios_4_scratch;
     CARD32            bios_5_scratch;
     CARD32            bios_6_scratch;
+    CARD32            surface_cntl;
+    CARD32            surfaces[8][3];
+    CARD32            mc_agp_location;
+    CARD32            mc_fb_location;
+    CARD32            display_base_addr;
+    CARD32            display2_base_addr;
+    CARD32            ov0_base_addr;
 
 				/* Other registers to save for VT switches */
     CARD32            dp_datatype;
@@ -157,8 +163,6 @@
     CARD32            clock_cntl_index;
     CARD32            amcgpio_en_reg;
     CARD32            amcgpio_mask;
-    
-    CARD32            surfaces[8][3];
 
 				/* CRTC registers */
     CARD32            crtc_gen_cntl;
diff -urN xc-COMMIT/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
--- xc-COMMIT/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-10-10 15:42:37.000000000 +1000
+++ xc-HEAD/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-10-24 11:30:54.000000000 +1000
@@ -129,6 +129,7 @@
 static int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn);
+static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 
 /* psuedo xinerama support */
 
@@ -2238,81 +2239,56 @@
 }
 
 /* Set up MC_FB_LOCATION and related registers */
-static void
-RADEONSetFBLocation(ScrnInfoPtr pScrn)
+static void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,RADEONSavePtr save,
+				      RADEONInfoPtr info)
 {
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 mc_fb_location;
-    CARD32 mc_agp_location = INREG(RADEON_MC_AGP_LOCATION);
-    CARD32 bus_cntl = INREG(RADEON_BUS_CNTL);
-    
-    OUTREG (RADEON_BUS_CNTL, bus_cntl | RADEON_BUS_MASTER_DIS);
-    RADEONWaitForIdleMMIO(pScrn);
 
-    /* This function has many problems with newer cards.
-     * Even with older cards, all registers changed here are not
-     * restored properly when X quits, this will also cause 
-     * various problems, especially with radeonfb.
-     * Since we don't have DRI support for R300 and above cards, 
-     * we just hardcode these values for now.
-     * Need to revisit this whole function!!!
-     */
+    /* Default to existing values */
+    save->mc_fb_location = INREG(RADEON_MC_FB_LOCATION);
+    save->mc_agp_location = INREG(RADEON_MC_AGP_LOCATION);
 
+    /*
+     * Warning: A lot of the stuff down there is fairly bogus. For example,
+     * we use CONFIG_APER_SIZE which is only _half_ of the PCI exposed area
+     * since we might expose our VRAM in 2 different non overlapping apertures
+     * depending on how the card is bootstrapped.
+     *
+     * This will have to be fixed some day ...
+     */
     if (info->IsIGP) {
-	mc_fb_location = INREG(RADEON_NB_TOM);
+	save->mc_fb_location = INREG(RADEON_NB_TOM);
 
+	/* Hack ... FIXME or at least move elsewhere*/
 	OUTREG(RADEON_GRPH2_BUFFER_CNTL,
 	       INREG(RADEON_GRPH2_BUFFER_CNTL) & ~0x7f0000);
 
     } else
 #ifdef XF86DRI
     if ( info->directRenderingEnabled && info->drmMinor < 10 ) {
-	mc_fb_location = (INREG(RADEON_CONFIG_APER_SIZE) - 1) & 0xffff0000U;
+	save->mc_fb_location = (INREG(RADEON_CONFIG_APER_SIZE) - 1) & 0xffff0000U;
     } else
 #endif
     {
 	CARD32 aper0_base = INREG(RADEON_CONFIG_APER_0_BASE);
 
-	mc_fb_location = (aper0_base >> 16)
-		       | ((aper0_base + (INREG(RADEON_CONFIG_APER_SIZE) - 1)
-			   ) & 0xffff0000U);
+	save->mc_fb_location = (aper0_base >> 16)
+		| ((aper0_base + (INREG(RADEON_CONFIG_APER_SIZE) - 1)
+		    ) & 0xffff0000U);
     }
 
-    info->fbLocation = (mc_fb_location & 0xffff) << 16;
+    info->fbLocation = (save->mc_fb_location & 0xffff) << 16;
 
-    if (((mc_agp_location & 0xffff) << 16) !=
-	((mc_fb_location & 0xffff0000U) + 0x10000)) {
-	mc_agp_location = mc_fb_location & 0xffff0000U;
-	mc_agp_location |= (mc_agp_location + 0x10000) >> 16;
+    if (((save->mc_agp_location & 0xffff) << 16) !=
+	((save->mc_fb_location & 0xffff0000U) + 0x10000)) {
+	save->mc_agp_location = save->mc_fb_location & 0xffff0000U;
+	save->mc_agp_location |= (save->mc_agp_location + 0x10000) >> 16;
     }
 
-    RADEONWaitForIdleMMIO(pScrn);
-
-    OUTREG(RADEON_MC_FB_LOCATION, mc_fb_location);
-    OUTREG(RADEON_MC_AGP_LOCATION, mc_agp_location);
-    OUTREG(RADEON_DISPLAY_BASE_ADDR, info->fbLocation);
-    if (info->HasCRTC2)
-	OUTREG(RADEON_DISPLAY2_BASE_ADDR, info->fbLocation);
-    OUTREG(RADEON_OV0_BASE_ADDR, info->fbLocation);
-
-    OUTREG (RADEON_BUS_CNTL, bus_cntl);
-    RADEONWaitForIdleMMIO(pScrn);
-
-    /* Set display0/1 priority up on r3/4xx in the memory controller for 
-     * high res modes if the user specifies HIGH for displaypriority 
-     * option.
-     */
-    if ((info->DispPriority == 2) && IS_R300_VARIANT) {
-        CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
-	if (info->MergedFB || pRADEONEnt->HasSecondary) {
-	    mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
-	} else {
-	    mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
-	}
-	OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
-    }
+    save->display_base_addr = info->fbLocation;
+    save->display2_base_addr = info->fbLocation;
+    save->ov0_base_addr = info->fbLocation;
 
 }
 
@@ -5503,6 +5479,8 @@
 	unsigned char *RADEONMMIO = info->MMIO;
 
 	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
+	RADEONSaveMemMapRegisters(pScrn, &info->ModeReg);
+	info->fbLocation = (info->ModeReg.mc_fb_location & 0xffff) << 16;
 	info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
     } else {
 	if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
@@ -5590,8 +5568,6 @@
     hasDRI = info->directRenderingEnabled;
 #endif
 
-    RADEONSetFBLocation(pScrn);
-
     if (!fbScreenInit(pScreen, info->FB,
 		      pScrn->virtualX, pScrn->virtualY,
 		      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
@@ -5830,7 +5806,66 @@
     return TRUE;
 }
 
-/* Write common registers (initialized to 0) */
+/* Write memory mapping registers */
+static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+					 RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int i;
+
+    /* Write memory mapping registers only if their value change
+     * since we must ensure no access is done while they are
+     * reprogrammed
+     */
+    if (INREG(RADEON_MC_FB_LOCATION) != restore->mc_fb_location ||
+	INREG(RADEON_MC_AGP_LOCATION) != restore->mc_agp_location) {
+	CARD32 tmp;
+
+	/* Make sure engine is idle. We assume the CCE is stopped
+	 * at this point
+	 */
+	RADEONWaitForIdleMMIO(pScrn);
+
+	/* Stop display & memory access */
+	tmp = INREG(RADEON_CRTC_EXT_CNTL);
+	OUTREG(RADEON_CRTC_EXT_CNTL, tmp | RADEON_CRTC_DISPLAY_DIS);
+	tmp = INREG(RADEON_CRTC_GEN_CNTL);
+	tmp &= ~RADEON_CRTC_CUR_EN;
+	tmp |= RADEON_CRTC_DISP_REQ_EN_B;
+	OUTREG(RADEON_CRTC_GEN_CNTL, tmp);
+	if (info->HasCRTC2) {
+		tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+		tmp &= ~RADEON_CRTC2_CUR_EN;
+		tmp |= RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_DISP_REQ_EN_B;
+		OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+	}
+	tmp = INREG(RADEON_OV0_SCALE_CNTL);
+	tmp &= ~RADEON_SCALER_ENABLE;
+
+	/* Clear all surfaces */
+	for (i = 0; i < 8; i++) {
+	    OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0);
+	    OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0);
+	    OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0);
+	}
+
+	/* Make sure the chip settles down and set new map*/ 
+	usleep(100000);
+	OUTREG(RADEON_MC_FB_LOCATION, restore->mc_fb_location);
+ 	OUTREG(RADEON_MC_AGP_LOCATION, restore->mc_agp_location);
+	/* Make sure map fully reached the chip */
+	(void)INREG(RADEON_MC_FB_LOCATION);
+
+    }
+    
+    /* Restore base addresses */
+    OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
+    OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr);
+    OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr);
+}
+
+/* Write common registers */
 static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
 					 RADEONSavePtr restore)
 {
@@ -6450,6 +6485,7 @@
 
     /* For Non-dual head card, we don't have private field in the Entity */
     if (!info->HasCRTC2) {
+	RADEONRestoreMemMapRegisters(pScrn, restore);
 	RADEONRestoreCommonRegisters(pScrn, restore);
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
@@ -6467,10 +6503,12 @@
      * order. Regardless the order of X server issuing the calls, we
      * have to ensure we set registers in the right order!!!  Otherwise
      * we may get a blank screen.
+     *
+     * We always restore MemMap first, the saverec should be up to date
+     * in all cases
      */
     if (info->IsSecondary) {
-	if (!pRADEONEnt->RestorePrimary  && !info->IsSwitching)
-	    RADEONRestoreCommonRegisters(pScrn, restore);
+	RADEONRestoreMemMapRegisters(pScrn, restore);
 	RADEONRestoreCrtc2Registers(pScrn, restore);
 	RADEONRestorePLL2Registers(pScrn, restore);
 
@@ -6481,15 +6519,14 @@
 	if (pRADEONEnt->RestorePrimary) {
 	    pRADEONEnt->RestorePrimary = FALSE;
 
+	    RADEONRestoreCommonRegisters(pScrn, &restore0);
 	    RADEONRestoreCrtcRegisters(pScrn, &restore0);
 	    RADEONRestoreFPRegisters(pScrn, &restore0);
 	    RADEONRestorePLLRegisters(pScrn, &restore0);
 	    pRADEONEnt->IsSecondaryRestored = FALSE;
 	}
     } else {
-	if (!pRADEONEnt->IsSecondaryRestored)
-	    RADEONRestoreCommonRegisters(pScrn, restore);
-
+	RADEONRestoreMemMapRegisters(pScrn, restore);
 	if (info->MergedFB) {
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
@@ -6499,6 +6536,7 @@
 	    info->IsSwitching) {
 	    pRADEONEnt->IsSecondaryRestored = FALSE;
 
+	    RADEONRestoreCommonRegisters(pScrn, restore);
 	    RADEONRestoreCrtcRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
 	    RADEONRestorePLLRegisters(pScrn, restore);
@@ -6513,6 +6551,19 @@
 #endif
 }
 
+/* Read memory map */
+static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->mc_fb_location     = INREG(RADEON_MC_FB_LOCATION);
+    save->mc_agp_location    = INREG(RADEON_MC_AGP_LOCATION);
+    save->display_base_addr  = INREG(RADEON_DISPLAY_BASE_ADDR);
+    save->display2_base_addr = INREG(RADEON_DISPLAY2_BASE_ADDR);
+    save->ov0_base_addr      = INREG(RADEON_OV0_BASE_ADDR);
+}
+
 /* Read common registers */
 static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
@@ -6696,6 +6747,7 @@
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
     RADEONTRACE(("RADEONSaveMode(%p)\n", save));
+    RADEONSaveMemMapRegisters(pScrn, save);
     RADEONSaveCommonRegisters(pScrn, save);
     if (info->IsSecondary) {
 	RADEONSaveCrtc2Registers(pScrn, save);
@@ -6724,6 +6776,7 @@
 
     RADEONTRACE(("RADEONSave\n"));
     if (info->FBDev) {
+	RADEONSaveMemMapRegisters(pScrn, save);
 	fbdevHWSave(pScrn);
 	return;
     }
@@ -6907,6 +6960,22 @@
     int stop_req, max_stop_req;
     float read_return_rate, time_disp1_drop_priority;
 
+    /* 
+     * Set display0/1 priority up on r3/4xx in the memory controller for 
+     * high res modes if the user specifies HIGH for displaypriority 
+     * option.
+     */
+    if ((info->DispPriority == 2) && IS_R300_VARIANT) {
+        CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
+	if (info->MergedFB || pRADEONEnt->HasSecondary) {
+	    mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
+	} else {
+	    mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
+	}
+	OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
+    }
+
+
     /* R420 family not supported yet */
     if (info->ChipFamily == CHIP_FAMILY_R420) return; 
 
@@ -8009,6 +8078,7 @@
 
     info->Flags = mode->Flags;
 
+    RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
     if (info->IsSecondary) {
 	if (!RADEONInitCrtc2Registers(pScrn, save, mode, info))
@@ -8389,7 +8459,6 @@
     } else
 	if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
 
-    RADEONSetFBLocation(pScrn);
     if (!info->IsSecondary)
 	RADEONRestoreSurfaces(pScrn, &info->ModeReg);
 #ifdef XF86DRI





More information about the xorg mailing list