summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--src/radeon_driver.c79
-rw-r--r--src/radeon_reg.h3
3 files changed, 58 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index f2d50888..d947a5d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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