? Makefile
? r128.4x.html
? r128._man
? radeon.4x.html
? radeon._man
? radeon_tvout.c
? radeon_tvout.diff
? radeon_tvout.h
? tvout.diff
Index: Imakefile
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v
retrieving revision 1.14
diff -u -r1.14 Imakefile
--- Imakefile 26 Mar 2005 00:53:01 -0000 1.14
+++ Imakefile 9 Apr 2005 14:45:04 -0000
@@ -190,7 +190,7 @@
SRCS3 = r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
r128_video.c $(DRISRCS3) $(MODSRCS3)
SRCS4 = radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c radeon_driver.c \
- radeon_video.c radeon_bios.c radeon_mm_i2c.c radeon_vip.c \
+ radeon_video.c radeon_bios.c radeon_mm_i2c.c radeon_vip.c radeon_tvout.c \
$(DRISRCS4) $(MODSRCS4)
SRCS_THEATRE = theatre.c $(MODSRC_THEATRE)
@@ -206,7 +206,7 @@
OBJS3 = r128_accel.o r128_cursor.o r128_dga.o r128_driver.o \
r128_video.o $(DRIOBJS3) $(MODOBJS3)
OBJS4 = radeon_accel.o radeon_mergedfb.o radeon_cursor.o radeon_dga.o radeon_driver.o \
- radeon_video.o radeon_bios.o radeon_mm_i2c.o radeon_vip.o \
+ radeon_video.o radeon_bios.o radeon_mm_i2c.o radeon_vip.o radeon_tvout.o \
$(DRIOBJS4) $(MODOBJS4)
OBJS_THEATRE = theatre.o $(MODOBJ_THEATRE)
@@ -405,6 +405,8 @@
InstallDriverSDKNonExecFile(radeon_chipset.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_common.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKNonExecFile(radeon_accelfuncs.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(radeon_tvout.c,$(DRIVERSDKDIR)/drivers/ati)
+InstallDriverSDKNonExecFile(radeon_tvout.h,$(DRIVERSDKDIR)/drivers/ati)
InstallDriverSDKObjectModule(ati,$(DRIVERSDKMODULEDIR),drivers)
InstallDriverSDKObjectModule(atimisc,$(DRIVERSDKMODULEDIR),drivers)
Index: radeon.h
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h,v
retrieving revision 1.20
diff -u -r1.20 radeon.h
--- radeon.h 29 Mar 2005 03:49:04 -0000 1.20
+++ radeon.h 9 Apr 2005 14:45:04 -0000
@@ -164,9 +164,9 @@
/* CRTC2 registers */
CARD32 crtc2_gen_cntl;
-
CARD32 dac2_cntl;
CARD32 disp_output_cntl;
+ CARD32 disp_tv_out_cntl;
CARD32 disp_hw_debug;
CARD32 disp2_merge_cntl;
CARD32 grph2_buffer_cntl;
@@ -177,6 +177,7 @@
CARD32 crtc2_offset;
CARD32 crtc2_offset_cntl;
CARD32 crtc2_pitch;
+
/* Flat panel registers */
CARD32 fp_crtc_h_total_disp;
CARD32 fp_crtc_v_total_disp;
@@ -194,6 +195,40 @@
CARD32 tmds_pll_cntl;
CARD32 tmds_transmitter_cntl;
+ /* TV out registers */
+ CARD32 tv_master_cntl;
+ CARD32 tv_tv_pll_cntl;
+ CARD32 tv_crt_pll_cntl;
+ CARD32 tv_htotal;
+ CARD32 tv_hsize;
+ CARD32 tv_hdisp;
+ CARD32 tv_hstart;
+ CARD32 tv_vtotal;
+ CARD32 tv_vdisp;
+ CARD32 tv_timing_cntl;
+ CARD32 tv_vscaler_cntl;
+ CARD32 tv_vscaler_cntl2;
+ CARD32 tv_sync_size;
+ CARD32 tv_vrestart;
+ CARD32 tv_hrestart;
+ CARD32 tv_frestart;
+ CARD32 tv_ftotal;
+ CARD32 tv_clock_sel_cntl;
+ CARD32 tv_clkout_cntl;
+ CARD32 tv_data_delay_a;
+ CARD32 tv_data_delay_b;
+ CARD32 tv_dac_cntl;
+ CARD32 tv_pll_cntl0;
+ CARD32 tv_modulator_cntl1;
+ CARD32 tv_modulator_cntl2;
+ CARD32 tv_frame_lock_cntl;
+ CARD32 tv_pre_dac_mux_cntl;
+ CARD32 tv_rgb_cntl;
+ CARD32 tv_saw_tooth_cntl;
+ CARD32 tv_rise_cntl;
+ CARD32 tv_fall_cntl;
+ CARD32 tv_uv_adr;
+
/* Computed values for PLL */
CARD32 dot_clock_freq;
CARD32 pll_output_freq;
@@ -204,6 +239,7 @@
unsigned ppll_ref_div;
unsigned ppll_div_3;
CARD32 htotal_cntl;
+ CARD32 vclk_cntl;
/* Computed values for PLL2 */
CARD32 dot_clock_freq_2;
@@ -215,14 +251,13 @@
CARD32 p2pll_ref_div;
CARD32 p2pll_div_0;
CARD32 htotal_cntl2;
+ CARD32 pixclks_cntl;
/* Pallet */
Bool palette_valid;
CARD32 palette[256];
CARD32 palette2[256];
- CARD32 tv_dac_cntl;
-
} RADEONSaveRec, *RADEONSavePtr;
typedef struct {
@@ -643,6 +678,19 @@
Bool VGAAccess;
+ /* tv out support */
+ int HOverPlusTV;
+ int HSyncWidthTV;
+ int HBlankTV;
+ int VOverPlusTV;
+ int VSyncWidthTV;
+ int VBlankTV;
+ int videoChip;
+ int vipChannel;
+ int tvoutType;
+ int tvFormat;
+ int tvModeIndex;
+
} RADEONInfoRec, *RADEONInfoPtr;
#define RADEONWaitForFifo(pScrn, entries) \
Index: radeon_driver.c
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c,v
retrieving revision 1.49
diff -u -r1.49 radeon_driver.c
--- radeon_driver.c 4 Apr 2005 23:07:08 -0000 1.49
+++ radeon_driver.c 9 Apr 2005 14:45:10 -0000
@@ -69,6 +69,8 @@
#include "radeon_probe.h"
#include "radeon_version.h"
#include "radeon_mergedfb.h"
+#include "radeon_tvout.h"
+#include "theatre_reg.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -179,7 +181,8 @@
OPTION_BIOS_HOTKEYS,
OPTION_VGA_ACCESS,
OPTION_REVERSE_DDC,
- OPTION_LVDS_PROBE_PLL
+ OPTION_LVDS_PROBE_PLL,
+ OPTION_TV_FORMAT
} RADEONOpts;
static const OptionInfoRec RADEONOptions[] = {
@@ -237,6 +240,7 @@
{ OPTION_VGA_ACCESS, "VGAAccess", OPTV_BOOLEAN, {0}, TRUE },
{ OPTION_REVERSE_DDC, "ReverseDDC", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_LVDS_PROBE_PLL, "LVDSProbePLL", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_TV_FORMAT, "TVFormat", OPTV_INTEGER, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -474,6 +478,50 @@
{{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_R420*/
};
+/* TV out */
+
+static unsigned long std_tv_clk[6] = {
+ 42954540, 53203425, 42907338, 42984675, 53203425, 53203425,
+};
+
+static TVTimingParam std_tv_timing[6] = {
+ {2730, 200, 28, 200, 110, 2170, 525, 440, 525, 2}, /* ntsc */
+ {3405, 250, 28, 320, 80, 2627, 625, 498, 625, 2}, /* pal */
+ {2727, 200, 28, 200, 110, 2170, 525, 440, 525, 2}, /* palm */
+ {2751, 202, 28, 202, 110, 2190, 625, 510, 625, 2}, /* palnc */
+ {3405, 250, 28, 320, 80, 2627, 625, 498, 625, 2}, /* scart pal ??? */
+ {3405, 250, 28, 320, 80, 2627, 525, 440, 525, 2}, /* pal 60 */
+};
+
+static TVOutModes tv_modes[] = {
+ {320, 350, 406, 525, 408, 625, 0, 0, 0, 0, 0, 0},
+ {320, 400, 406, 525, 432, 625, 0, 0, 0, 0, 0, 0},
+ {320, 480, 400, 600, 408, 625, 0, 0, 0, 0, 0, 0},
+ {360, 400, 451, 525, 459, 625, 0, 0, 0, 0, 0, 0},
+ {400, 600, 500, 716, 560, 762, 0, 0, 0, 0, 0, 0},
+ {512, 384, 672, 525, 660, 625, 671, 472, 661, 487, 0, 0},
+ {512, 768, 672, 1000, 660, 625, 0, 0, 0, 0},
+ {640, 350, 800, 525, 808, 625, 792, 498, 688, 388, 784, 390},
+ {640, 480, 800, 600, 816, 625, 800, 525, 656, 490, 752, 492},
+ {720, 350, 900, 525, 909, 625, 0, 0, 0, 0, 0, 0},
+ {720, 400, 900, 525, 909, 625, 896, 417, 736, 401, 808, 404},
+ {720, 480, 896, 590, 909, 625, 896, 497, 736, 481, 808, 484},
+ {720, 576, 896, 716, 912, 730, 0, 0, 0, 0, 0, 0},
+ {768, 576, 950, 740, 950, 740, 0, 0, 0, 0, 0, 0},
+ {800, 600, 995, 740, 1120, 740, 1056, 628, 840, 601, 968, 605},
+ {848, 480, 1088, 590, 1104, 625, 1056, 497, 864, 481, 952, 484},
+ {1024, 480, 1280, 960, 1286, 961, 0, 0, 0, 0, 0, 0},
+ {1024, 768, 1280, 959, 1286, 961, 1344, 806, 1048, 771, 1184, 777},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
+static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
+static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
+static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
+
+/* TV out */
+
extern int getRADEONEntityIndex(void);
struct RADEONInt10Save {
@@ -837,6 +885,10 @@
if (!info->IsSecondary) {
switch(info->DisplayType) {
+ case MT_STV:
+ case MT_CTV:
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, 0, ~RADEON_DAC_TVO_EN);
case MT_LCD:
case MT_CRT:
case MT_DFP:
@@ -849,14 +901,21 @@
default:
break;
}
- if (info->MergedFB)
+ if (info->MergedFB) {
OUTREGP(RADEON_CRTC2_GEN_CNTL,
RADEON_CRTC2_DISP_DIS,
~(RADEON_CRTC2_DISP_DIS));
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV))
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, 0, ~RADEON_DAC_TVO_EN);
+ }
} else {
OUTREGP(RADEON_CRTC2_GEN_CNTL,
RADEON_CRTC2_DISP_DIS,
~(RADEON_CRTC2_DISP_DIS));
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV))
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, 0, ~RADEON_DAC_TVO_EN);
}
}
@@ -868,6 +927,10 @@
if (!info->IsSecondary) {
switch (info->DisplayType) {
+ case MT_STV:
+ case MT_CTV:
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, RADEON_DAC_TVO_EN, ~RADEON_DAC_TVO_EN);
case MT_LCD:
case MT_CRT:
case MT_DFP:
@@ -880,12 +943,23 @@
default:
break;
}
- if (info->MergedFB)
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, RADEON_DAC_TVO_EN, ~RADEON_DAC_TVO_EN);
+ }/* else {*/
OUTREGP(RADEON_CRTC2_GEN_CNTL,
0,
~(RADEON_CRTC2_DISP_DIS));
+ /*}*/
+ }
} else {
switch (info->DisplayType) {
+ case MT_CTV:
+ case MT_STV:
+ if (info->tvoutType != TVOUT_INTERNAL)
+ OUTREGP (RADEON_DAC_CNTL, RADEON_DAC_TVO_EN, ~RADEON_DAC_TVO_EN);
+ /*break;*/
case MT_LCD:
case MT_DFP:
case MT_CRT:
@@ -1720,7 +1794,7 @@
{
"NONE",
"Internal",
- "External"
+ "External"
};
const char *DDCTypeName[5] =
@@ -1729,7 +1803,7 @@
"MONID",
"DVI_DDC",
"VGA_DDC",
- "CRT2_DDC"
+ "CRT2_DDC"
};
const char *DACTypeName[3] =
@@ -1765,7 +1839,7 @@
"Unsupported"
};
- max_mt = 5;
+ max_mt = 7;
if(info->IsSecondary) {
info->DisplayType = (RADEONMonitorType)pRADEONEnt->MonType2;
@@ -1957,6 +2031,23 @@
}
+#if 0
+ if ((pRADEONEnt->PortInfo[1].MonType == MT_CTV) ||
+ (pRADEONEnt->PortInfo[1].MonType == MT_STV) ||
+ (pRADEONEnt->PortInfo[0].MonType == MT_CTV) ||
+ (pRADEONEnt->PortInfo[0].MonType == MT_STV)) {
+ pRADEONEnt->PortInfo[1].DACType = DAC_PRIMARY;
+ pRADEONEnt->PortInfo[1].TMDSType = TMDS_UNKNOWN;
+ pRADEONEnt->PortInfo[1].DDCType = DDC_VGA;
+ pRADEONEnt->PortInfo[1].ConnectorType = CONNECTOR_CRT;
+ pRADEONEnt->PortInfo[0].DACType = DAC_TVDAC;
+ pRADEONEnt->PortInfo[0].TMDSType = TMDS_UNKNOWN;
+ pRADEONEnt->PortInfo[0].DDCType = DDC_NONE_DETECTED;
+ pRADEONEnt->PortInfo[0].ConnectorType = pRADEONEnt->PortInfo[0].MonType+1;
+ pRADEONEnt->PortInfo[0].MonInfo = NULL;
+ }
+#endif
+
if(((!info->HasCRTC2) || info->IsDellServer)) {
if (pRADEONEnt->PortInfo[0].MonType == MT_UNKNOWN) {
if((pRADEONEnt->PortInfo[0].MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI, &pRADEONEnt->PortInfo[0])));
@@ -2349,6 +2440,8 @@
case PCI_CHIP_RADEON_LZ:
info->IsMobility = TRUE;
info->ChipFamily = CHIP_FAMILY_RV100;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV100_QY:
@@ -2356,6 +2449,8 @@
case PCI_CHIP_RN50_515E: /* RN50 is based on the RV100 but 3D isn't guaranteed to work. YMMV. */
case PCI_CHIP_RN50_5969:
info->ChipFamily = CHIP_FAMILY_RV100;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
/* DELL triple-head configuration. */
if ((info->PciInfo->subsysVendor == PCI_VENDOR_DELL) &&
@@ -2380,6 +2475,8 @@
case PCI_CHIP_RS100_4136:
info->ChipFamily = CHIP_FAMILY_RS100;
info->IsIGP = TRUE;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RS200_4337:
@@ -2387,6 +2484,8 @@
case PCI_CHIP_RS200_4137:
info->ChipFamily = CHIP_FAMILY_RS200;
info->IsIGP = TRUE;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RS250_4437:
@@ -2394,6 +2493,8 @@
case PCI_CHIP_RS250_4237:
info->ChipFamily = CHIP_FAMILY_RS200;
info->IsIGP = TRUE;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R200_BB:
@@ -2402,14 +2503,23 @@
case PCI_CHIP_R200_QL:
case PCI_CHIP_R200_QM:
info->ChipFamily = CHIP_FAMILY_R200;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_RT1;
break;
case PCI_CHIP_RADEON_LW:
case PCI_CHIP_RADEON_LX:
info->IsMobility = TRUE;
+ info->ChipFamily = CHIP_FAMILY_RV200;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_INTERNAL;
+ break;
+
case PCI_CHIP_RV200_QW: /* RV200 desktop */
case PCI_CHIP_RV200_QX:
info->ChipFamily = CHIP_FAMILY_RV200;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV250_Ld:
@@ -2419,6 +2529,8 @@
case PCI_CHIP_RV250_If:
case PCI_CHIP_RV250_Ig:
info->ChipFamily = CHIP_FAMILY_RV250;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RS300_5835:
@@ -2429,6 +2541,8 @@
info->ChipFamily = CHIP_FAMILY_RS300;
info->IsIGP = TRUE;
info->HasSingleDAC = TRUE;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV280_5C61:
@@ -2440,6 +2554,8 @@
case PCI_CHIP_RV280_5964:
case PCI_CHIP_RV280_5965:
info->ChipFamily = CHIP_FAMILY_RV280;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R300_AD:
@@ -2451,6 +2567,8 @@
case PCI_CHIP_R300_NF:
case PCI_CHIP_R300_NG:
info->ChipFamily = CHIP_FAMILY_R300;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV350_NP:
@@ -2468,6 +2586,8 @@
case PCI_CHIP_RV350_AV:
case PCI_CHIP_RV350_4155:
info->ChipFamily = CHIP_FAMILY_RV350;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R350_AH:
@@ -2479,6 +2599,8 @@
case PCI_CHIP_R350_NK:
case PCI_CHIP_R360_NJ:
info->ChipFamily = CHIP_FAMILY_R350;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV380_3150:
@@ -2487,6 +2609,8 @@
case PCI_CHIP_RV380_3E50:
case PCI_CHIP_RV380_3E54:
info->ChipFamily = CHIP_FAMILY_RV380;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV370_5460:
@@ -2496,6 +2620,8 @@
case PCI_CHIP_RV370_5B64:
case PCI_CHIP_RV370_5B65:
info->ChipFamily = CHIP_FAMILY_RV380;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RS400_5A42:
@@ -2510,6 +2636,8 @@
info->ChipFamily = CHIP_FAMILY_RS300; /*CHIP_FAMILY_RS400*/
info->IsIGP = TRUE;
info->HasSingleDAC = TRUE; /*?*/
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_RV410_564A:
@@ -2537,6 +2665,8 @@
case PCI_CHIP_R420_JP:
case PCI_CHIP_R420_4A4F:
info->ChipFamily = CHIP_FAMILY_R420;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R423_UH:
@@ -2549,6 +2679,8 @@
case PCI_CHIP_R423_5D57:
case PCI_CHIP_R423_5550:
info->ChipFamily = CHIP_FAMILY_R420;
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R430_5D49:
@@ -2560,6 +2692,8 @@
case PCI_CHIP_R430_554E:
case PCI_CHIP_R430_554C:
info->ChipFamily = CHIP_FAMILY_R420; /*CHIP_FAMILY_R430*/
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
case PCI_CHIP_R480_5D4C:
@@ -2573,12 +2707,16 @@
case PCI_CHIP_R481_4B49:
case PCI_CHIP_R481_4B4C:
info->ChipFamily = CHIP_FAMILY_R420; /*CHIP_FAMILY_R480*/
+ info->videoChip = VCHIP_RT2;
+ info->tvoutType = TVOUT_INTERNAL;
break;
default:
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
info->HasCRTC2 = FALSE;
+ info->videoChip = VCHIP_RT1;
+ info->tvoutType = TVOUT_RT1;
}
/* Framebuffer */
@@ -2868,6 +3006,32 @@
}
}
+static Bool
+RADEONGetTVInfo (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO, "TV Chip type: %d\n", info->videoChip);
+
+ if (info->tvoutType != TVOUT_INTERNAL)
+ if (!RADEONDetectTheatre (pScrn))
+ return FALSE;
+
+ /*R300DumpTVInfo (pScrn); */
+
+ info->tvFormat = NTSC; /* Default to NTSC */
+ if (xf86GetOptValInteger (info->Options,
+ OPTION_TV_FORMAT, &(info->tvFormat))) {
+ if (info->tvFormat > PAL)
+ info->tvFormat = NTSC;
+ }
+
+ /*TODO: Get tvFormat from BIOS or Config file */
+
+
+ return TRUE;
+}
+
/* BIOS may not have right panel size, we search through all supported
* DDC modes looking for the maximum panel size.
@@ -3501,6 +3665,223 @@
return count;
}
+/*
+ * TV support **********************************
+ */
+static int
+RADEONValidateTVModes (ScrnInfoPtr pScrn)
+{
+ int i, count = 0, width, height;
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ DisplayModePtr last = NULL, new = NULL, first = NULL;
+
+ /* Free any allocated modes during configuration. We don't need them */
+ while (pScrn->modes) {
+ xf86DeleteMode (&pScrn->modes, pScrn->modes);
+ }
+ while (pScrn->modePool) {
+ xf86DeleteMode (&pScrn->modePool, pScrn->modePool);
+ }
+
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+
+ /* If no mode specified in config, we use native resolution */
+ if (!pScrn->display->modes[0]) {
+ pScrn->display->modes[0] = xnfalloc (16);
+ sprintf (pScrn->display->modes[0], "%dx%d", 640, 480);
+ }
+
+ for (i = 0; pScrn->display->modes[i] != NULL; i++) {
+ if (sscanf (pScrn->display->modes[i], "%dx%d", &width, &height) == 2) {
+ int j = 0;
+ while (tv_modes[j].h_disp) {
+ if (width != tv_modes[j].h_disp ||
+ height != tv_modes[j].v_disp) {
+ j++;
+ continue;
+ } else
+ break;
+ };
+
+ if (!tv_modes[j].h_disp) {
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+ "Mode %s is not a valid TV mode.\n",
+ pScrn->display->modes[i]);
+ continue;
+ }
+
+ new = xnfcalloc (1, sizeof (DisplayModeRec));
+ new->prev = last;
+ new->name = xnfalloc (strlen (pScrn->display->modes[i]) + 1);
+ strcpy (new->name, pScrn->display->modes[i]);
+ new->HDisplay = new->CrtcHDisplay = width;
+ new->VDisplay = new->CrtcVDisplay = height;
+ switch (info->tvFormat) {
+ case NTSC:
+ new->HTotal = tv_modes[j].h_total_ntsc;
+ new->VTotal = tv_modes[j].v_total_ntsc;
+ break;
+ case PAL:
+ new->HTotal = tv_modes[j].h_total_pal;
+ new->VTotal = tv_modes[j].v_total_pal;
+ break;
+ default:
+ new->HTotal = tv_modes[j].h_total_ntsc;
+ new->VTotal = tv_modes[j].v_total_ntsc;
+ break;
+ }
+ new->CrtcHTotal = tv_modes[j].h_crtc_total;
+ new->CrtcVTotal = tv_modes[j].v_crtc_total;
+ new->CrtcHSyncStart = tv_modes[j].h_crtc_sync_start;
+ new->CrtcVSyncStart = tv_modes[j].v_crtc_sync_start;
+ new->CrtcHSyncEnd = tv_modes[j].h_crtc_sync_end;
+ new->CrtcVSyncEnd = tv_modes[j].v_crtc_sync_end;
+
+ if (new->prev)
+ new->prev->next = new;
+ last = new;
+ if (!first)
+ first = new;
+ pScrn->display->virtualX =
+ pScrn->virtualX = MAX (pScrn->virtualX, width);
+ pScrn->display->virtualY =
+ pScrn->virtualY = MAX (pScrn->virtualY, height);
+ count++;
+
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO, "TV mode: %s OK\n",
+ pScrn->display->modes[i]);
+
+ } else {
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+ "Mode %s is invalid\n",
+ pScrn->display->modes[i]);
+ continue;
+ }
+ }
+ if (last) {
+ last->next = first;
+ first->prev = last;
+ pScrn->modes = first;
+ RADEONSetPitch(pScrn);
+ }
+ return count;
+}
+
+static int
+RADEONValidateMergeTVModes (ScrnInfoPtr pScrn1)
+{
+ int i, count = 0, width, height;
+ RADEONInfoPtr info = RADEONPTR (pScrn1);
+ ScrnInfoPtr pScrn = info->CRT2pScrn;
+ DisplayModePtr last = NULL, new = NULL, first = NULL;
+
+ /* fill in pScrn2 */
+ pScrn->videoRam = pScrn1->videoRam;
+ pScrn->depth = pScrn1->depth;
+ pScrn->numClocks = pScrn1->numClocks;
+ pScrn->progClock = pScrn1->progClock;
+ pScrn->fbFormat = pScrn1->fbFormat;
+ pScrn->videoRam = pScrn1->videoRam;
+ pScrn->maxHValue = pScrn1->maxHValue;
+ pScrn->maxVValue = pScrn1->maxVValue;
+ pScrn->xInc = pScrn1->xInc;
+
+ if (info->NoVirtual) {
+ pScrn1->display->virtualX = 0;
+ pScrn1->display->virtualY = 0;
+ }
+
+ /* Free any allocated modes during configuration. We don't need them */
+ while (pScrn->modes) {
+ xf86DeleteMode (&pScrn->modes, pScrn->modes);
+ }
+ while (pScrn->modePool) {
+ xf86DeleteMode (&pScrn->modePool, pScrn->modePool);
+ }
+
+ /* If no mode specified in config, we use native resolution */
+ if (!pScrn1->display->modes[0]) {
+ pScrn1->display->modes[0] = xnfalloc (16);
+ sprintf (pScrn1->display->modes[0], "%dx%d", 640, 480);
+ }
+
+ for (i = 0; pScrn1->display->modes[i] != NULL; i++) {
+ if (sscanf (pScrn1->display->modes[i], "%dx%d", &width, &height) == 2) {
+ int j = 0;
+ while (tv_modes[j].h_disp) {
+ if (width != tv_modes[j].h_disp ||
+ height != tv_modes[j].v_disp) {
+ j++;
+ continue;
+ } else
+ break;
+ };
+
+ if (!tv_modes[j].h_disp) {
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+ "Mode %s is not a valid TV mode.\n",
+ pScrn1->display->modes[i]);
+ continue;
+ }
+
+ new = xnfcalloc (1, sizeof (DisplayModeRec));
+ new->prev = last;
+ new->name = xnfalloc (strlen (pScrn1->display->modes[i]) + 1);
+ strcpy (new->name, pScrn1->display->modes[i]);
+ new->HDisplay = new->CrtcHDisplay = width;
+ new->VDisplay = new->CrtcVDisplay = height;
+ switch (info->tvFormat) {
+ case NTSC:
+ new->HTotal = tv_modes[j].h_total_ntsc;
+ new->VTotal = tv_modes[j].v_total_ntsc;
+ break;
+ case PAL:
+ new->HTotal = tv_modes[j].h_total_pal;
+ new->VTotal = tv_modes[j].v_total_pal;
+ break;
+ default:
+ new->HTotal = tv_modes[j].h_total_ntsc;
+ new->VTotal = tv_modes[j].v_total_ntsc;
+ break;
+ }
+ new->CrtcHTotal = tv_modes[j].h_crtc_total;
+ new->CrtcVTotal = tv_modes[j].v_crtc_total;
+ new->CrtcHSyncStart = tv_modes[j].h_crtc_sync_start;
+ new->CrtcVSyncStart = tv_modes[j].v_crtc_sync_start;
+ new->CrtcHSyncEnd = tv_modes[j].h_crtc_sync_end;
+ new->CrtcVSyncEnd = tv_modes[j].v_crtc_sync_end;
+
+ if (new->prev)
+ new->prev->next = new;
+ last = new;
+ if (!first)
+ first = new;
+#if 1
+ pScrn->virtualX = MAX (pScrn1->virtualX, width);
+ pScrn->virtualY = MAX (pScrn1->virtualY, height);
+#endif
+ count++;
+
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO, "TV mode: %s OK\n",
+ pScrn->display->modes[i]);
+
+ } else {
+ xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+ "Mode %s is invalid\n",
+ pScrn->display->modes[i]);
+ continue;
+ }
+ }
+ if (last) {
+ last->next = first;
+ first->prev = last;
+ pScrn->modes = first;
+ RADEONSetPitch(pScrn);
+ }
+ return count;
+}
+
/* This is called by RADEONPreInit to initialize gamma correction */
static Bool RADEONPreInitGamma(ScrnInfoPtr pScrn)
{
@@ -3943,7 +4324,11 @@
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
return FALSE;
}
-
+ } else if (info->DisplayType == MT_CTV || info->DisplayType == MT_STV) {
+ /* TV mode validation routine */
+ modesFound = RADEONValidateTVModes (pScrn);
+ if (modesFound < 1)
+ return FALSE;
} else {
/* First, free any allocated modes during configuration, since
* we don't need them
@@ -4036,8 +4421,10 @@
if (!pRADEONEnt->HasSecondary) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Validating CRTC2 modes for MergedFB ------------ \n");
-
- modesFound = RADEONValidateMergeModes(pScrn);
+ if (info->MergeType == MT_STV || info->MergeType == MT_CTV)
+ modesFound = RADEONValidateMergeTVModes(pScrn);
+ else
+ modesFound = RADEONValidateMergeModes(pScrn);
if (modesFound < 1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"No valid mode found for CRTC2, disabling MergedFB\n");
@@ -4731,6 +5118,11 @@
if (!info->IsSecondary)
RADEONGetMergedFBOptions(pScrn);
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ if (!RADEONGetTVInfo (pScrn)) goto fail;
+ }
+
+
if (!RADEONPreInitGamma(pScrn)) goto fail;
if (!RADEONPreInitModes(pScrn, pInt10)) goto fail;
@@ -5717,12 +6109,28 @@
OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
- OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
- if ((info->ChipFamily == CHIP_FAMILY_R200) ||
- IS_R300_VARIANT) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV))
+ OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+ else
+ OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
+ } else {
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV))
+ OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+ else
+ OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
+ }
} else {
OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+ if (info->MergedFB) {
+ if ((info->MergeType != MT_STV) && (info->MergeType != MT_CTV))
+ OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
+ } else {
+ if ((info->DisplayType != MT_STV) && (info->DisplayType != MT_CTV))
+ OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
+ }
}
OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
@@ -5812,6 +6220,131 @@
}
}
+static void
+RADEONRestoreTVRegisters (ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ OUTREG (RADEON_TV_MASTER_CNTL, restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | 0xf0);
+/*
+ OUTREG(RADEON_TV_TVO_DATA_DELAY_A,
+ restore->tv_data_delay_a);
+ OUTREG(RADEON_TV_TVO_DATA_DELAY_B,
+ restore->tv_data_delay_b);
+
+ OUTREG(RADEON_TV_CLKOUT_CNTL, restore->tv_clkout_cntl);
+ OUTREG(RADEON_TV_PLL_CNTL0, restore->tv_pll_cntl0);
+ OUTREG(RADEON_TV_CLOCK_SEL_CNTL,
+ restore->tv_clock_sel_cntl);
+*/
+ OUTREG (RADEON_TV_HRESTART, restore->tv_hrestart);
+ OUTREG (RADEON_TV_VRESTART, restore->tv_vrestart);
+ OUTREG (RADEON_TV_FRESTART, restore->tv_frestart);
+ OUTREG (RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+ OUTPLLP (pScrn, RADEON_TV_PLL_CNTL, restore->tv_tv_pll_cntl, 0);
+ OUTPLLP (pScrn, RADEON_TV_PLL_CNTL1, restore->tv_pll_cntl0, 0);
+ OUTPLLP (pScrn, RADEON_TV_PLL_FINE_CNTL, 0, 0);
+
+ OUTREG (RADEON_TV_HTOTAL, restore->tv_htotal - 1);
+ /*OUTREG(RADEON_TV_HSIZE, restore->tv_hsize); */
+ OUTREG (RADEON_TV_HDISP, restore->tv_hdisp);
+ OUTREG (RADEON_TV_HSTART, restore->tv_hstart);
+ OUTREG (RADEON_TV_VTOTAL, restore->tv_vtotal - 1);
+ OUTREG (RADEON_TV_VDISP, restore->tv_vdisp);
+
+ OUTREG (RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ OUTREG (RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl);
+ OUTREG (RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+ /*OUTREG(RADEON_TV_SYNC_SIZE, restore->tv_sync_size); */
+ OUTREG (RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_saw_tooth_cntl);
+ OUTREG (RADEON_TV_Y_RISE_CNTL, restore->tv_rise_cntl);
+ OUTREG (RADEON_TV_Y_FALL_CNTL, restore->tv_fall_cntl);
+
+ OUTREG (RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+ OUTREG (RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+
+ OUTREG (RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+ OUTREG (RADEON_TV_UV_ADR, restore->tv_uv_adr);
+
+ OUTREG (RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+ /*OUTREG(RADEON_TV_FRAME_LOCK_CNTL, restore->tv_frame_lock_cntl); */
+
+ usleep (50000);
+
+ OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+ OUTREG (RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+ } else {
+
+ RT_OUTREG(pScrn, VIP_MASTER_CNTL,
+ restore->tv_master_cntl | 0xf3);
+
+ RT_OUTREG(pScrn, VIP_TVO_DATA_DELAY_A,
+ restore->tv_data_delay_a);
+ RT_OUTREG(pScrn, VIP_TVO_DATA_DELAY_B,
+ restore->tv_data_delay_b);
+
+ RT_OUTREG(pScrn, VIP_CLKOUT_CNTL, restore->tv_clkout_cntl);
+ RT_OUTREG(pScrn, VIP_PLL_CNTL0, restore->tv_pll_cntl0);
+
+ RT_OUTREG(pScrn, VIP_DHRESTART, restore->tv_hrestart);
+ RT_OUTREG(pScrn, VIP_DVRESTART, restore->tv_vrestart);
+ RT_OUTREG(pScrn, VIP_DFRESTART, restore->tv_frestart);
+ RT_OUTREG(pScrn, VIP_VFTOTAL, restore->tv_ftotal);
+
+ RT_OUTREG(pScrn, VIP_CLOCK_SEL_CNTL,
+ restore->tv_clock_sel_cntl);
+ RT_OUTREG(pScrn, VIP_TV_PLL_CNTL, restore->tv_tv_pll_cntl);
+ RT_OUTREG(pScrn, VIP_CRT_PLL_CNTL, restore->tv_crt_pll_cntl);
+ RT_OUTREG(pScrn, VIP_HTOTAL, restore->tv_htotal - 1);
+ RT_OUTREG(pScrn, VIP_HSIZE, restore->tv_hsize);
+ RT_OUTREG(pScrn, VIP_HDISP, restore->tv_hdisp);
+ RT_OUTREG(pScrn, VIP_HSTART, restore->tv_hstart);
+ RT_OUTREG(pScrn, VIP_VTOTAL, restore->tv_vtotal - 1);
+ RT_OUTREG(pScrn, VIP_VDISP, restore->tv_vdisp);
+
+ RT_OUTREG(pScrn, VIP_TIMING_CNTL, restore->tv_timing_cntl);
+
+ RT_OUTREG(pScrn, VIP_VSCALER_CNTL1, restore->tv_vscaler_cntl);
+ RT_OUTREG(pScrn, VIP_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+ RT_OUTREG(pScrn, VIP_SYNC_SIZE, restore->tv_sync_size);
+ RT_OUTREG(pScrn, VIP_Y_SAW_TOOTH_CNTL,
+ restore->tv_saw_tooth_cntl);
+ RT_OUTREG(pScrn, VIP_Y_RISE_CNTL, restore->tv_rise_cntl);
+ RT_OUTREG(pScrn, VIP_Y_FALL_CNTL, restore->tv_fall_cntl);
+
+ RT_OUTREG(pScrn, VIP_MODULATOR_CNTL1,
+ restore->tv_modulator_cntl1);
+ RT_OUTREG(pScrn, VIP_MODULATOR_CNTL2,
+ restore->tv_modulator_cntl2);
+
+ RT_OUTREG(pScrn, VIP_RGB_CNTL, restore->tv_rgb_cntl);
+
+ RT_OUTREG(pScrn, VIP_UV_ADR, restore->tv_uv_adr);
+
+ RT_OUTREG(pScrn, VIP_PRE_DAC_MUX_CNTL,
+ restore->tv_pre_dac_mux_cntl);
+ RT_OUTREG(pScrn, VIP_FRAME_LOCK_CNTL,
+ restore->tv_frame_lock_cntl);
+
+ usleep (50000);
+
+ RT_OUTREG(pScrn, VIP_TV_DAC_CNTL, restore->tv_dac_cntl);
+ RT_OUTREG(pScrn, VIP_MASTER_CNTL, restore->tv_master_cntl);
+
+
+ }
+
+}
+
static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
{
int i = 0;
@@ -5954,9 +6487,12 @@
usleep(50000); /* Let the clock to lock */
+#if 0
OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
RADEON_VCLK_SRC_SEL_PPLLCLK,
~(RADEON_VCLK_SRC_SEL_MASK));
+#endif
+ OUTPLLP (pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_cntl, 0);
}
@@ -6013,9 +6549,12 @@
usleep(5000); /* Let the clock to lock */
+#if 0
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
~(RADEON_PIX2CLK_SRC_SEL_MASK));
+#endif
+ OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl, 0);
}
void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
@@ -6204,6 +6743,19 @@
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
static RADEONSaveRec restore0;
+
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ if (info->tvoutType != TVOUT_INTERNAL)
+ RADEONVIPReset (pScrn);
+ RADEONRestoreTVRegisters (pScrn, restore);
+ } else if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ if (info->tvoutType != TVOUT_INTERNAL)
+ RADEONVIPReset (pScrn);
+ RADEONRestoreTVRegisters (pScrn, restore);
+ }
+ }
+
/* For Non-dual head card, we don't have private field in the Entity */
if (!info->HasCRTC2) {
RADEONRestoreCommonRegisters(pScrn, restore);
@@ -6331,6 +6883,7 @@
save->crtc_pitch = INREG(RADEON_CRTC_PITCH);
save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL);
save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL);
+ save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
if (info->IsDellServer) {
save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
@@ -6367,6 +6920,93 @@
}
}
+static void
+RADEONSaveTVRegisters (ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (info->tvoutType == TVOUT_RT1) {
+ save->tv_master_cntl = RT_INREG(pScrn, VIP_MASTER_CNTL);
+ save->tv_tv_pll_cntl = RT_INREG(pScrn, VIP_TV_PLL_CNTL);
+ save->tv_crt_pll_cntl = RT_INREG(pScrn, VIP_CRT_PLL_CNTL);
+ save->tv_htotal = RT_INREG(pScrn, VIP_HTOTAL) + 1;
+ save->tv_hsize = RT_INREG(pScrn, VIP_HSIZE);
+ save->tv_hdisp = RT_INREG(pScrn, VIP_HDISP);
+ save->tv_hstart = RT_INREG(pScrn, VIP_HSTART);
+ save->tv_vtotal = RT_INREG(pScrn, VIP_VTOTAL) + 1;
+ save->tv_vdisp = RT_INREG(pScrn, VIP_VDISP);
+ save->tv_timing_cntl = RT_INREG(pScrn, VIP_TIMING_CNTL);
+ save->tv_vscaler_cntl = RT_INREG(pScrn, VIP_VSCALER_CNTL1);
+ save->tv_vscaler_cntl2 = RT_INREG(pScrn, VIP_VSCALER_CNTL2);
+ save->tv_sync_size = RT_INREG(pScrn, VIP_SYNC_SIZE);
+ save->tv_clock_sel_cntl = RT_INREG(pScrn, VIP_CLOCK_SEL_CNTL);
+ save->tv_clkout_cntl = RT_INREG(pScrn, VIP_CLKOUT_CNTL);
+ save->tv_hrestart = RT_INREG(pScrn, VIP_DHRESTART);
+ save->tv_vrestart = RT_INREG(pScrn, VIP_DVRESTART);
+ save->tv_frestart = RT_INREG(pScrn, VIP_DFRESTART);
+ save->tv_ftotal = RT_INREG(pScrn, VIP_VFTOTAL);
+ save->tv_data_delay_a = RT_INREG(pScrn, VIP_TVO_DATA_DELAY_A);
+ save->tv_data_delay_b = RT_INREG(pScrn, VIP_TVO_DATA_DELAY_B);
+ save->tv_dac_cntl = RT_INREG(pScrn, VIP_TV_DAC_CNTL);
+ save->tv_pll_cntl0 = RT_INREG(pScrn, VIP_PLL_CNTL0);
+ save->tv_modulator_cntl1 =
+ RT_INREG(pScrn, VIP_MODULATOR_CNTL1);
+ save->tv_modulator_cntl2 =
+ RT_INREG(pScrn, VIP_MODULATOR_CNTL2);
+ save->tv_frame_lock_cntl =
+ RT_INREG(pScrn, VIP_FRAME_LOCK_CNTL);
+ save->tv_pre_dac_mux_cntl =
+ RT_INREG(pScrn, VIP_PRE_DAC_MUX_CNTL);
+ save->tv_rgb_cntl = RT_INREG(pScrn, VIP_RGB_CNTL);
+ save->tv_saw_tooth_cntl =
+ RT_INREG(pScrn, VIP_Y_SAW_TOOTH_CNTL);
+ save->tv_rise_cntl = RT_INREG(pScrn, VIP_Y_RISE_CNTL);
+ save->tv_fall_cntl = RT_INREG(pScrn, VIP_Y_FALL_CNTL);
+ save->tv_uv_adr = RT_INREG(pScrn, VIP_UV_ADR);
+
+ save->disp_output_cntl = INREG (RADEON_DISP_OUTPUT_CNTL);
+ } else if (info->tvoutType == TVOUT_INTERNAL) {
+ save->tv_master_cntl = INREG (RADEON_TV_MASTER_CNTL);
+ save->tv_tv_pll_cntl = INPLL (pScrn, RADEON_TV_PLL_CNTL);
+ save->tv_pll_cntl0 = INPLL (pScrn, RADEON_TV_PLL_CNTL1);
+ save->tv_htotal = INREG (RADEON_TV_HTOTAL) + 1;
+ save->tv_hsize = INREG (RADEON_TV_HDISP);
+ save->tv_hdisp = INREG (RADEON_TV_HDISP);
+ save->tv_hstart = INREG (RADEON_TV_HSTART);
+ save->tv_vtotal = INREG (RADEON_TV_VTOTAL) + 1;
+ save->tv_vdisp = INREG (RADEON_TV_VDISP);
+ save->tv_timing_cntl = INREG (RADEON_TV_TIMING_CNTL);
+ save->tv_vscaler_cntl = INREG (RADEON_TV_VSCALER_CNTL1);
+ save->tv_vscaler_cntl2 = INREG (RADEON_TV_VSCALER_CNTL2);
+ /*save->tv_sync_size = INREG(RADEON_TV_SYNC_SIZE);
+ save->tv_clock_sel_cntl = INREG(RADEON_TV_CLOCK_SEL_CNTL);
+ save->tv_clkout_cntl = INREG(RADEON_TV_CLKOUT_CNTL); */
+ save->tv_hrestart = INREG (RADEON_TV_HRESTART);
+ save->tv_vrestart = INREG (RADEON_TV_VRESTART);
+ save->tv_frestart = INREG (RADEON_TV_FRESTART);
+ save->tv_ftotal = INREG (RADEON_TV_FTOTAL);
+ /*save->tv_data_delay_a = INREG(RADEON_TV_TVO_DATA_DELAY_A);
+ save->tv_data_delay_b = INREG(RADEON_TV_TVO_DATA_DELAY_B); */
+ save->tv_dac_cntl = INREG (RADEON_TV_DAC_CNTL);
+ /*save->tv_pll_cntl0 = INREG(RADEON_TV__PLL_CNTL0); */
+ save->tv_modulator_cntl1 = INREG (RADEON_TV_MODULATOR_CNTL1);
+ save->tv_modulator_cntl2 = INREG (RADEON_TV_MODULATOR_CNTL2);
+ /*save->tv_frame_lock_cntl =
+ INREG(RADEON_TV_FRAME_LOCK_CNTL); */
+ save->tv_pre_dac_mux_cntl = INREG (RADEON_TV_PRE_DAC_MUX_CNTL);
+ save->tv_rgb_cntl = INREG (RADEON_TV_RGB_CNTL);
+ save->tv_saw_tooth_cntl = INREG (RADEON_TV_Y_SAW_TOOTH_CNTL);
+ save->tv_rise_cntl = INREG (RADEON_TV_Y_RISE_CNTL);
+ save->tv_fall_cntl = INREG (RADEON_TV_Y_FALL_CNTL);
+ save->tv_uv_adr = INREG (RADEON_TV_UV_ADR);
+
+ save->disp_output_cntl = INREG (RADEON_DISP_OUTPUT_CNTL);
+
+ }
+
+}
+
/* Read CRTC2 registers */
static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
@@ -6376,6 +7016,7 @@
save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
+ save->disp_tv_out_cntl = INREG (RADEON_DISP_TV_OUT_CNTL);
save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
save->crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
@@ -6398,6 +7039,7 @@
save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3);
save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL);
+ save->vclk_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n",
save->ppll_ref_div,
@@ -6415,6 +7057,7 @@
save->p2pll_ref_div = INPLL(pScrn, RADEON_P2PLL_REF_DIV);
save->p2pll_div_0 = INPLL(pScrn, RADEON_P2PLL_DIV_0);
save->htotal_cntl2 = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
+ save->pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08x\n",
save->p2pll_ref_div,
@@ -7070,6 +7713,16 @@
save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+ if ((info->DisplayType == MT_CTV) || (info->DisplayType == MT_STV)) {
+ save->disp_merge_cntl |= RADEON_DISP_RGB_OFFSET_EN;
+ mode->CrtcHTotal = save->tv_htotal;
+ mode->CrtcVTotal = save->tv_vtotal;
+ mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlusTV;
+ mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidthTV;
+ mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlusTV;
+ mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidthTV;
+ }
+
#if X_BYTE_ORDER == X_BIG_ENDIAN
/* Alhought we current onlu use aperture 0, also setting aperture 1 should not harm -ReneR */
switch (pScrn->bitsPerPixel) {
@@ -7102,6 +7755,19 @@
save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
}
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->vclk_cntl = (info->SavedReg.vclk_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | 0xc3;
+ } else {
+ save->vclk_cntl = (info->SavedReg.vclk_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | 0xc2;
+ }
+ } else {
+ save->vclk_cntl = (info->SavedReg.vclk_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+ }
+
RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
save->crtc_pitch, pScrn->virtualX,
info->CurrentLayout.displayWidth));
@@ -7150,21 +7816,52 @@
/* Turn CRT on in case the first head is a DFP */
save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
save->dac2_cntl = info->SavedReg.dac2_cntl;
- /* always let TVDAC drive CRT2, we don't support tvout yet */
- save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
save->disp_output_cntl = info->SavedReg.disp_output_cntl;
- if (info->ChipFamily == CHIP_FAMILY_R200 ||
- IS_R300_VARIANT) {
- save->disp_output_cntl &= ~(RADEON_DISP_DAC_SOURCE_MASK |
+
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ save->dac2_cntl &= ~RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_output_cntl = ((info->SavedReg.disp_output_cntl
+ & ~RADEON_DISP_DAC_SOURCE_MASK) | RADEON_DISP_TV_SOURCE_CRTC);
+ save->disp_tv_out_cntl =
+ info->SavedReg.disp_tv_out_cntl | RADEON_DISP_TV_PATH_SRC_CRTC2;
+ } else {
+ save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_output_cntl &= ~(RADEON_DISP_DAC_SOURCE_MASK |
RADEON_DISP_DAC2_SOURCE_MASK);
- if (pRADEONEnt->MonType1 != MT_CRT) {
- save->disp_output_cntl |= (RADEON_DISP_DAC_SOURCE_CRTC2 |
+ if (pRADEONEnt->MonType1 != MT_CRT) {
+ save->disp_output_cntl |= (RADEON_DISP_DAC_SOURCE_CRTC2 |
RADEON_DISP_DAC2_SOURCE_CRTC2);
+ } else {
+ if (pRADEONEnt->ReversedDAC) {
+ save->disp_output_cntl |= RADEON_DISP_DAC2_SOURCE_CRTC2;
+ } else {
+ save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ }
+ }
+ }
} else {
- if (pRADEONEnt->ReversedDAC) {
- save->disp_output_cntl |= RADEON_DISP_DAC2_SOURCE_CRTC2;
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ save->dac2_cntl &= ~RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_output_cntl = ((info->SavedReg.disp_output_cntl
+ & ~RADEON_DISP_DAC_SOURCE_MASK) | RADEON_DISP_TV_SOURCE_CRTC);
+ save->disp_tv_out_cntl =
+ info->SavedReg.disp_tv_out_cntl | RADEON_DISP_TV_PATH_SRC_CRTC2;
} else {
- save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+ save->disp_output_cntl &= ~(RADEON_DISP_DAC_SOURCE_MASK |
+ RADEON_DISP_DAC2_SOURCE_MASK);
+ if (pRADEONEnt->MonType1 != MT_CRT) {
+ save->disp_output_cntl |= (RADEON_DISP_DAC_SOURCE_CRTC2 |
+ RADEON_DISP_DAC2_SOURCE_CRTC2);
+ } else {
+ if (pRADEONEnt->ReversedDAC) {
+ save->disp_output_cntl |= RADEON_DISP_DAC2_SOURCE_CRTC2;
+ } else {
+ save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ }
+ }
}
}
} else {
@@ -7187,6 +7884,71 @@
save->dac2_cntl |= RADEON_DAC2_DAC_CLK_SEL;
}
}
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV))
+ save->dac2_cntl = info->SavedReg.dac2_cntl
+ & ~(RADEON_DAC2_DAC_CLK_SEL | RADEON_DAC2_DAC2_CLK_SEL);
+ } else {
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV))
+ save->dac2_cntl = info->SavedReg.dac2_cntl
+ & ~(RADEON_DAC2_DAC_CLK_SEL | RADEON_DAC2_DAC2_CLK_SEL);
+ }
+ }
+ }
+
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+
+ mode->CrtcHTotal = save->tv_htotal;
+ mode->CrtcVTotal = save->tv_vtotal;
+ mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlusTV;
+ mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidthTV;
+ mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlusTV;
+ mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidthTV;
+
+#if 0
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ /*save->dac_cntl = info->SavedReg.dac_cntl | (1<<10); */
+ save->disp_output_cntl |= (1 << 16);
+ save->disp_output_cntl &= ~3;
+ save->disp_tv_out_cntl =
+ info->SavedReg.disp_tv_out_cntl | RADEON_DISP_TV_PATH_SRC_CRTC2;
+ /*****workaround for R200 1024x768 Mode problem, not working yet
+ if ((mode->HDisplay == 1024) && (mode->VDisplay == 768)) {
+ save->disp_tv_out_cntl |= 0x555 | (1<<15);
+ mode->CrtcHTotal *= 2;
+ }
+ */
+ }
+#endif
+ }
+ } else {
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+
+ mode->CrtcHTotal = save->tv_htotal;
+ mode->CrtcVTotal = save->tv_vtotal;
+ mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlusTV;
+ mode->CrtcHSyncEnd = mode->CrtcHSyncStart + info->HSyncWidthTV;
+ mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlusTV;
+ mode->CrtcVSyncEnd = mode->CrtcVSyncStart + info->VSyncWidthTV;
+
+#if 0
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ /*save->dac_cntl = info->SavedReg.dac_cntl | (1<<10); */
+ save->disp_output_cntl |= (1 << 16);
+ save->disp_output_cntl &= ~3;
+ save->disp_tv_out_cntl =
+ info->SavedReg.disp_tv_out_cntl | RADEON_DISP_TV_PATH_SRC_CRTC2;
+ /*****workaround for R200 1024x768 Mode problem, not working yet
+ if ((mode->HDisplay == 1024) && (mode->VDisplay == 768)) {
+ save->disp_tv_out_cntl |= 0x555 | (1<<15);
+ mode->CrtcHTotal *= 2;
+ }
+ */
+ }
+#endif
+ }
}
save->crtc2_h_total_disp =
@@ -7296,6 +8058,40 @@
}
#endif
+ if (info->MergedFB) {
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->pixclks_cntl =
+ (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | 0x103;
+ } else {
+ save->pixclks_cntl =
+ (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | 0x102;
+ }
+ } else {
+ save->pixclks_cntl = (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+ }
+ } else {
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->pixclks_cntl =
+ (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | 0x103;
+ } else {
+ save->pixclks_cntl =
+ (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | 0x102;
+ }
+ } else {
+ save->pixclks_cntl = (info->SavedReg.pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+ }
+ }
+
RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
save->crtc2_pitch, pScrn->virtualX,
info->CurrentLayout.displayWidth));
@@ -7546,6 +8342,422 @@
save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
}
+static void
+RADEONInitTVRegisters (ScrnInfoPtr pScrn, RADEONSavePtr orig,
+ RADEONSavePtr save, DisplayModePtr mode, RADEONPLLPtr pll,
+ RADEONInfoPtr info)
+{
+ SETCLK_INPUT SetClkInput;
+ SETCLK_OUTPUT SetClkOutput;
+ SETCRTMN_INPUT SetMnInput;
+ SETCRTMN_OUTPUT SetMnOutput;
+ VT_MASTER_INPUT Input;
+ VT_MASTER_OUTPUT Output;
+ unsigned long start_line, lines_before_active, vert_space,
+ flicker_removal;
+ int retcode, mode888, i;
+ float h_scale;
+
+ /*mode888 = (mode->HDisplay > 800) ? 0 : 1; */
+ mode888 = 1;
+ SetClkInput.RefClk = pll->reference_freq * 10000;
+ SetClkInput.ReqdClk = std_tv_clk[info->tvFormat];
+ if (info->tvFormat == PAL && SetClkInput.RefClk == 27000000)
+ SetClkInput.MinPLLInputFreq = 330000;
+ else
+ SetClkInput.MinPLLInputFreq = 400000;
+ SetClkInput.MinPLLOutputFreq = 100000000;
+ SetClkInput.MaxPLLOutputFreq = 250000000;
+ SetClkInput.BestPLLOutputFreq = 210000000;
+ SetClkInput.FBDivMult = 1;
+ SetClkInput.FixedPostDiv = 0;
+ SetClkInput.PUpperLimit = 16;
+ SetClkInput.ErrSign = 0;
+ SetClkInput.CalculateCRTClkValues = FALSE;
+ SetClkInput.ulChipType = info->videoChip;
+ SetClkInput.CalculateCRTClkValues = FALSE;
+
+ SetClk (&SetClkInput, &SetClkOutput);
+
+ /* Lets setup the input paramaters for SetCRTMN() */
+ SetMnInput.noCLKBY2 = 0;
+ SetMnInput.CRTFBDivMult = 1;
+
+ SetMnInput.MinCRTPLLInputFreq = 200000;
+ if (info->tvoutType == TVOUT_INTERNAL)
+ SetMnInput.MinCRTPLLOutputFreq = 100000000;
+ else
+ SetMnInput.MinCRTPLLOutputFreq = 125000000;
+ SetMnInput.MaxCRTPLLOutputFreq = 250000000;
+
+ if ((info->ChipFamily == CHIP_FAMILY_RV200) &&
+ (mode->HDisplay == 800) && (mode->VDisplay == 600)) {
+ SetMnInput.MinCRTPLLInputFreq = 400000;
+ SetMnInput.MaxCRTPLLOutputFreq = 400000000;
+ }
+
+ if (info->tvoutType == TVOUT_INTERNAL)
+ SetMnInput.BestCRTPLLOutputFreq = 175000000;
+ else
+ SetMnInput.BestCRTPLLOutputFreq = 210000000;
+
+ SetMnInput.CRT_VTotal = mode->VTotal;
+ SetMnInput.CRT_HTotal = mode->HTotal;
+
+ /*****workaround for R200 1024x768 Mode problem, not working yet
+ if (mode->HDisplay == 1024) SetMnInput.CRT_HTotal /= 2;
+ */
+ SetMnInput.MaxVDelta = 2;
+ SetMnInput.MaxHDelta = 40;
+ SetMnInput.CRTRefClk = pll->reference_freq * 10000;
+ SetMnInput.TVRefClk = pll->reference_freq * 10000;
+ SetMnInput.TVFBDivMult = 1;
+ SetMnInput.TV_M = SetClkOutput.BestM;
+ SetMnInput.TV_N = SetClkOutput.BestN;
+ SetMnInput.TV_P = SetClkOutput.BestP;
+ SetMnInput.TV_HTotal = std_tv_timing[info->tvFormat].h_total;
+ SetMnInput.TV_VTotal = std_tv_timing[info->tvFormat].v_total;
+
+ SetMnInput.BytesPerPixel = 2 + mode888;
+ if (info->tvFormat == PAL)
+ SetMnInput.FrameSizeAdjust = -6;
+ else
+ SetMnInput.FrameSizeAdjust = 0;
+ SetMnInput.PUpperLimit = 16;
+ SetMnInput.ErrSign = 0;
+
+ if (info->tvoutType == TVOUT_INTERNAL)
+ SetMnInput.FrameRateDiffTol = 6;
+ else
+ SetMnInput.FrameRateDiffTol = 0;
+
+ SetMnInput.FixedPostDiv = 0;
+ SetMnInput.ulChipType = info->videoChip;
+
+ SetCrtMN (&SetMnInput, &SetMnOutput);
+
+ Input.RefFreq = pll->reference_freq * 10000;
+ start_line = std_tv_timing[info->tvFormat].h_sync_len +
+ std_tv_timing[info->tvFormat].h_setup_del +
+ std_tv_timing[info->tvFormat].h_active_del -
+ std_tv_timing[info->tvFormat].h_genclk_del;
+ lines_before_active =
+ ((std_tv_timing[info->tvFormat].v_field_total -
+ std_tv_timing[info->tvFormat].v_active_lines) / 2 - 1) -
+ VERT_LEAD_IN_LINES + 1;
+
+ Input.TVClksToActive = lines_before_active *
+ std_tv_timing[info->tvFormat].h_total + start_line;
+ Input.TVHPeriod = std_tv_timing[info->tvFormat].h_total;
+ Input.TVHBlank = std_tv_timing[info->tvFormat].h_total -
+ std_tv_timing[info->tvFormat].h_active_len;
+
+ Input.D_HTOTAL = SetMnOutput.HTotal - 1;
+ Input.D_VTOTAL = SetMnOutput.VTotal - 1;
+
+ if ((info->tvFormat == NTSC) ||
+ (info->tvFormat == PAL60) || (info->tvFormat == PALM)) {
+ Input.D_FTOTAL = std_tv_timing[info->tvFormat].v_fields - 1;
+ } else {
+ Input.D_FTOTAL = std_tv_timing[info->tvFormat].v_fields * 2 - 1;
+ }
+ save->tv_ftotal = Input.D_FTOTAL;
+
+ Input.D_HDISP = mode->HDisplay - 1;
+ /*****workaround for R200 1024x768 Mode problem, not working yet
+ if (mode->HDisplay == 1024) Input.D_HDISP = 511;
+ */
+ Input.D_VDISP = mode->VDisplay - 1;
+
+ Input.CRT_M = SetMnOutput.CRT_M;
+ Input.CRT_N = SetMnOutput.CRT_N;
+
+ Input.CRTCLK_USE_CLKBY2 = SetMnOutput.CRTCLK_USE_CLKBY2;
+ Input.BYT_CLK_DIV = SetMnOutput.BYT_CLK_DIV;
+ Input.RGB_565_888 = mode888;
+ Input.TVFBDivMult = 1;
+ Input.CRTFBDivMult = 1;
+
+ Input.TV_M = SetClkOutput.BestM;
+ Input.TV_N = SetClkOutput.BestN;
+ Input.TV_P = SetClkOutput.BestP;
+
+ Input.TV_Lines = std_tv_timing[info->tvFormat].v_field_total;
+ Input.TV_Fsc = std_tv_clk[info->tvFormat];
+ Input.TV_Samples = std_tv_timing[info->tvFormat].h_total;
+
+ Input.UV_ACCUM_INIT = 0x10; /*????? */
+ Input.Y_ACCUM_INIT = 0x0;
+
+ vert_space = SetMnOutput.VTotal * 2 * 10000 /
+ std_tv_timing[info->tvFormat].v_field_total;
+ Input.UV_INC = vert_space * (1 << FRAC_BITS) / 10000;
+ Input.Y_INC = Input.UV_INC;
+ save->tv_vscaler_cntl =
+ (orig->tv_vscaler_cntl & 0xe3ff0000) | Input.UV_INC;
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->tv_vscaler_cntl |= RADEON_RESTART_FIELD;
+ if (mode->HDisplay == 1024)
+ save->tv_vscaler_cntl |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
+ else
+ save->tv_vscaler_cntl |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+ } else
+ save->tv_vscaler_cntl |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+
+ flicker_removal =
+ (float) SetMnOutput.VTotal * 2.0 /
+ std_tv_timing[info->tvFormat].v_field_total + 0.5;
+ if (flicker_removal < 3)
+ flicker_removal = 3;
+ for (i = 0; i < 6; ++i) {
+ if (flicker_removal == SLOPE_limit[i])
+ break;
+ }
+ save->tv_saw_tooth_cntl =
+ (vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) +
+ 5001) / 10000 / 8 | ((SLOPE_value[i] * (1 << (FRAC_BITS - 1)) /
+ 8) << 16);
+ save->tv_fall_cntl =
+ (YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
+ RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
+ 1024;
+ save->tv_rise_cntl =
+ RADEON_Y_RISE_PING_PONG | (flicker_removal * 1024 -
+ 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS -
+ 1)) / 1024;
+
+ save->tv_vscaler_cntl2 = (orig->tv_vscaler_cntl2 & 0x00ffffff)
+ | (Input.UV_ACCUM_INIT << 24)
+ | RADEON_DITHER_MODE
+ | RADEON_Y_OUTPUT_DITHER_EN
+ | RADEON_UV_OUTPUT_DITHER_EN
+ | RADEON_UV_TO_BUF_DITHER_EN;
+
+ retcode =
+ VTMaster ((LPVT_MASTER_INPUT) & Input, (LPVT_MASTER_OUTPUT) & Output);
+ if (retcode) {
+ save->tv_hrestart = Output.D_HRESTART;
+ save->tv_vrestart = Output.D_VRESTART;
+ save->tv_frestart = Output.D_FRESTART;
+ } else {
+ save->tv_hrestart = orig->tv_hrestart;
+ save->tv_vrestart = mode->CrtcVDisplay + 25;
+ save->tv_frestart = orig->tv_frestart;
+ }
+
+ save->tv_tv_pll_cntl = (SetClkOutput.BestP << 24) |
+ ((SetClkOutput.BestN & 0x1ff) << 8) |
+ ((SetClkOutput.BestN >> 9) << 21) |
+ (SetClkOutput.BestM & 0xff) |
+ ((SetClkOutput.BestM >> 8) << 18) | RADEON_TV_SLIP_EN | RADEON_TV_DTO_EN;
+
+ save->tv_crt_pll_cntl =
+ ((SetMnOutput.CRT_N & 0x1ff) << 8) |
+ ((SetMnOutput.CRT_N >> 9) << 21) |
+ (SetMnOutput.CRT_M & 0xff) |
+ ((SetMnOutput.CRT_M >> 8) << 18) |
+ (SetMnOutput.CRTCLK_USE_CLKBY2 ? 0x02000000 : 0);
+
+ save->tv_clock_sel_cntl = (orig->tv_clock_sel_cntl & ~0x3f) |
+ 0x33 | ((SetMnOutput.BYT_CLK_DIV - 1) << 2);
+ save->tv_clkout_cntl = 0x09;
+ if (info->tvoutType != TVOUT_INTERNAL) {
+ save->tv_clkout_cntl |= (1 << 5);
+ }
+
+ save->tv_htotal = SetMnOutput.HTotal;
+ save->tv_hsize = mode->HDisplay;
+ save->tv_hdisp = mode->HDisplay - 1;
+
+ if (info->tvoutType == TVOUT_INTERNAL)
+ save->tv_hstart = mode->HDisplay - mode888 - 12;
+ else
+ save->tv_hstart = mode->HDisplay - mode888 + 12;
+
+ save->tv_vtotal = SetMnOutput.VTotal;
+ save->tv_vdisp = mode->VDisplay - 1;
+ save->tv_sync_size = mode->HDisplay + 8;
+
+ /*****workaround for R200 1024x768 Mode problem, not working yet
+ if (mode->HDisplay == 1024) {
+ save->tv_hsize = 512;
+ save->tv_hdisp = 511;
+ save->tv_hstart = 512 + 12 - mode888;
+ }
+ */
+
+ if (info->tvFormat == NTSC)
+ h_scale = 0.88;
+ else
+ h_scale = 0.91;
+ save->tv_timing_cntl = (orig->tv_timing_cntl & 0xfffff000)
+ /* | (unsigned long) (mode->HDisplay * 4096 / 1976); */
+ | (unsigned long) (mode->HDisplay * 4096 /
+ (std_tv_timing[info->tvFormat].h_active_len +
+ std_tv_timing[info->tvFormat].h_active_del) /
+ h_scale);
+ if (IS_R300_VARIANT) {
+ int tmp;
+ tmp = 0x72 * 640 / mode->HDisplay;
+ /* 1024x768 mode UV seems to be scaled too high by BIOS (0x80)
+ we scale it down a bit here. This is a hack, need to find
+ a proper way of doing this.
+ */
+ save->tv_timing_cntl &= 0x00ffffff;
+ save->tv_timing_cntl |= (tmp << 24);
+ }
+
+ if (info->MergedFB) {
+ if (info->MergeType == MT_STV || info->MergeType == MT_CTV) {
+ save->feedback_div_2 = SetMnOutput.CRT_N;
+ if (info->tvoutType == TVOUT_INTERNAL)
+ save->p2pll_ref_div =
+ SetMnOutput.CRT_M * (SetMnOutput.BYT_CLK_DIV);
+ else {
+ save->p2pll_ref_div =
+ SetMnOutput.CRT_M * (SetMnOutput.BYT_CLK_DIV);
+ /*if (mode->HDisplay == 1024) save->p2pll_ref_div /= 2; */
+ }
+ save->post_div_2 = (2 + mode888);
+ save->p2pll_div_0 = (save->feedback_div_2 | (4 << 16));
+ save->htotal_cntl2 = save->tv_htotal & 0x07;
+ }
+ } else if (info->IsSecondary) {
+ save->feedback_div_2 = SetMnOutput.CRT_N;
+ if (info->tvoutType == TVOUT_INTERNAL)
+ save->p2pll_ref_div =
+ SetMnOutput.CRT_M * (SetMnOutput.BYT_CLK_DIV);
+ else {
+ save->p2pll_ref_div =
+ SetMnOutput.CRT_M * (SetMnOutput.BYT_CLK_DIV);
+ /*if (mode->HDisplay == 1024) save->p2pll_ref_div /= 2; */
+ }
+ save->post_div_2 = (2 + mode888);
+ save->p2pll_div_0 = (save->feedback_div_2 | (4 << 16));
+ save->htotal_cntl2 = save->tv_htotal & 0x07;
+ } else {
+ save->feedback_div = SetMnOutput.CRT_N;
+ save->ppll_ref_div = SetMnOutput.CRT_M * (SetMnOutput.BYT_CLK_DIV);
+ save->post_div = (2 + mode888);
+ save->ppll_div_3 = (save->feedback_div | (4 << 16));
+ save->htotal_cntl = save->tv_htotal & 0x07;
+
+ }
+
+ {
+ info->HBlankTV = mode->CrtcHTotal - mode->CrtcHDisplay;
+ info->HOverPlusTV = mode->CrtcHSyncStart - mode->CrtcHDisplay;
+ info->HSyncWidthTV = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
+
+ /*****workaround for R200 1024x768 Mode problem, not working yet */
+ if (0 /*mode->HDisplay == 1024 */ ) {
+ info->HOverPlusTV = info->HOverPlusTV *
+ (save->tv_htotal * 2 - mode->CrtcHDisplay -
+ info->HSyncWidthTV) / (info->HBlankTV - info->HSyncWidthTV);
+ info->HBlankTV = save->tv_htotal * 2 - mode->CrtcHDisplay;
+ } else {
+ info->HOverPlusTV = info->HOverPlusTV *
+ (save->tv_htotal - mode->CrtcHDisplay - info->HSyncWidthTV) /
+ (info->HBlankTV - info->HSyncWidthTV);
+ info->HBlankTV = save->tv_htotal - mode->CrtcHDisplay;
+ }
+ info->VBlankTV = mode->CrtcVTotal - mode->CrtcVDisplay;
+ info->VOverPlusTV = mode->CrtcVSyncStart - mode->CrtcVDisplay;
+ info->VSyncWidthTV = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+
+ info->VOverPlusTV = info->VOverPlusTV *
+ (save->tv_vtotal - mode->CrtcVDisplay - info->VSyncWidthTV) /
+ (info->VBlankTV - info->VSyncWidthTV);
+ info->VBlankTV = save->tv_vtotal - mode->CrtcVDisplay;
+ if (info->VOverPlusTV == 0)
+ info->VOverPlusTV = 1;
+
+ }
+
+ /*save->tv_hstart = mode->HDisplay + info->HOverPlus - 1;*/
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->tv_dac_cntl = (orig->tv_dac_cntl | RADEON_TV_DAC_BLANK | RADEON_TV_DAC_HOLD)
+ & 0xf8ffffb7;
+
+ if (info->ChipFamily == CHIP_FAMILY_RV200) {
+ save->tv_dac_cntl &= ~(0xf << 20);
+ save->tv_dac_cntl |= (6 << 20);
+ }
+ save->tv_dac_cntl = 0x00680103;
+ } else {
+ save->tv_dac_cntl = (orig->tv_dac_cntl
+ | RADEON_TV_DAC_BLANK
+ | RADEON_TV_DAC_HOLD
+ | RADEON_TV_MONITOR_DETECT_EN)
+ & ~0x3cc;
+ }
+
+ save->tv_modulator_cntl1 = (orig->tv_modulator_cntl1 & ~0x007f7fc0);
+ switch (info->tvFormat) {
+
+ case PAL:
+ save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
+ | RADEON_ALT_PHASE_EN
+ | (0x3b << 16)
+ | (0x3b << 8);
+ save->tv_modulator_cntl2 = (0x1b2) | (0x3e << 16);
+ break;
+
+ case NTSC:
+ default:
+ save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+ save->tv_modulator_cntl1 |= RADEON_SYNC_TIP_LEVEL | (0x3b << 16) | (0x46 << 8);
+ save->tv_modulator_cntl2 = (0x191);
+ break;
+
+ }
+
+ save->tv_data_delay_a = 0x0b0c0a06;
+ save->tv_data_delay_b = 0x070a0a0c;
+ if (info->tvoutType == TVOUT_INTERNAL)
+ save->tv_frame_lock_cntl = 0x0;
+ else
+ save->tv_frame_lock_cntl = 0x0f;
+
+ if (info->tvoutType == TVOUT_INTERNAL) {
+ save->tv_pll_cntl0 = (4 << 8) | (4 << 11) | (2 << 14)
+ | RADEON_TVCLK_SRC_SEL_TVPLL | RADEON_TVPLL_TEST_DIS;
+ if (info->MergedFB) {
+ if (info->MergeType == MT_STV || info->MergeType == MT_CTV)
+ save->tv_rgb_cntl = RADEON_RGB_SRC_SEL_CRTC2;
+ } else if (info->IsSecondary) {
+ save->tv_rgb_cntl = RADEON_RGB_SRC_SEL_CRTC2;
+ } else {
+ save->tv_rgb_cntl = 0x0;
+ }
+ save->tv_rgb_cntl |= RADEON_RGB_DITHER_EN | (0x0b << 16) | (0x07 << 20);
+ save->tv_pre_dac_mux_cntl = RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_DAC_DITHER_EN
+ | (0x2c << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+ } else {
+ save->tv_pll_cntl0 = RADEON_TVPLL_SLEEP | RADEON_TVPLL_REFCLK_SEL
+ | (4 << 8) | (1 << 11) | (5 << 13) | (4 << 16) | (1 << 19) | (5 << 21);
+ save->tv_rgb_cntl = mode888;
+ save->tv_pre_dac_mux_cntl = RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_DAC_DITHER_EN
+ | (0xaf << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+ }
+
+ save->tv_master_cntl = (orig->tv_master_cntl & 0xe0)
+ & (RADEON_CRT_FIFO_CE_EN | RADEON_TV_FIFO_CE_EN);
+ if (info->tvFormat == NTSC)
+ save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
+ else
+ save->tv_master_cntl &= ~RADEON_RESTART_PHASE_FIX;
+
+ save->tv_uv_adr = 0xc8;
+
+}
+
/* Define PLL registers for requested video mode */
static void RADEONInitPLLRegisters(RADEONInfoPtr info, RADEONSavePtr save,
RADEONPLLPtr pll, double dot_clock)
@@ -7745,14 +8957,32 @@
if (info->IsSecondary) {
if (!RADEONInitCrtc2Registers(pScrn, save, mode, info))
return FALSE;
- RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
+
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ RADEONInitTVRegisters (pScrn, &info->SavedReg, save, mode,
+ &info->pll, info);
+ } else {
+ RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
+ }
} else if (info->MergedFB) {
RADEONInitCommonRegisters(save, info);
+
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ RADEONInitTVRegisters (pScrn, &info->SavedReg, save,
+ ((RADEONMergedDisplayModePtr)mode->Private)->CRT1,
+ &info->pll, info);
+ }
+
if (!RADEONInitCrtcRegisters(pScrn, save,
((RADEONMergedDisplayModePtr)mode->Private)->CRT1, info))
return FALSE;
dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT1)->Clock / 1000.0;
- if (dot_clock) {
+ if ((info->DisplayType == MT_STV) ||
+ (info->DisplayType == MT_CTV)) {
+ /* Don't do any thing here, it will be handled in
+ * InitTV function
+ */
+ } else if (dot_clock) {
RADEONInitPLLRegisters(info, save, &info->pll, dot_clock);
} else {
save->ppll_ref_div = info->SavedReg.ppll_ref_div;
@@ -7762,12 +8992,30 @@
RADEONInitCrtc2Registers(pScrn, save,
((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info);
dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT2)->Clock / 1000.0;
- RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->MergeType != MT_CRT);
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ RADEONInitTVRegisters (pScrn, &info->SavedReg, save,
+ ((RADEONMergedDisplayModePtr)mode->Private)->CRT2,
+ &info->pll, info);
+ } else {
+ RADEONInitPLL2Registers(save, &info->pll,
+ dot_clock, info->MergeType != MT_CRT);
+ }
} else {
+
+ if ((info->DisplayType == MT_STV) || (info->DisplayType == MT_CTV)) {
+ RADEONInitTVRegisters (pScrn, &info->SavedReg, save, mode,
+ &info->pll, info);
+ }
+
if (!RADEONInitCrtcRegisters(pScrn, save, mode, info))
return FALSE;
dot_clock = mode->Clock/1000.0;
- if (dot_clock) {
+ if ((info->DisplayType == MT_STV) ||
+ (info->DisplayType == MT_CTV)) {
+ /* Don't do any thing here, it will be handled in
+ * InitTV function
+ */
+ } else if (dot_clock) {
RADEONInitPLLRegisters(info, save, &info->pll, dot_clock);
} else {
save->ppll_ref_div = info->SavedReg.ppll_ref_div;
@@ -8555,6 +9803,11 @@
}
}
+ if ((info->MergeType == MT_STV) || (info->MergeType == MT_CTV)) {
+ if (!RADEONGetTVInfo (pScrn))
+ info->MergedFB = FALSE;
+ }
+
/* Do some MergedFB mode initialisation */
if(info->MergedFB) {
info->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
Index: radeon_reg.h
===================================================================
RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h,v
retrieving revision 1.15
diff -u -r1.15 radeon_reg.h
--- radeon_reg.h 26 Jan 2005 18:23:41 -0000 1.15
+++ radeon_reg.h 9 Apr 2005 14:45:12 -0000
@@ -418,6 +418,7 @@
# define RADEON_DAC_CMP_EN (1 << 3)
# define RADEON_DAC_CMP_OUTPUT (1 << 7)
# define RADEON_DAC_8BIT_EN (1 << 8)
+# define RADEON_DAC_TVO_EN (1 << 10)
# define RADEON_DAC_VGA_ADR_EN (1 << 13)
# define RADEON_DAC_PDWN (1 << 15)
# define RADEON_DAC_MASK_ALL (0xff << 24)
@@ -436,8 +437,14 @@
# define RADEON_DAC_PDWN_G (1 << 17)
# define RADEON_DAC_PDWN_B (1 << 18)
#define RADEON_TV_DAC_CNTL 0x088c
-# define RADEON_TV_DAC_STD_MASK 0x0300
+# define RADEON_TV_DAC_BLANK (1 << 0)
+# define RADEON_TV_DAC_HOLD (1 << 1)
+# define RADEON_TV_DAC_PEDESTAL (1 << 2)
+# define RADEON_TV_MONITOR_DETECT_EN (1 << 4)
+# define RADEON_TV_DAC_CMPOUT (1 << 5)
# define RADEON_TV_DAC_BGSLEEP (1 << 6)
+# define RADEON_TV_DAC_STD_MASK 0x0300
+# define RADEON_TV_DAC_STD_NTSC (1 << 8)
# define RADEON_TV_DAC_RDACPD (1 << 24)
# define RADEON_TV_DAC_GDACPD (1 << 25)
# define RADEON_TV_DAC_BDACPD (1 << 26)
@@ -448,6 +455,12 @@
# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c
# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01
# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04
+# define RADEON_DISP_TV_SOURCE_CRTC (1 << 16) /* crtc1 or crtc2 */
+# define RADEON_DISP_TV_SOURCE_LTU (0 << 16) /* linear transform unit */
+#define RADEON_DISP_TV_OUT_CNTL 0x0d6c
+# define RADEON_DISP_TV_PATH_SRC_CRTC2 (1 << 16)
+# define RADEON_DISP_TV_PATH_SRC_CRTC1 (0 << 16)
+
#define RADEON_DAC_CRC_SIG 0x02cc
#define RADEON_DAC_DATA 0x03c9 /* VGA */
#define RADEON_DAC_MASK 0x03c6 /* VGA */
@@ -1372,6 +1385,9 @@
#define RADEON_VIPH_CH2_ABCNT 0x0c38
#define RADEON_VIPH_CH3_ABCNT 0x0c3c
#define RADEON_VIPH_CONTROL 0x0c40
+# define RADEON_VIP_BUSY 0
+# define RADEON_VIP_IDLE 1
+# define RADEON_VIP_RESET 2
#define RADEON_VIPH_DV_LAT 0x0c44
#define RADEON_VIPH_BM_CHUNK 0x0c48
#define RADEON_VIPH_DV_INT 0x0c4c
@@ -2897,16 +2913,76 @@
#define RADEON_SS_HORZ_GUARD_DISCARD_ADJ_ADDR 51
#define RADEON_SS_SHININESS 60
-#define RADEON_TV_MASTER_CNTL 0x0800
+#define RADEON_TV_MASTER_CNTL 0x0800
+# define RADEON_TV_ASYNC_RST (1 << 0)
+# define RADEON_CRT_ASYNC_RST (1 << 1)
+# define RADEON_RESTART_PHASE_FIX (1 << 3)
+# define RADEON_CRT_FIFO_CE_EN (1 << 9)
+# define RADEON_TV_FIFO_CE_EN (1 << 10)
# define RADEON_TVCLK_ALWAYS_ONb (1 << 30)
-#define RADEON_TV_DAC_CNTL 0x088c
-# define RADEON_TV_DAC_CMPOUT (1 << 5)
-#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888
-# define RADEON_Y_RED_EN (1 << 0)
-# define RADEON_C_GRN_EN (1 << 1)
-# define RADEON_CMP_BLU_EN (1 << 2)
-# define RADEON_RED_MX_FORCE_DAC_DATA (6 << 4)
-# define RADEON_GRN_MX_FORCE_DAC_DATA (6 << 8)
+#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888
+# define RADEON_Y_RED_EN (1 << 0)
+# define RADEON_C_GRN_EN (1 << 1)
+# define RADEON_CMP_BLU_EN (1 << 2)
+# define RADEON_DAC_DITHER_EN (1 << 3)
+# define RADEON_RED_MX_FORCE_DAC_DATA (6 << 4)
+# define RADEON_GRN_MX_FORCE_DAC_DATA (6 << 8)
# define RADEON_BLU_MX_FORCE_DAC_DATA (6 << 12)
# define RADEON_TV_FORCE_DAC_DATA_SHIFT 16
+#define RADEON_TV_RGB_CNTL 0x0804
+# define RADEON_SWITCH_TO_BLUE (1 << 4)
+# define RADEON_RGB_DITHER_EN (1 << 5)
+# define RADEON_RGB_SRC_SEL_MASK (3 << 8)
+# define RADEON_RGB_SRC_SEL_CRTC1 (0 << 8)
+# define RADEON_RGB_SRC_SEL_RMX (1 << 8)
+# define RADEON_RGB_SRC_SEL_CRTC2 (2 << 8)
+# define RADEON_RGB_CONVERT_BY_PASS (1 << 10)
+#define RADEON_TV_SYNC_CNTL 0x0808
+#define RADEON_TV_HTOTAL 0x080c
+#define RADEON_TV_HDISP 0x0810
+#define RADEON_TV_HSTART 0x0818
+#define RADEON_TV_HCOUNT 0x081C
+#define RADEON_TV_VTOTAL 0x0820
+#define RADEON_TV_VDISP 0x0824
+#define RADEON_TV_VCOUNT 0x0828
+#define RADEON_TV_FTOTAL 0x082c
+#define RADEON_TV_FCOUNT 0x0830
+#define RADEON_TV_FRESTART 0x0834
+#define RADEON_TV_HRESTART 0x0838
+#define RADEON_TV_VRESTART 0x083c
+#define RADEON_TV_HOST_READ_DATA 0x0840
+#define RADEON_TV_HOST_WRITE_DATA 0x0844
+#define RADEON_TV_HOST_RD_WT_CNTL 0x0848
+#define RADEON_TV_VSCALER_CNTL1 0x084c
+# define RADEON_RESTART_FIELD (1 << 29) /* restart on field 0 */
+# define RADEON_Y_DEL_W_SIG_SHIFT 26
+#define RADEON_TV_TIMING_CNTL 0x0850
+#define RADEON_TV_VSCALER_CNTL2 0x0854
+# define RADEON_DITHER_MODE (1 << 0)
+# define RADEON_Y_OUTPUT_DITHER_EN (1 << 1)
+# define RADEON_UV_OUTPUT_DITHER_EN (1 << 2)
+# define RADEON_UV_TO_BUF_DITHER_EN (1 << 3)
+#define RADEON_TV_Y_FALL_CNTL 0x0858
+# define RADEON_Y_FALL_PING_PONG (1 << 16)
+#define RADEON_TV_Y_RISE_CNTL 0x085c
+# define RADEON_Y_RISE_PING_PONG (1 << 16)
+#define RADEON_TV_Y_SAW_TOOTH_CNTL 0x0860
+#define RADEON_TV_UPSAMP_AND_GAIN_CNTL 0x0864
+#define RADEON_TV_GAIN_LIMIT_SETTINGS 0x0868
+#define RADEON_TV_LINEAR_GAIN_SETTINGS 0x086c
+#define RADEON_TV_MODULATOR_CNTL1 0x0870
+# define RADEON_ALT_PHASE_EN (1 << 6)
+# define RADEON_SYNC_TIP_LEVEL (1 << 7)
+#define RADEON_TV_MODULATOR_CNTL2 0x0874
+#define RADEON_TV_CRC_CNTL 0x0890
+#define RADEON_TV_UV_ADR 0x08ac
+#define RADEON_TV_PLL_FINE_CNTL 0x0020 /* PLL */
+#define RADEON_TV_PLL_CNTL 0x0021 /* PLL */
+# define RADEON_TV_SLIP_EN (1 << 23)
+# define RADEON_TV_DTO_EN (1 << 28)
+#define RADEON_TV_PLL_CNTL1 0x0022 /* PLL */
+# define RADEON_TVPLL_TEST_DIS (1 << 31)
+# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30)
+# define RADEON_TVPLL_SLEEP (1 << 3)
+# define RADEON_TVPLL_REFCLK_SEL (1 << 4)
#endif