summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-07-17 14:37:05 +1000
committerBrice Goglin <bgoglin@debian.org>2008-08-02 18:47:29 +0200
commitdcee07a3c4fbc6de77ee2bc0c7c7fe4cdfbeebda (patch)
treee53a37c5f2b921fc1cc0faf5fdbef008307b773a
parent9c46a8dd46cd583468254130c832993881eced20 (diff)
downloadxf86-video-ati-frc-dcee07a3c4fbc6de77ee2bc0c7c7fe4cdfbeebda.tar.gz
xf86-video-ati-frc-dcee07a3c4fbc6de77ee2bc0c7c7fe4cdfbeebda.tar.bz2
Fix console switch on R500
This patch fixes the console switch for me on R5xx. There are two aspects to it: - Fix the ordering of avivo_restore() to better match what's happening in the driver & ATOM, properly locking/unlocking and only enabling the CRTCs after everything has been properly programmed. - Don't ASIC_INIT if the card has any CRTC enabled. This is the best I came up with for avoiding spurrious ASIC_INIT on cards that -are- POSTed but don't have the BIOS coming from c0000 on x86. The problem with spurrious ASIC_INIT is that we do it before we do RADEONSave(), so that screws up the console switch. Note that I think we also should save/restore the palette, I don't think we do. right now, it's a minor issue for me because I fixed offb to be able to set it on AVIVO's but it might still have to be done in the long run. Tested with a VGA analog setup on DACA and a DVI setup on TMDS 0. I haven't tested any other combo but that should get us going. Cheers, Ben. Signed-off-by: Dave Airlie <airlied@redhat.com> (cherry picked from commit df53d12a06fad41f00cff849458cb358ab5e2098)
-rw-r--r--src/radeon_bios.c20
-rw-r--r--src/radeon_driver.c130
-rw-r--r--src/radeon_probe.h1
-rw-r--r--src/radeon_reg.h4
4 files changed, 112 insertions, 43 deletions
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 51484ac..35e6960 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -382,6 +382,26 @@ RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
info->MasterDataStart = RADEON_BIOS16 (info->ROMHeaderStart + 32);
}
+ /* We are a bit too quick at using this "unposted" to re-post the
+ * card. This causes some problems with VT switch on some machines,
+ * so let's work around this for now by only POSTing if none of the
+ * CRTCs are enabled
+ */
+ if (unposted && info->VBIOS) {
+ unsigned char *RADEONMMIO = info->MMIO;
+ uint32_t reg;
+
+ if (IS_AVIVO_VARIANT) {
+ reg = INREG(AVIVO_D1CRTC_CONTROL) | INREG(AVIVO_D2CRTC_CONTROL);
+ if (reg & AVIVO_CRTC_EN)
+ unposted = FALSE;
+ } else {
+ reg = INREG(RADEON_CRTC_GEN_CNTL) | INREG(RADEON_CRTC2_GEN_CNTL);
+ if (reg & RADEON_CRTC_EN)
+ unposted = FALSE;
+ }
+ }
+
if (unposted && info->VBIOS) {
if (info->IsAtomBios) {
if (!rhdAtomASICInit(info->atomBIOS))
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 041faa1..bb154de 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4236,6 +4236,7 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
state->grph1.x_end = INREG(AVIVO_D1GRPH_X_END);
state->grph1.y_end = INREG(AVIVO_D1GRPH_Y_END);
+ state->grph1.desktop_height = INREG(AVIVO_D1MODE_DESKTOP_HEIGHT);
state->grph1.viewport_start = INREG(AVIVO_D1MODE_VIEWPORT_START);
state->grph1.viewport_size = INREG(AVIVO_D1MODE_VIEWPORT_SIZE);
@@ -4275,6 +4276,7 @@ avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
state->grph2.x_end = INREG(AVIVO_D2GRPH_X_END);
state->grph2.y_end = INREG(AVIVO_D2GRPH_Y_END);
+ state->grph2.desktop_height = INREG(AVIVO_D2MODE_DESKTOP_HEIGHT);
state->grph2.viewport_start = INREG(AVIVO_D2MODE_VIEWPORT_START);
state->grph2.viewport_size = INREG(AVIVO_D2MODE_VIEWPORT_SIZE);
@@ -4480,14 +4482,69 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
struct avivo_state *state = &restore->avivo;
int i, j;
- // OUTMC(pScrn, AVIVO_MC_MEMORY_MAP, state->mc_memory_map);
- // OUTREG(AVIVO_VGA_MEMORY_BASE, state->vga_memory_base);
- // OUTREG(AVIVO_VGA_FB_START, state->vga_fb_start);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "avivo_restore !\n");
+
+ /* Disable VGA control for now.. maybe needs to be changed */
+ OUTREG(AVIVO_D1VGA_CONTROL, 0);
+ OUTREG(AVIVO_D2VGA_CONTROL, 0);
+
+ /* Disable CRTCs */
+ OUTREG(AVIVO_D1CRTC_CONTROL,
+ (INREG(AVIVO_D1CRTC_CONTROL) & ~0x300) | 0x01000000);
+ OUTREG(AVIVO_D2CRTC_CONTROL,
+ (INREG(AVIVO_D2CRTC_CONTROL) & ~0x300) | 0x01000000);
+ OUTREG(AVIVO_D1CRTC_CONTROL,
+ INREG(AVIVO_D1CRTC_CONTROL) & ~0x1);
+ OUTREG(AVIVO_D2CRTC_CONTROL,
+ INREG(AVIVO_D2CRTC_CONTROL) & ~0x1);
+ OUTREG(AVIVO_D1CRTC_CONTROL,
+ INREG(AVIVO_D1CRTC_CONTROL) | 0x100);
+ OUTREG(AVIVO_D2CRTC_CONTROL,
+ INREG(AVIVO_D2CRTC_CONTROL) | 0x100);
+
+ /* Lock graph registers */
+ OUTREG(AVIVO_D1GRPH_UPDATE, AVIVO_D1GRPH_UPDATE_LOCK);
+ OUTREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, state->grph1.prim_surf_addr);
+ OUTREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, state->grph1.sec_surf_addr);
+ OUTREG(AVIVO_D1GRPH_CONTROL, state->grph1.control);
+ OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_X, state->grph1.x_offset);
+ OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y, state->grph1.y_offset);
+ OUTREG(AVIVO_D1GRPH_X_START, state->grph1.x_start);
+ OUTREG(AVIVO_D1GRPH_Y_START, state->grph1.y_start);
+ OUTREG(AVIVO_D1GRPH_X_END, state->grph1.x_end);
+ OUTREG(AVIVO_D1GRPH_Y_END, state->grph1.y_end);
+ OUTREG(AVIVO_D1GRPH_PITCH, state->grph1.pitch);
+ OUTREG(AVIVO_D1GRPH_ENABLE, state->grph1.enable);
+ OUTREG(AVIVO_D1GRPH_UPDATE, 0);
+ OUTREG(AVIVO_D2GRPH_UPDATE, AVIVO_D1GRPH_UPDATE_LOCK);
+ OUTREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, state->grph2.prim_surf_addr);
+ OUTREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, state->grph2.sec_surf_addr);
+ OUTREG(AVIVO_D2GRPH_CONTROL, state->grph2.control);
+ OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_X, state->grph2.x_offset);
+ OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y, state->grph2.y_offset);
+ OUTREG(AVIVO_D2GRPH_X_START, state->grph2.x_start);
+ OUTREG(AVIVO_D2GRPH_Y_START, state->grph2.y_start);
+ OUTREG(AVIVO_D2GRPH_X_END, state->grph2.x_end);
+ OUTREG(AVIVO_D2GRPH_Y_END, state->grph2.y_end);
+ OUTREG(AVIVO_D2GRPH_PITCH, state->grph2.pitch);
+ OUTREG(AVIVO_D2GRPH_ENABLE, state->grph2.enable);
+ OUTREG(AVIVO_D2GRPH_UPDATE, 0);
- OUTREG(AVIVO_DC_CRTC_MASTER_EN, state->crtc_master_en);
- OUTREG(AVIVO_DC_CRTC_TV_CONTROL, state->crtc_tv_control);
+ /* Whack some mode regs too */
+ OUTREG(AVIVO_D1SCL_UPDATE, AVIVO_D1SCL_UPDATE_LOCK);
+ OUTREG(AVIVO_D1MODE_DESKTOP_HEIGHT, state->grph1.desktop_height);
+ OUTREG(AVIVO_D1MODE_VIEWPORT_START, state->grph1.viewport_start);
+ OUTREG(AVIVO_D1MODE_VIEWPORT_SIZE, state->grph1.viewport_size);
+ OUTREG(AVIVO_D1SCL_UPDATE, 0);
+
+ OUTREG(AVIVO_D2SCL_UPDATE, AVIVO_D1SCL_UPDATE_LOCK);
+ OUTREG(AVIVO_D2MODE_DESKTOP_HEIGHT, state->grph2.desktop_height);
+ OUTREG(AVIVO_D2MODE_VIEWPORT_START, state->grph2.viewport_start);
+ OUTREG(AVIVO_D2MODE_VIEWPORT_SIZE, state->grph2.viewport_size);
+ OUTREG(AVIVO_D2SCL_UPDATE, 0);
+ /* Set the PLL */
OUTREG(AVIVO_EXT1_PPLL_REF_DIV_SRC, state->pll1.ref_div_src);
OUTREG(AVIVO_EXT1_PPLL_REF_DIV, state->pll1.ref_div);
OUTREG(AVIVO_EXT1_PPLL_FB_DIV, state->pll1.fb_div);
@@ -4507,7 +4564,9 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(AVIVO_P2PLL_INT_SS_CNTL, state->pll2.int_ss_cntl);
OUTREG(AVIVO_PCLK_CRTC1_CNTL, state->crtc1.pll_source);
+ OUTREG(AVIVO_PCLK_CRTC2_CNTL, state->crtc2.pll_source);
+ /* Set the CRTC */
OUTREG(AVIVO_D1CRTC_H_TOTAL, state->crtc1.h_total);
OUTREG(AVIVO_D1CRTC_H_BLANK_START_END, state->crtc1.h_blank_start_end);
OUTREG(AVIVO_D1CRTC_H_SYNC_A, state->crtc1.h_sync_a);
@@ -4522,29 +4581,12 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(AVIVO_D1CRTC_V_SYNC_B, state->crtc1.v_sync_b);
OUTREG(AVIVO_D1CRTC_V_SYNC_B_CNTL, state->crtc1.v_sync_b_cntl);
- OUTREG(AVIVO_D1CRTC_CONTROL, state->crtc1.control);
- OUTREG(AVIVO_D1CRTC_BLANK_CONTROL, state->crtc1.blank_control);
OUTREG(AVIVO_D1CRTC_INTERLACE_CONTROL, state->crtc1.interlace_control);
OUTREG(AVIVO_D1CRTC_STEREO_CONTROL, state->crtc1.stereo_control);
OUTREG(AVIVO_D1CUR_CONTROL, state->crtc1.cursor_control);
- OUTREG(AVIVO_D1GRPH_ENABLE, state->grph1.enable);
- OUTREG(AVIVO_D1GRPH_CONTROL, state->grph1.control);
- OUTREG(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS, state->grph1.prim_surf_addr);
- OUTREG(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS, state->grph1.sec_surf_addr);
- OUTREG(AVIVO_D1GRPH_PITCH, state->grph1.pitch);
- OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_X, state->grph1.x_offset);
- OUTREG(AVIVO_D1GRPH_SURFACE_OFFSET_Y, state->grph1.y_offset);
- OUTREG(AVIVO_D1GRPH_X_START, state->grph1.x_start);
- OUTREG(AVIVO_D1GRPH_Y_START, state->grph1.y_start);
- OUTREG(AVIVO_D1GRPH_X_END, state->grph1.x_end);
- OUTREG(AVIVO_D1GRPH_Y_END, state->grph1.y_end);
-
- OUTREG(AVIVO_D1MODE_VIEWPORT_START, state->grph1.viewport_start);
- OUTREG(AVIVO_D1MODE_VIEWPORT_SIZE, state->grph1.viewport_size);
-
- OUTREG(AVIVO_PCLK_CRTC2_CNTL, state->crtc2.pll_source);
+ /* XXX Fix scaler */
OUTREG(AVIVO_D2CRTC_H_TOTAL, state->crtc2.h_total);
OUTREG(AVIVO_D2CRTC_H_BLANK_START_END, state->crtc2.h_blank_start_end);
@@ -4560,29 +4602,11 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(AVIVO_D2CRTC_V_SYNC_B, state->crtc2.v_sync_b);
OUTREG(AVIVO_D2CRTC_V_SYNC_B_CNTL, state->crtc2.v_sync_b_cntl);
- OUTREG(AVIVO_D2CRTC_CONTROL, state->crtc2.control);
- OUTREG(AVIVO_D2CRTC_BLANK_CONTROL, state->crtc2.blank_control);
OUTREG(AVIVO_D2CRTC_INTERLACE_CONTROL, state->crtc2.interlace_control);
OUTREG(AVIVO_D2CRTC_STEREO_CONTROL, state->crtc2.stereo_control);
OUTREG(AVIVO_D2CUR_CONTROL, state->crtc2.cursor_control);
- OUTREG(AVIVO_D2GRPH_ENABLE, state->grph2.enable);
- OUTREG(AVIVO_D2GRPH_CONTROL, state->grph2.control);
- OUTREG(AVIVO_D2GRPH_PRIMARY_SURFACE_ADDRESS, state->grph2.prim_surf_addr);
- OUTREG(AVIVO_D2GRPH_SECONDARY_SURFACE_ADDRESS, state->grph2.sec_surf_addr);
- OUTREG(AVIVO_D2GRPH_PITCH, state->grph2.pitch);
- OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_X, state->grph2.x_offset);
- OUTREG(AVIVO_D2GRPH_SURFACE_OFFSET_Y, state->grph2.y_offset);
- OUTREG(AVIVO_D2GRPH_X_START, state->grph2.x_start);
- OUTREG(AVIVO_D2GRPH_Y_START, state->grph2.y_start);
- OUTREG(AVIVO_D2GRPH_X_END, state->grph2.x_end);
- OUTREG(AVIVO_D2GRPH_Y_END, state->grph2.y_end);
-
- OUTREG(AVIVO_D2MODE_VIEWPORT_START, state->grph2.viewport_start);
- OUTREG(AVIVO_D2MODE_VIEWPORT_SIZE, state->grph2.viewport_size);
-
-
if (IS_DCE3_VARIANT) {
/* DVOA regs */
OUTREG(0x7080, state->dvoa[0]);
@@ -4702,7 +4726,7 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
}
j = 0;
- /* DAC regs */
+ /* DAC regs */ /* -- MIGHT NEED ORDERING FIX & DELAYS -- */
for (i = 0x7800; i <= 0x782c; i += 4) {
OUTREG(i, state->daca[j]);
OUTREG((i + 0x200), state->dacb[j]);
@@ -4769,8 +4793,30 @@ avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
OUTREG(0x6e30, state->dxscl[6]);
OUTREG(0x6e34, state->dxscl[7]);
+ /* Enable CRTCs */
+ if (state->crtc1.control & 1) {
+ OUTREG(AVIVO_D1CRTC_CONTROL, 0x01000101);
+ INREG(AVIVO_D1CRTC_CONTROL);
+ OUTREG(AVIVO_D1CRTC_CONTROL, 0x00010101);
+ }
+ if (state->crtc2.control & 1) {
+ OUTREG(AVIVO_D2CRTC_CONTROL, 0x01000101);
+ INREG(AVIVO_D2CRTC_CONTROL);
+ OUTREG(AVIVO_D2CRTC_CONTROL, 0x00010101);
+ }
+
+ /* Where should that go ? */
+ OUTREG(AVIVO_DC_CRTC_TV_CONTROL, state->crtc_tv_control);
+
+ /* Need fixing too ? */
+ OUTREG(AVIVO_D1CRTC_BLANK_CONTROL, state->crtc1.blank_control);
+ OUTREG(AVIVO_D2CRTC_BLANK_CONTROL, state->crtc2.blank_control);
+
+ /* Dbl check */
OUTREG(AVIVO_D1VGA_CONTROL, state->vga1_cntl);
OUTREG(AVIVO_D2VGA_CONTROL, state->vga2_cntl);
+
+ /* Should only enable outputs here */
}
static void avivo_restore_vga_regs(ScrnInfoPtr pScrn, RADEONSavePtr restore)
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 24af52b..2837671 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -310,6 +310,7 @@ struct avivo_grph_state {
uint32_t x_end;
uint32_t y_end;
+ uint32_t desktop_height;
uint32_t viewport_start;
uint32_t viewport_size;
};
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 59e2f12..936f8fa 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3599,7 +3599,7 @@
#define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8
-#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C
+#define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652c
#define AVIVO_D1MODE_VIEWPORT_START 0x6580
#define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584
#define AVIVO_D1MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6588
@@ -3651,6 +3651,7 @@
#define AVIVO_D2CUR_SIZE 0x6c10
#define AVIVO_D2CUR_POSITION 0x6c14
+#define AVIVO_D2MODE_DESKTOP_HEIGHT 0x6d2c
#define AVIVO_D2MODE_VIEWPORT_START 0x6d80
#define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84
#define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88
@@ -3658,6 +3659,7 @@
#define AVIVO_D2SCL_SCALER_ENABLE 0x6d90
#define AVIVO_D2SCL_SCALER_TAP_CONTROL 0x6d94
+#define AVIVO_D2SCL_UPDATE 0x6dcc
#define AVIVO_DDIA_BIT_DEPTH_CONTROL 0x7214