summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-03-18 00:08:24 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-03-18 00:08:24 +0000
commit21acdf371e3cf913c5affbd3e86641cfb115311c (patch)
tree58b4f3281feacae71653f0e90f8fc5e64c4ce592
parent323ecb92e40d71c5ef994b41b6d8dedba6dd6203 (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--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