Index: radeon_driver.c =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v retrieving revision 1.83 diff -p -u -r1.83 radeon_driver.c --- radeon_driver.c 14 Dec 2005 19:41:19 -0000 1.83 +++ radeon_driver.c 17 Feb 2006 10:48:35 -0000 @@ -864,6 +864,9 @@ void RADEONWaitForVerticalSync(ScrnInfoP unsigned char *RADEONMMIO = info->MMIO; int i; + if (INREG(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_DISP_REQ_EN_B) + return; + /* Clear the CRTC_VBLANK_SAVE bit */ OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); @@ -881,6 +884,9 @@ void RADEONWaitForVerticalSync2(ScrnInfo unsigned char *RADEONMMIO = info->MMIO; int i; + if (INREG(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_DISP_REQ_EN_B) + return; + /* Clear the CRTC2_VBLANK_SAVE bit */ OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); @@ -2261,11 +2267,8 @@ RADEONSetFBLocation(ScrnInfoPtr 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); + CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_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 @@ -2305,15 +2308,46 @@ RADEONSetFBLocation(ScrnInfoPtr pScrn) RADEONWaitForIdleMMIO(pScrn); + /* Stop display & memory access */ + ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL); + OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE); + crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL); + OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS); + crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL); + RADEONWaitForVerticalSync(pScrn); + OUTREG(RADEON_CRTC_GEN_CNTL, (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) | + RADEON_CRTC_DISP_REQ_EN_B); + if (info->HasCRTC2) { + crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL); + RADEONWaitForVerticalSync2(pScrn); + OUTREG(RADEON_CRTC2_GEN_CNTL, (crtc2_gen_cntl & ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) | + RADEON_CRTC2_DISP_REQ_EN_B); + } + + /* Wait for MC idle */ + while (!(INREG(RADEON_MC_STATUS) & RADEON_MC_IDLE)) + usleep(1); + + /* Make sure the chip settles down and set new map*/ + usleep(100000); + OUTREG(RADEON_MC_FB_LOCATION, mc_fb_location); OUTREG(RADEON_MC_AGP_LOCATION, mc_agp_location); + + /* Make sure map fully reached the chip */ + (void)INREG(RADEON_MC_FB_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); + /* Restore display & memory access */ + OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + OUTREG(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); + if (info->HasCRTC2) + OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); + OUTREG(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl); /* Set display0/1 priority up on r3/4xx in the memory controller for * high res modes if the user specifies HIGH for displaypriority Index: radeon_reg.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v retrieving revision 1.20 diff -p -u -r1.20 radeon_reg.h --- radeon_reg.h 17 Sep 2005 07:47:51 -0000 1.20 +++ radeon_reg.h 17 Feb 2006 10:48:35 -0000 @@ -307,9 +307,9 @@ # define RADEON_CRTC_DBL_SCAN_EN (1 << 0) # define RADEON_CRTC_INTERLACE_EN (1 << 1) # define RADEON_CRTC_CSYNC_EN (1 << 4) +# define RADEON_CRTC_ICON_EN (1 << 15) # define RADEON_CRTC_CUR_EN (1 << 16) # define RADEON_CRTC_CUR_MODE_MASK (7 << 17) -# define RADEON_CRTC_ICON_EN (1 << 20) # define RADEON_CRTC_EXT_DISP_EN (1 << 24) # define RADEON_CRTC_EN (1 << 25) # define RADEON_CRTC_DISP_REQ_EN_B (1 << 26) @@ -847,6 +847,8 @@ #define RADEON_MAX_LATENCY 0x0f3f /* PCI */ #define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_STATUS 0x0150 +# define RADEON_MC_IDLE (1 << 2) #define RADEON_MC_FB_LOCATION 0x0148 #define RADEON_DISPLAY_BASE_ADDR 0x23c #define RADEON_DISPLAY2_BASE_ADDR 0x33c