summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@samba.(none)>2008-03-21 15:24:36 -0400
committerAlex Deucher <alex@samba.(none)>2008-03-21 15:24:36 -0400
commitfb1cffac05ae20c8365b25a2042b0ae961880faf (patch)
treedcc917b497533d73556f0d8810aaf5b66b11c642
parent5e3b21284482df9974c9a58f248f0100def2bb0c (diff)
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.
-rw-r--r--src/legacy_crtc.c26
-rw-r--r--src/legacy_output.c92
-rw-r--r--src/radeon_probe.h14
-rw-r--r--src/radeon_reg.h35
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