diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-17 14:37:05 +1000 |
---|---|---|
committer | Brice Goglin <bgoglin@debian.org> | 2008-08-02 18:47:29 +0200 |
commit | dcee07a3c4fbc6de77ee2bc0c7c7fe4cdfbeebda (patch) | |
tree | e53a37c5f2b921fc1cc0faf5fdbef008307b773a | |
parent | 9c46a8dd46cd583468254130c832993881eced20 (diff) | |
download | xf86-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.c | 20 | ||||
-rw-r--r-- | src/radeon_driver.c | 130 | ||||
-rw-r--r-- | src/radeon_probe.h | 1 | ||||
-rw-r--r-- | src/radeon_reg.h | 4 |
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 |