ATI Radeon XPRESS 200M freezes on VT switch (often even during initial
Xserver start). It turned out to be a regression, which was introduced
with git commit 7d9f643ae3d07 for fixing xorg bug 21321.
It seems that on this chip you cannot reliably disable crtcs. I tried to
work around that with usleep()s, but I didn't succeed fully. Patch 2+3
are different attempts, both fix the issue somewhat, but after 5-60 VT
switches (depending on phase of the moon or whatever) the system freezes
again. Note that the freeze happens not at register access time, but
sometime later, sometimes a second later. Increasing the sleep time
doesn't help much.
The attached Patch 1 disables crtc switch-off for the affected chips -
it seems on these chips there is not much potential for power saving
anyway, at least my measurements (when they were successful with one of
my other patches) were pretty inconclusive.
I'd like to see Patch 1 applied. Patches 2 and 3 are just for reference.
If there is a different potential fix, I can reproduce the issue here
and would be able to test patches.
Matthias
--
Matthias Hopf <[email protected]> __ __ __
Maxfeldstr. 5 / 90409 Nuernberg (_ | | (_ |__ [email protected]
Phone +49-911-74053-715 __) |_| __) |__ R & D www.mshopf.de
>From e704557e21b6dc6dbf40856a31cd0744b4188999 Mon Sep 17 00:00:00 2001
From: Matthias Hopf <[email protected]>
Date: Tue, 15 Dec 2009 14:12:30 +0100
Subject: [PATCH] 200M freezes on VT switch if CRTC is disabled.
No luck with adding usleep()s so far.
---
src/legacy_crtc.c | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index ed339ab..2486c25 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -46,6 +46,7 @@
#include "radeon_probe.h"
#include "radeon_version.h"
#include "radeon_atombios.h"
+#include "ati_pciids_gen.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -912,6 +913,17 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
? RADEON_CRTC_INTERLACE_EN
: 0));
+ /* 200M freezes on VT switch sometimes if CRTC is disabled */
+ if (info->Chipset == PCI_CHIP_RS400_5A41 ||
+ info->Chipset == PCI_CHIP_RS400_5A42 ||
+ info->Chipset == PCI_CHIP_RC410_5A61 ||
+ info->Chipset == PCI_CHIP_RC410_5A62 ||
+ info->Chipset == PCI_CHIP_RS480_5954 ||
+ info->Chipset == PCI_CHIP_RS480_5955 ||
+ info->Chipset == PCI_CHIP_RS482_5974 ||
+ info->Chipset == PCI_CHIP_RS485_5975)
+ save->crtc_gen_cntl |= RADEON_CRTC_EN;
+
save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
RADEON_CRTC_VSYNC_DIS |
RADEON_CRTC_HSYNC_DIS |
@@ -1162,6 +1174,17 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
? RADEON_CRTC2_INTERLACE_EN
: 0));
+ /* 200M freezes on VT switch sometimes if CRTC is disabled */
+ if (info->Chipset == PCI_CHIP_RS400_5A41 ||
+ info->Chipset == PCI_CHIP_RS400_5A42 ||
+ info->Chipset == PCI_CHIP_RC410_5A61 ||
+ info->Chipset == PCI_CHIP_RC410_5A62 ||
+ info->Chipset == PCI_CHIP_RS480_5954 ||
+ info->Chipset == PCI_CHIP_RS480_5955 ||
+ info->Chipset == PCI_CHIP_RS482_5974 ||
+ info->Chipset == PCI_CHIP_RS485_5975)
+ save->crtc_gen_cntl |= RADEON_CRTC2_EN;
+
save->disp2_merge_cntl = info->SavedReg->disp2_merge_cntl;
save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
--
1.6.0.2
--- src/legacy_output.c 2009-09-10 04:58:47.000000000 +0200
+++ /tmp/legacy_output.c.ok 2009-12-14 18:51:03.000000000 +0100
@@ -348,9 +348,20 @@
unsigned char *RADEONMMIO = info->MMIO;
if (info->IsMobility) {
+ unsigned long tmpPixclksCntl;
+ if (! (restore->lvds_gen_cntl & RADEON_LVDS_ON)) {
+ tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ /* Asic bug, when turning off LVDS_ON, we have to make sure
+ RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+ */
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+ }
OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+usleep (500 * 1000);
/*OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl);*/
-
+ if (! (restore->lvds_gen_cntl & RADEON_LVDS_ON)) {
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ }
if (info->ChipFamily == CHIP_FAMILY_RV410) {
OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
}
@@ -994,6 +1005,7 @@
case ENCODER_OBJECT_ID_INTERNAL_LVDS:
{
unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ radeon_lvds_ptr lvds = (radeon_lvds_ptr)radeon_encoder->dev_priv;
ErrorF("disable LVDS\n");
if (info->IsMobility || info->IsIGP) {
/* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -1010,6 +1022,7 @@
if (info->IsMobility || info->IsIGP) {
OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
+ usleep (lvds->PanelPwrDly * 1000);
}
break;
case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index b57ba5f..8a89ccc 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -145,8 +145,11 @@ RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
/* We prevent the CRTC from hitting the memory controller until
* fully programmed
*/
+ErrorF ("crtc1 pre sleep\n");
OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl |
RADEON_CRTC_DISP_REQ_EN_B);
+usleep (500 * 1000);
+ErrorF ("crtc1 mid sleep\n");
OUTREGP(RADEON_CRTC_EXT_CNTL,
restore->crtc_ext_cntl,
@@ -172,6 +175,8 @@ RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
}
OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
+usleep (500 * 1000);
+ErrorF ("crtc1 post sleep\n");
}
/* Write CRTC2 registers */
@@ -190,10 +195,13 @@ RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
/* We prevent the CRTC from hitting the memory controller until
* fully programmed
*/
+ErrorF ("crtc2 pre sleep\n");
OUTREG(RADEON_CRTC2_GEN_CNTL,
restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
RADEON_CRTC2_DISP_REQ_EN_B);
+usleep (500 * 1000);
+ErrorF ("crtc2 mid sleep\n");
OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
@@ -209,6 +217,8 @@ RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl);
OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+usleep (500 * 1000);
+ErrorF ("crtc2 mid sleep\n");
}
_______________________________________________
xorg-driver-ati mailing list
[email protected]
http://lists.x.org/mailman/listinfo/xorg-driver-ati