summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.de>2011-11-14 19:10:01 +0100
committerEgbert Eich <eich@freedesktop.org>2012-01-05 09:25:48 +0100
commitac51e331895b216d288bc7bd108a38b362214668 (patch)
treeafc04857e82c85fe0d1dc61cec62d659ded03fdf
parent0a8d04eeac95f4db9d03ee31070bd825a7feb0b2 (diff)
UMS: Fix lockups in palette save/restore on pre-AVIVO chips.
The reintroduction of palette save/restore in 5efdf514 causes some pre-AVIVO chips to lock up. An investigation revealed that accessing palette registers when the associated PLL is not running is causing this. With UMS the PLL setup that is saved has been done by the BIOS typically. A similar issue was observed when VGA palette save/restore had been reinitroduced with 80eee856: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=480312 and has been worked around for Linux without further investigation by 87e66ce7. To fix the issue we now a. introduce 'on-demand' palette saving (ie the palette is saved before it is first altered). This guarantees that the palette register are only associated when the associated CRTC is active and thus the PLLs are powered up and running. b. move palette restore before PLL restore. c. eliminate generic VGA palette save/restore which seems to be unneeded when the palette is restored natively. It is believed that this caused the behavior described in https://bugs.freedesktop.org/show_bug.cgi?id=18407#c27 Signed-off-by: Egbert Eich <eich@freedesktop.org> Reviewed-by: Alex Deucher <alexdeucher@gmail.com>
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_crtc.c2
-rw-r--r--src/radeon_driver.c61
-rw-r--r--src/radeon_probe.h4
4 files changed, 40 insertions, 28 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 91c7b624..3f7ad4e6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -1072,6 +1072,7 @@ extern void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
extern void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
extern void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
extern void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+extern void radeon_save_palette_on_demand(ScrnInfoPtr pScrn, int palID);
extern void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn, radeon_tvdac_ptr tvdac);
extern void RADEONGetTMDSInfoFromTable(ScrnInfoPtr pScrn, radeon_tmds_ptr tmds);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 3c037001..9821ab60 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -510,6 +510,8 @@ radeon_crtc_load_lut(xf86CrtcPtr crtc)
if (!crtc->enabled)
return;
+ radeon_save_palette_on_demand(pScrn, radeon_crtc->crtc_id);
+
if (IS_DCE4_VARIANT) {
OUTREG(EVERGREEN_DC_LUT_CONTROL + radeon_crtc->crtc_offset, 0);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 81f5645a..04a242a7 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4477,22 +4477,17 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
/* Read palette data */
-static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
+static void RADEONSavePalette(ScrnInfoPtr pScrn, int palID, RADEONSavePtr save)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
int i;
- PAL_SELECT(1);
+ PAL_SELECT(palID);
INPAL_START(0);
- for (i = 0; i < 256; i++) {
- save->palette2[i] = INREG(RADEON_PALETTE_30_DATA);
- }
- PAL_SELECT(0);
- INPAL_START(0);
for (i = 0; i < 256; i++) {
- save->palette[i] = INREG(RADEON_PALETTE_30_DATA);
+ save->palette[palID][i] = INREG(RADEON_PALETTE_30_DATA);
}
}
@@ -4502,16 +4497,21 @@ static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
unsigned char *RADEONMMIO = info->MMIO;
int i;
- PAL_SELECT(1);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- OUTREG(RADEON_PALETTE_30_DATA, restore->palette2[i]);
+ if (restore->palette_saved[1]) {
+ ErrorF("Restore Palette 2\n");
+ PAL_SELECT(1);
+ OUTPAL_START(0);
+ for (i = 0; i < 256; i++) {
+ OUTREG(RADEON_PALETTE_30_DATA, restore->palette[1][i]);
+ }
}
-
- PAL_SELECT(0);
- OUTPAL_START(0);
- for (i = 0; i < 256; i++) {
- OUTREG(RADEON_PALETTE_30_DATA, restore->palette[i]);
+ if (restore->palette_saved[0]) {
+ ErrorF("Restore Palette 1\n");
+ PAL_SELECT(0);
+ OUTPAL_START(0);
+ for (i = 0; i < 256; i++) {
+ OUTREG(RADEON_PALETTE_30_DATA, restore->palette[0][i]);
+ }
}
}
@@ -5737,6 +5737,20 @@ RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
}
+void radeon_save_palette_on_demand(ScrnInfoPtr pScrn, int palID)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSavePtr save = info->SavedReg;
+
+ if (save->palette_saved[palID] == TRUE)
+ return;
+
+ if (!IS_AVIVO_VARIANT)
+ RADEONSavePalette(pScrn, palID, save);
+
+ save->palette_saved[palID] = TRUE;
+}
+
/* Save everything needed to restore the original VC state */
static void RADEONSave(ScrnInfoPtr pScrn)
{
@@ -5760,12 +5774,9 @@ static void RADEONSave(ScrnInfoPtr pScrn)
* setup in the card at all !!
*/
vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
-# elif defined(__linux__)
+# else
/* Save only mode * & fonts */
vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
-# else
- /* Save mode * & fonts & cmap */
- vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_ALL);
# endif
vgaHWLock(hwp);
}
@@ -5790,7 +5801,7 @@ static void RADEONSave(ScrnInfoPtr pScrn)
RADEONSaveCrtcRegisters(pScrn, save);
RADEONSaveFPRegisters(pScrn, save);
RADEONSaveDACRegisters(pScrn, save);
- RADEONSavePalette(pScrn, save);
+ /* Palette saving is done on demand now */
if (pRADEONEnt->HasCRTC2) {
RADEONSaveCrtc2Registers(pScrn, save);
@@ -5844,6 +5855,7 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
RADEONRestoreMemMapRegisters(pScrn, restore);
RADEONRestoreCommonRegisters(pScrn, restore);
+ RADEONRestorePalette(pScrn, restore);
if (pRADEONEnt->HasCRTC2) {
RADEONRestoreCrtc2Registers(pScrn, restore);
RADEONRestorePLL2Registers(pScrn, restore);
@@ -5900,10 +5912,8 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
* write VGA fonts, will find a better solution in the future
*/
vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
-# elif defined(__linux__)
- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
# else
- vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL );
+ vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
# endif
vgaHWLock(hwp);
}
@@ -5917,7 +5927,6 @@ static void RADEONRestore(ScrnInfoPtr pScrn)
else if (IS_AVIVO_VARIANT)
avivo_restore_vga_regs(pScrn, restore);
else {
- RADEONRestorePalette(pScrn, restore);
RADEONRestoreDACRegisters(pScrn, restore);
}
#if 0
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 94f6d7d1..8ba7214a 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -663,8 +663,8 @@ typedef struct {
/* Pallet */
Bool palette_valid;
- uint32_t palette[256];
- uint32_t palette2[256];
+ Bool palette_saved[2];
+ uint32_t palette[2][256];
uint32_t disp2_req_cntl1;
uint32_t disp2_req_cntl2;