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