diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-03-18 00:08:24 +0000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2006-03-18 00:08:24 +0000 |
commit | 21acdf371e3cf913c5affbd3e86641cfb115311c (patch) | |
tree | 58b4f3281feacae71653f0e90f8fc5e64c4ce592 | |
parent | 323ecb92e40d71c5ef994b41b6d8dedba6dd6203 (diff) |
Clear the offsets when updating the memory map instead of when enabling the
CRTCs and try to make that code more reliable. Doesn't disable the
CRTCs beforehand.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | src/radeon_driver.c | 79 | ||||
-rw-r--r-- | src/radeon_reg.h | 3 |
3 files changed, 58 insertions, 33 deletions
@@ -1,3 +1,12 @@ +2006-03-18 Benjamin Herrenschmidt <benh@kernel.crashing.org> + + * src/radeon_driver.c: (RADEONRestoreMemMapRegisters), + (RADEONRestoreCrtcRegisters), (RADEONRestoreCrtc2Registers): + * src/radeon_reg.h: + Clear the offsets when updating the memory map instead of when + enabling the CRTCs and try to make that code more reliable. Doesn't + disable the CRTCs beforehand. + 2006-03-18 Roland Scheidegger <rscheidegger_lists@hispeed.ch> * src/radeon_dri.c: (RADEONDRIGetVersion): * src/radeon_driver.c: (RADEONGetAccessibleVRAM): diff --git a/src/radeon_driver.c b/src/radeon_driver.c index ae40bb42..5a83de4a 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -1,5 +1,5 @@ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v 1.117 2004/02/19 22:38:12 tsi Exp $ */ -/* $XdotOrg: driver/xf86-video-ati/src/radeon_driver.c,v 1.104 2006/03/16 21:53:58 benh Exp $ */ +/* $XdotOrg: driver/xf86-video-ati/src/radeon_driver.c,v 1.105 2006/03/17 03:00:53 sroland Exp $ */ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. @@ -6130,7 +6130,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int i; + int i, timeout; RADEONTRACE(("RADEONRestoreMemMapRegisters() : \n")); RADEONTRACE((" MC_FB_LOCATION : 0x%08lx\n", restore->mc_fb_location)); @@ -6144,7 +6144,6 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, INREG(RADEON_MC_AGP_LOCATION) != restore->mc_agp_location) { CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl; CARD32 old_mc_status, status_idle; - int timeout; RADEONTRACE((" Map Changed ! Applying ...\n")); @@ -6168,7 +6167,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONWaitForVerticalSync(pScrn); OUTREG(RADEON_CRTC_GEN_CNTL, (crtc_gen_cntl - & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN | RADEON_CRTC_EN)) + & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN); if (info->HasCRTC2) { @@ -6176,9 +6175,8 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONWaitForVerticalSync2(pScrn); OUTREG(RADEON_CRTC2_GEN_CNTL, (crtc2_gen_cntl - & ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN | - RADEON_CRTC2_EN)) - | RADEON_CRTC2_DISP_REQ_EN_B | RADEON_CRTC2_EN); + & ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) + | RADEON_CRTC2_DISP_REQ_EN_B); } /* Make sure the chip settles down (paranoid !) */ @@ -6190,6 +6188,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, else status_idle = RADEON_MC_IDLE; + timeout = 0; while (!(INREG(RADEON_MC_STATUS) & status_idle)) { if (++timeout > 1000000) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -6206,6 +6205,7 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, */ usleep(2000000); } + usleep(10); } /* Update maps, first clearing out AGP to make sure we don't get @@ -6228,15 +6228,50 @@ static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn, RADEONTRACE(("Updating base addresses...\n")); - /* Restore base addresses */ + /* Make sure we have sane offsets before enabling, disable + * stereo and wait for offsets to catch up with hw + */ + OUTREG(RADEON_CRTC_OFFSET_CNTL, RADEON_CRTC_OFFSET_FLIP_CNTL); + OUTREG(RADEON_CRTC_OFFSET, 0); + OUTREG(RADEON_CRTC_OFFSET_CNTL, 0); + OUTREG(RADEON_CUR_OFFSET, 0); + timeout = 0; + while(INREG(RADEON_CRTC_OFFSET) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) { + if (timeout++ > 1000000) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Timeout waiting for CRTC offset to update !\n"); + break; + } + usleep(1000); + } OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr); - if (info->HasCRTC2) + + if (info->HasCRTC2) { + /* Make sure we have sane offsets before enabling, disable + * stereo and wait for offsets to catch up with hw + */ + OUTREG(RADEON_CRTC2_OFFSET_CNTL, RADEON_CRTC2_OFFSET_FLIP_CNTL); + OUTREG(RADEON_CRTC2_OFFSET, 0); + OUTREG(RADEON_CRTC2_OFFSET_CNTL, 0); + OUTREG(RADEON_CUR2_OFFSET, 0); + timeout = 0; + while(INREG(RADEON_CRTC2_OFFSET) & RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET) { + if (timeout++ > 1000000) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Timeout waiting for CRTC2 offset to update !\n"); + break; + } + usleep(1000); + } OUTREG(RADEON_DISPLAY2_BASE_ADDR, restore->display2_base_addr); - OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr); + } - /* Flush PCI posting, make sure the above actually hit the card */ + OUTREG(RADEON_OV0_BASE_ADDR, restore->ov0_base_addr); (void)INREG(RADEON_OV0_BASE_ADDR); + /* More paranoia delays, wait 100ms */ + usleep(100000); + RADEONTRACE(("Done updating base addresses.\n")); } @@ -6350,17 +6385,6 @@ static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn, RADEONTRACE(("Programming CRTC1, offset: 0x%08x\n", restore->crtc_offset)); - /* Make sure we have sane offsets before enabling */ - OUTREG(RADEON_CRTC_OFFSET, 0); - OUTREG(RADEON_CRTC_OFFSET_CNTL, 0); - OUTREG(RADEON_CUR_OFFSET, 0); - - /* Magic delay ! This helps fixing a lockup on some setups, maybe - * the above need some time to properly hit the CRTC before we enable - * it, go figure ... - */ - usleep(100000); - /* We prevent the CRTC from hitting the memory controller until * fully programmed */ @@ -6409,17 +6433,6 @@ static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, RADEONTRACE(("Programming CRTC2, offset: 0x%08x\n", restore->crtc2_offset)); - /* Make sure we have sane offsets before enabling */ - OUTREG(RADEON_CRTC2_OFFSET, 0); - OUTREG(RADEON_CRTC2_OFFSET_CNTL, 0); - OUTREG(RADEON_CUR2_OFFSET, 0); - - /* Magic delay ! This helps fixing a lockup on some setups, maybe - * the above need some time to properly hit the CRTC before we enable - * it, go figure ... - */ - usleep(100000); - crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) & (RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 48fccdf4..a18582df 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -364,6 +364,8 @@ # define RADEON_CRTC_OFFSET__OFFSET_LOCK (1<<31) #define RADEON_CRTC2_OFFSET 0x0324 +# define RADEON_CRTC2_OFFSET__GUI_TRIG_OFFSET (1<<30) +# define RADEON_CRTC2_OFFSET__OFFSET_LOCK (1<<31) #define RADEON_CRTC_OFFSET_CNTL 0x0228 # define RADEON_CRTC_TILE_LINE_SHIFT 0 # define RADEON_CRTC_TILE_LINE_RIGHT_SHIFT 4 @@ -392,6 +394,7 @@ #define R300_CRTC2_TILE_X0_Y0 0x0358 #define RADEON_CRTC2_OFFSET_CNTL 0x0328 +# define RADEON_CRTC2_OFFSET_FLIP_CNTL (1 << 16) # define RADEON_CRTC2_TILE_EN (1 << 15) #define RADEON_CRTC_PITCH 0x022c # define RADEON_CRTC_PITCH__SHIFT 0 |