summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@t41p.hsd1.va.comcast.net>2007-08-14 23:42:32 -0400
committerAlex Deucher <alex@t41p.hsd1.va.comcast.net>2007-08-14 23:42:32 -0400
commit6f398cd07ea734dd66a8eac71b629e59123d75b8 (patch)
tree547647b5f3fd250fdd88b5e02dc1d19468f75832
parent366a1d4c240ac93622caff97b652696db99bf2e6 (diff)
RADEON: Implement improved tv load detection for r300
The previous implementation resulted in false positives on occasion. This method works much more reliably. Based on beos code by Thomas Kurschel
-rw-r--r--src/radeon_output.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/radeon_output.c b/src/radeon_output.c
index fdf85a9..7f8f406 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1325,6 +1325,76 @@ radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
}
static RADEONMonitorType
+r300_detect_tv(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
+ CARD32 gpiopad_a;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ gpiopad_a = INREG(RADEON_GPIOPAD_A);
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+
+ OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
+
+ OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
+
+ OUTREG(RADEON_DAC_EXT_CNTL,
+ RADEON_DAC2_FORCE_BLANK_OFF_EN |
+ RADEON_DAC2_FORCE_DATA_EN |
+ RADEON_DAC_FORCE_DATA_SEL_RGB |
+ (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(4000);
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN |
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(6000);
+
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
+ found = MT_STV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "S-Video TV connection detected\n");
+ } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
+ found = MT_CTV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Composite TV connection detected\n" );
+ }
+
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+ OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+
+ return found;
+}
+
+static RADEONMonitorType
radeon_detect_tv(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -1333,6 +1403,9 @@ radeon_detect_tv(ScrnInfoPtr pScrn)
CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
RADEONMonitorType found = MT_NONE;
+ if (IS_R300_VARIANT)
+ return r300_detect_tv(pScrn);
+
/* save the regs we need */
dac_cntl2 = INREG(RADEON_DAC_CNTL2);
crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);