From fb1cffac05ae20c8365b25a2042b0ae961880faf Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 21 Mar 2008 15:24:36 -0400 Subject: RS4xx: attempt to fix TMDS/DVO support XPRESS chips added a second set of FP control registers. I don't have the hw to test however. --- src/legacy_crtc.c | 26 +++++++-------- src/legacy_output.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/radeon_probe.h | 14 +++++--- src/radeon_reg.h | 35 +++++++++++++++++--- 4 files changed, 146 insertions(+), 21 deletions(-) diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c index 06891142..4257b8ae 100644 --- a/src/legacy_crtc.c +++ b/src/legacy_crtc.c @@ -179,10 +179,10 @@ RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn, OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl); if (info->ChipFamily == CHIP_FAMILY_RS400) { - OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30); - OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34); - OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38); - OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c); + OUTREG(RS400_DISP2_REQ_CNTL1, restore->disp2_req_cntl1); + OUTREG(RS400_DISP2_REQ_CNTL2, restore->disp2_req_cntl2); + OUTREG(RS400_DMIF_MEM_CNTL1, restore->dmif_mem_cntl1); + OUTREG(RS400_DISP1_REQ_CNTL1, restore->disp1_req_cntl1); } OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl); @@ -551,12 +551,12 @@ RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save) save->fp_v2_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID); if (info->ChipFamily == CHIP_FAMILY_RS400) { - save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30); - save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34); - save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38); - save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c); + save->disp2_req_cntl1 = INREG(RS400_DISP2_REQ_CNTL1); + save->disp2_req_cntl2 = INREG(RS400_DISP2_REQ_CNTL2); + save->dmif_mem_cntl1 = INREG(RS400_DMIF_MEM_CNTL1); + save->disp1_req_cntl1 = INREG(RS400_DISP1_REQ_CNTL1); } - + save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL); /* track if the crtc is enabled for text restore */ @@ -1126,10 +1126,10 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save, save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid; if (info->ChipFamily == CHIP_FAMILY_RS400) { - save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */ - save->rs480_unk_e34 = 0x2749D000; /* AMD really should */ - save->rs480_unk_e38 = 0x29ca71dc; /* release docs */ - save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */ + save->disp2_req_cntl1 = 0x105DC1CC; + save->disp2_req_cntl2 = 0x2749D000; + save->dmif_mem_cntl1 = 0x29ca71dc; + save->disp1_req_cntl1 = 0x28FBC3AC; } return TRUE; diff --git a/src/legacy_output.c b/src/legacy_output.c index 9dc72869..0d6e4f1d 100644 --- a/src/legacy_output.c +++ b/src/legacy_output.c @@ -103,6 +103,12 @@ RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl); OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl); + if (info->ChipFamily == CHIP_FAMILY_RS400) { + OUTREG(RS400_FP_2ND_GEN_CNTL, restore->fp_2nd_gen_cntl); + /*OUTREG(RS400_TMDS2_CNTL, restore->tmds2_cntl);*/ + OUTREG(RS400_TMDS2_TRANSMITTER_CNTL, restore->tmds2_transmitter_cntl); + } + /* old AIW Radeon has some BIOS initialization problem * with display buffer underflow, only occurs to DFP */ @@ -121,6 +127,8 @@ RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore) OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl); + if (info->ChipFamily == CHIP_FAMILY_RS400) + OUTREG(RS400_FP2_2_GEN_CNTL, restore->fp2_2_gen_cntl); } /* Write RMX registers */ @@ -203,6 +211,14 @@ RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save) /* bit 22 of TMDS_PLL_CNTL is read-back inverted */ save->tmds_pll_cntl ^= (1 << 22); } + + if (info->ChipFamily == CHIP_FAMILY_RS400) { + save->fp_2nd_gen_cntl = INREG(RS400_FP_2ND_GEN_CNTL); + save->fp2_2_gen_cntl = INREG(RS400_FP2_2_GEN_CNTL); + save->tmds2_cntl = INREG(RS400_TMDS2_CNTL); + save->tmds2_transmitter_cntl = INREG(RS400_TMDS2_TRANSMITTER_CNTL); + } + } Bool @@ -716,6 +732,13 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + if (info->ChipFamily == CHIP_FAMILY_RS400) { + tmp = INREG(RS400_FP_2ND_GEN_CNTL); + tmp |= (RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); + OUTREG(RS400_FP_2ND_GEN_CNTL, tmp); + save->fp_2nd_gen_cntl |= (RS400_FP_2ND_ON | + RS400_TMDS_2ND_EN); + } } else if (radeon_output->TMDSType == TMDS_EXT) { info->output_dfp2 |= (1 << o); tmp = INREG(RADEON_FP2_GEN_CNTL); @@ -724,6 +747,14 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; + if (info->ChipFamily == CHIP_FAMILY_RS400) { + tmp = INREG(RS400_FP2_2_GEN_CNTL); + tmp &= ~RS400_FP2_2_BLANK_EN; + tmp |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + OUTREG(RS400_FP2_2_GEN_CNTL, tmp); + save->fp2_2_gen_cntl |= (RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + save->fp2_2_gen_cntl &= ~RS400_FP2_2_BLANK_EN; + } } } else if (radeon_output->MonType == MT_LCD) { info->output_lcd1 |= (1 << o); @@ -780,6 +811,13 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); OUTREG(RADEON_FP_GEN_CNTL, tmp); save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + if (info->ChipFamily == CHIP_FAMILY_RS400) { + tmp = INREG(RS400_FP_2ND_GEN_CNTL); + tmp &= ~(RS400_FP_2ND_ON | RS400_TMDS_2ND_EN); + OUTREG(RS400_FP_2ND_GEN_CNTL, tmp); + save->fp_2nd_gen_cntl &= ~(RS400_FP_2ND_ON | + RS400_TMDS_2ND_EN); + } } } else if (radeon_output->TMDSType == TMDS_EXT) { info->output_dfp2 &= ~(1 << o); @@ -790,6 +828,14 @@ RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable) OUTREG(RADEON_FP2_GEN_CNTL, tmp); save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN; + if (info->ChipFamily == CHIP_FAMILY_RS400) { + tmp = INREG(RS400_FP2_2_GEN_CNTL); + tmp |= RS400_FP2_2_BLANK_EN; + tmp &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + OUTREG(RS400_FP2_2_GEN_CNTL, tmp); + save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | RS400_FP2_2_DVO2_EN); + save->fp2_2_gen_cntl |= RS400_FP2_2_BLANK_EN; + } } } } else if (radeon_output->MonType == MT_LCD) { @@ -918,6 +964,29 @@ RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save, save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2; } + if (info->ChipFamily == CHIP_FAMILY_RS400) { + save->tmds2_transmitter_cntl = info->SavedReg->tmds2_transmitter_cntl & + ~(RS400_TMDS2_PLLRST); + save->tmds2_transmitter_cntl &= ~(RS400_TMDS2_PLLEN); + + save->fp_2nd_gen_cntl = info->SavedReg->fp_2nd_gen_cntl; + + if (pScrn->rgbBits == 8) + save->fp_2nd_gen_cntl |= RS400_PANEL_FORMAT_2ND; /* 24 bit format */ + else + save->fp_2nd_gen_cntl &= ~RS400_PANEL_FORMAT_2ND;/* 18 bit format */ + + save->fp_2nd_gen_cntl &= ~RS400_FP_2ND_SOURCE_SEL_MASK; + + if (IsPrimary) { + if (radeon_output->Flags & RADEON_USE_RMX) + save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_RMX; + else + save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC1; + } else + save->fp_2nd_gen_cntl |= RS400_FP_2ND_SOURCE_SEL_CRTC2; + } + } static void @@ -954,6 +1023,8 @@ RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save, save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK; if (radeon_output->Flags & RADEON_USE_RMX) save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX; + else + save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC1; } else { save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2; } @@ -966,6 +1037,27 @@ RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save, } } + if (info->ChipFamily == CHIP_FAMILY_RS400) { + if (pScrn->rgbBits == 8) + save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl | + RS400_FP2_2_PANEL_FORMAT; /* 24 bit format, */ + else + save->fp2_2_gen_cntl = info->SavedReg->fp2_2_gen_cntl & + ~RS400_FP2_2_PANEL_FORMAT;/* 18 bit format, */ + + save->fp2_2_gen_cntl &= ~(RS400_FP2_2_ON | + RS400_FP2_2_DVO2_EN | + RS400_FP2_2_SOURCE_SEL_MASK); + + if (IsPrimary) { + if (radeon_output->Flags & RADEON_USE_RMX) + save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_RMX; + else + save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC1; + } else + save->fp2_2_gen_cntl |= RS400_FP2_2_SOURCE_SEL_CRTC2; + } + } static void diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 7dfce685..0096ce02 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -505,10 +505,16 @@ typedef struct { CARD32 palette[256]; CARD32 palette2[256]; - CARD32 rs480_unk_e30; - CARD32 rs480_unk_e34; - CARD32 rs480_unk_e38; - CARD32 rs480_unk_e3c; + CARD32 disp2_req_cntl1; + CARD32 disp2_req_cntl2; + CARD32 dmif_mem_cntl1; + CARD32 disp1_req_cntl1; + + CARD32 fp_2nd_gen_cntl; + CARD32 fp2_2_gen_cntl; + CARD32 tmds2_cntl; + CARD32 tmds2_transmitter_cntl; + /* TV out registers */ CARD32 tv_master_cntl; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 62454035..6a3d964f 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -887,6 +887,33 @@ # define RADEON_VERT_STRETCH_BLEND (1 << 26) # define RADEON_VERT_AUTO_RATIO_EN (1 << 27) # define RADEON_VERT_STRETCH_RESERVED 0xf1000000 +#define RS400_FP_2ND_GEN_CNTL 0x0384 +# define RS400_FP_2ND_ON (1 << 0) +# define RS400_FP_2ND_BLANK_EN (1 << 1) +# define RS400_TMDS_2ND_EN (1 << 2) +# define RS400_PANEL_FORMAT_2ND (1 << 3) +# define RS400_FP_2ND_EN_TMDS (1 << 7) +# define RS400_FP_2ND_DETECT_SENSE (1 << 8) +# define RS400_FP_2ND_SOURCE_SEL_MASK (3 << 10) +# define RS400_FP_2ND_SOURCE_SEL_CRTC1 (0 << 10) +# define RS400_FP_2ND_SOURCE_SEL_CRTC2 (1 << 10) +# define RS400_FP_2ND_SOURCE_SEL_RMX (2 << 10) +# define RS400_FP_2ND_DETECT_EN (1 << 12) +# define RS400_HPD_2ND_SEL (1 << 13) +#define RS400_FP2_2_GEN_CNTL 0x0388 +# define RS400_FP2_2_BLANK_EN (1 << 1) +# define RS400_FP2_2_ON (1 << 2) +# define RS400_FP2_2_PANEL_FORMAT (1 << 3) +# define RS400_FP2_2_DETECT_SENSE (1 << 8) +# define RS400_FP2_2_SOURCE_SEL_MASK (3 << 10) +# define RS400_FP2_2_SOURCE_SEL_CRTC1 (0 << 10) +# define RS400_FP2_2_SOURCE_SEL_CRTC2 (1 << 10) +# define RS400_FP2_2_SOURCE_SEL_RMX (2 << 10) +# define RS400_FP2_2_DVO2_EN (1 << 25) +#define RS400_TMDS2_CNTL 0x0394 +#define RS400_TMDS2_TRANSMITTER_CNTL 0x03a4 +# define RS400_TMDS2_PLLEN (1 << 0) +# define RS400_TMDS2_PLLRST (1 << 1) #define RADEON_GEN_INT_CNTL 0x0040 #define RADEON_GEN_INT_STATUS 0x0044 @@ -3328,10 +3355,10 @@ # define RADEON_TVPLL_TEST_DIS (1 << 31) # define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30) -#define RADEON_RS480_UNK_e30 0xe30 -#define RADEON_RS480_UNK_e34 0xe34 -#define RADEON_RS480_UNK_e38 0xe38 -#define RADEON_RS480_UNK_e3c 0xe3c +#define RS400_DISP2_REQ_CNTL1 0xe30 +#define RS400_DISP2_REQ_CNTL2 0xe34 +#define RS400_DMIF_MEM_CNTL1 0xe38 +#define RS400_DISP1_REQ_CNTL1 0xe3c #define RS690_MC_INDEX 0x78 # define RS690_MC_INDEX_MASK 0x1ff -- cgit v1.2.3