xf86-video-ati: Branch 'randr-1.2' - 20 commits
Alex Deucher
agd5f at kemper.freedesktop.org
Sun Aug 5 01:03:24 PDT 2007
src/Makefile.am | 3
src/radeon.h | 64 ++++
src/radeon_bios.c | 273 ++++++++++++++++++
src/radeon_crtc.c | 27 +
src/radeon_display.c | 26 -
src/radeon_driver.c | 504 ++++++++++++++++++++++++++++++++-
src/radeon_modes.c | 15 +
src/radeon_output.c | 227 ++++++++-------
src/radeon_probe.h | 21 +
src/radeon_reg.h | 88 +++++
src/radeon_tv.c | 759 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/radeon_tv.h | 56 +++
12 files changed, 1914 insertions(+), 149 deletions(-)
New commits:
diff-tree d1abdad167aa24ac970c69422435df443c82ebd6 (from 0cca25d8d6a0cb0d29b68e6cd9c699d1390aede1)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Aug 5 03:45:02 2007 -0400
RADEON: fixes
- fix output ordering
- set tv-out to return un-connected for now in radeon_detect()
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index fe1d091..4556552 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -200,13 +200,13 @@ static Bool RADEONGetATOMConnectorInfoFr
/* DVI-I ports have 2 entries: one for analog, one for digital. combine them */
if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
- info->BiosConnector[0].TMDSType = info->BiosConnector[7].TMDSType;
- info->BiosConnector[7].valid = FALSE;
+ info->BiosConnector[7].DACType = info->BiosConnector[0].DACType;
+ info->BiosConnector[0].valid = FALSE;
}
if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
- info->BiosConnector[4].TMDSType = info->BiosConnector[3].TMDSType;
- info->BiosConnector[3].valid = FALSE;
+ info->BiosConnector[3].DACType = info->BiosConnector[4].DACType;
+ info->BiosConnector[4].valid = FALSE;
}
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 0cd1183..f65507a 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1038,9 +1038,11 @@ radeon_detect(xf86OutputPtr output)
/* assume tv is connected for now */
if (radeon_output->type == OUTPUT_STV) {
- radeon_output->MonType = MT_STV;
+ /*radeon_output->MonType = MT_STV;*/
+ radeon_output->MonType = MT_NONE;
} else if (radeon_output->type == OUTPUT_CTV) {
- radeon_output->MonType = MT_CTV;
+ /*radeon_output->MonType = MT_CTV;*/
+ radeon_output->MonType = MT_NONE;
} else {
radeon_output->MonType = MT_UNKNOWN;
RADEONConnectorFindMonitor(pScrn, output);
@@ -1851,17 +1853,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
if (num_dvi > 1) {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
num_dvi--;
} else {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
}
} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) {
if (num_vga > 1) {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
num_vga--;
} else {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
}
} else
output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
@@ -1869,17 +1871,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
(info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
if (num_dvi > 1) {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
num_dvi--;
} else {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
}
} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
if (num_vga > 1) {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
num_vga--;
} else {
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
}
} else
output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
diff-tree 0cca25d8d6a0cb0d29b68e6cd9c699d1390aede1 (from ba5496ae7973786802962bf649dd91c219531749)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Aug 5 03:19:24 2007 -0400
RADEON: Fix DVI-I support in ATOM bios connector table parsing
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index b79fea7..fe1d091 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -198,6 +198,18 @@ static Bool RADEONGetATOMConnectorInfoFr
return FALSE;
}
+ /* DVI-I ports have 2 entries: one for analog, one for digital. combine them */
+ if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
+ info->BiosConnector[0].TMDSType = info->BiosConnector[7].TMDSType;
+ info->BiosConnector[7].valid = FALSE;
+ }
+
+ if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
+ info->BiosConnector[4].TMDSType = info->BiosConnector[3].TMDSType;
+ info->BiosConnector[3].valid = FALSE;
+ }
+
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
if (info->BiosConnector[i].valid) {
diff-tree ba5496ae7973786802962bf649dd91c219531749 (from 2ec22783ddf4c522df9e5fd1b2003854486d7a2b)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Aug 5 02:27:32 2007 -0400
RADEON: refactor output init to handle multiple DVI or VGA
- refactor output init to handle multiple DVI or VGA with the new
bios table parsing
diff --git a/src/radeon_output.c b/src/radeon_output.c
index d0225aa..0cd1183 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1701,7 +1701,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
xf86OutputPtr output;
char *optstr;
int i = 0;
-
+ int num_vga = 0;
+ int num_dvi = 0;
/* We first get the information about all connectors from BIOS.
* This is how the card is phyiscally wired up.
@@ -1795,6 +1796,27 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
if (info->BiosConnector[i].valid) {
+ if (info->IsAtomBios) {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+ num_dvi++;
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
+ num_vga++;
+ }
+ } else {
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+ num_dvi++;
+ } else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
+ num_vga++;
+ }
+ }
+ }
+ }
+
+ for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
if (!radeon_output) {
return FALSE;
@@ -1825,39 +1847,40 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
}
RADEONSetOutputType(pScrn, radeon_output);
if (info->IsAtomBios) {
- if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
- (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
- (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_A_ATOM)) &&
- ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
- (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
- (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_A_ATOM))) {
- if (i > 0)
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+ if (num_dvi > 1) {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
- else
+ num_dvi--;
+ } else {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
- } else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) &&
- (info->BiosConnector[1].ConnectorType == CONNECTOR_VGA_ATOM)) {
- if (i > 0)
+ }
+ } else if (info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) {
+ if (num_vga > 1) {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
- else
+ num_vga--;
+ } else {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ }
} else
output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
} else {
- if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D) ||
- (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I)) &&
- ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D) ||
- (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I))) {
- if (i > 0)
+ if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+ (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+ if (num_dvi > 1) {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
- else
+ num_dvi--;
+ } else {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
- } else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) &&
- (info->BiosConnector[1].ConnectorType == CONNECTOR_CRT)) {
- if (i > 0)
+ }
+ } else if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
+ if (num_vga > 1) {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
- else
+ num_vga--;
+ } else {
output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+ }
} else
output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
}
diff-tree 2ec22783ddf4c522df9e5fd1b2003854486d7a2b (from cc8e1d95f1b90a259beea4e8cc4d7e29af660919)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Aug 5 01:39:35 2007 -0400
RADEON: attempt to do the right thing for standards other than PAL or NTSC
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index ec355e2..3c12dfd 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -203,7 +203,10 @@ static Bool RADEONInitTVRestarts(xf86Out
const TVModeConstants *constPtr;
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
@@ -211,7 +214,10 @@ static Bool RADEONInitTVRestarts(xf86Out
hTotal = constPtr->horTotal;
vTotal = constPtr->verTotal;
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
fTotal = NTSC_TV_VFTOTAL + 1;
else
fTotal = PAL_TV_VFTOTAL + 1;
@@ -219,7 +225,9 @@ static Bool RADEONInitTVRestarts(xf86Out
/* Adjust positions 1&2 in hor. code timing table */
hOffset = radeon_output->hPos * H_POS_UNIT;
- if (radeon_output->tvStd == TV_STD_NTSC) {
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M) {
p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
} else {
@@ -247,7 +255,10 @@ static Bool RADEONInitTVRestarts(xf86Out
* Convert vPos TV lines to n. of CRTC pixels
* Be verrrrry careful when mixing signed & unsigned values in C..
*/
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M||
+ radeon_output->tvStd == TV_STD_PAL_60)
vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
else
vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
@@ -267,7 +278,10 @@ static Bool RADEONInitTVRestarts(xf86Out
save->tv_frestart , save->tv_vrestart , save->tv_hrestart);
/* Compute H_INC from hSize */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
(radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
else
@@ -298,7 +312,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
@@ -330,16 +347,18 @@ void RADEONInitTVRegisters(xf86OutputPtr
| (0x3b << RADEON_BLANK_LEVEL_SHIFT)
| (0x6 << RADEON_CY_FILT_BLEND_SHIFT);
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60 ||
+ radeon_output->tvStd == TV_STD_SCART_PAL) {
save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT);
- else
+ save->tv_modulator_cntl2 = 0x00000191;
+ } else {
save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
| (0x3b << RADEON_SET_UP_LEVEL_SHIFT);
-
- if (radeon_output->tvStd == TV_STD_NTSC)
- save->tv_modulator_cntl2 = 0x00000191;
- else
save->tv_modulator_cntl2 = 0x003e01b2;
+ }
save->pll_test_cntl = 0;
@@ -364,7 +383,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
save->tv_sync_size = constPtr->horResolution + 8;
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
else
vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
@@ -378,7 +400,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
else
save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
flicker_removal =
(float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
else
@@ -416,12 +441,16 @@ void RADEONInitTVRegisters(xf86OutputPtr
save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
else
save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
#if 0
+ /* needs fixes for r4xx */
save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
| RADEON_TV_DAC_BDACPD);
@@ -435,7 +464,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
}
#endif
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
(((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
@@ -454,18 +486,30 @@ void RADEONInitTVRegisters(xf86OutputPtr
save->tv_vdisp = constPtr->verResolution - 1;
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
save->tv_ftotal = NTSC_TV_VFTOTAL;
else
save->tv_ftotal = PAL_TV_VFTOTAL;
save->tv_vtotal = constPtr->verTotal - 1;
- if (radeon_output->tvStd == TV_STD_NTSC) {
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M) {
hor_timing = hor_timing_NTSC;
- vert_timing = vert_timing_NTSC;
} else {
hor_timing = hor_timing_PAL;
+ }
+
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60) {
+ vert_timing = vert_timing_NTSC;
+ } else {
vert_timing = vert_timing_PAL;
}
@@ -546,7 +590,10 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
RADEONOutputPrivatePtr radeon_output = output->driver_private;
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
@@ -576,7 +623,10 @@ void RADEONAdjustPLLRegistersForTV(ScrnI
RADEONOutputPrivatePtr radeon_output = output->driver_private;
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
@@ -627,7 +677,10 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
RADEONOutputPrivatePtr radeon_output = output->driver_private;
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
@@ -657,7 +710,10 @@ void RADEONAdjustPLL2RegistersForTV(Scrn
RADEONOutputPrivatePtr radeon_output = output->driver_private;
/* FIXME: need to revisit this when we add more modes */
- if (radeon_output->tvStd == TV_STD_NTSC)
+ if (radeon_output->tvStd == TV_STD_NTSC ||
+ radeon_output->tvStd == TV_STD_NTSC_J ||
+ radeon_output->tvStd == TV_STD_PAL_M ||
+ radeon_output->tvStd == TV_STD_PAL_60)
constPtr = &availableTVModes[0];
else
constPtr = &availableTVModes[1];
diff-tree cc8e1d95f1b90a259beea4e8cc4d7e29af660919 (from b61a49f2a5401560f85e11bcdd005287433cad12)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Aug 5 01:14:36 2007 -0400
RADEON: Major rework of BIOS table parsing
- greatly simplify ATOM and legacy connector table parsing
- use bios tables to detect LVDS and TV outputs
- add support for TV table parsing (legacy only)
diff --git a/src/radeon.h b/src/radeon.h
index 7792f31..432ee89 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -875,6 +875,7 @@ extern Bool RADEONGetConnectorInf
extern Bool RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
extern Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
extern Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output);
extern Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
extern void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 26019ba..b79fea7 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -141,6 +141,175 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn
return TRUE;
}
+static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int offset, i, tmp, tmp0, crtc, portinfo, gpio;
+
+ if (!info->VBIOS) return FALSE;
+
+ offset = RADEON_BIOS16(info->MasterDataStart + 22);
+
+ if (offset) {
+ tmp = RADEON_BIOS16(offset + 4);
+ for (i = 0; i < 8; i++) {
+ if (tmp & (1 << i)) {
+ info->BiosConnector[i].valid = TRUE;
+ portinfo = RADEON_BIOS16(offset + 6 + i * 2);
+ info->BiosConnector[i].DACType = (portinfo & 0xf) - 1;
+ info->BiosConnector[i].ConnectorType = (portinfo >> 4) & 0xf;
+ crtc = (portinfo >> 8) & 0xf;
+ tmp0 = RADEON_BIOS16(info->MasterDataStart + 24);
+ gpio = RADEON_BIOS16(tmp0 + 4 + 27 * crtc) * 4;
+ switch(gpio) {
+ case RADEON_GPIO_MONID:
+ info->BiosConnector[i].DDCType = DDC_MONID;
+ break;
+ case RADEON_GPIO_DVI_DDC:
+ info->BiosConnector[i].DDCType = DDC_DVI;
+ break;
+ case RADEON_GPIO_VGA_DDC:
+ info->BiosConnector[i].DDCType = DDC_VGA;
+ break;
+ case RADEON_GPIO_CRT2_DDC:
+ info->BiosConnector[i].DDCType = DDC_CRT2;
+ break;
+ case RADEON_LCD_GPIO_MASK:
+ info->BiosConnector[i].DDCType = DDC_LCD;
+ break;
+ default:
+ info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+ break;
+ }
+
+ if (i == 3)
+ info->BiosConnector[i].TMDSType = TMDS_INT;
+ else if (i == 7)
+ info->BiosConnector[i].TMDSType = TMDS_EXT;
+ else
+ info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+
+ } else {
+ info->BiosConnector[i].valid = FALSE;
+ }
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
+ return FALSE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+ info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+ }
+ }
+
+ return TRUE;
+}
+
+static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+ int offset, i, entry, tmp, tmp0, tmp1;
+
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x50);
+ if (offset) {
+ for (i = 0; i < 4; i++) {
+ entry = offset + 2 + i*2;
+
+ if (!RADEON_BIOS16(entry)) {
+ break;
+ }
+ info->BiosConnector[i].valid = TRUE;
+ tmp = RADEON_BIOS16(entry);
+ info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf;
+ info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf;
+ info->BiosConnector[i].DACType = tmp & 0x3;
+ if (tmp & 0x10)
+ info->BiosConnector[i].TMDSType = TMDS_EXT;
+ else
+ info->BiosConnector[i].TMDSType = TMDS_INT;
+
+ }
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
+ return FALSE;
+ }
+
+ /* check LVDS table */
+ if (info->IsMobility) {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
+ if (offset) {
+ info->BiosConnector[4].valid = TRUE;
+ info->BiosConnector[4].ConnectorType = CONNECTOR_PROPRIETARY;
+ info->BiosConnector[4].DACType = DAC_NONE;
+ info->BiosConnector[4].TMDSType = TMDS_NONE;
+
+ tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
+ if (tmp) {
+ tmp0 = RADEON_BIOS16(tmp + 0x15);
+ if (tmp0) {
+ tmp1 = RADEON_BIOS8(tmp0+2) & 0x07;
+ if (tmp1) {
+ info->BiosConnector[4].DDCType = tmp1;
+ if (info->BiosConnector[4].DDCType > DDC_LCD) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unknown DDCType %d found\n",
+ info->BiosConnector[4].DDCType);
+ info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
+ }
+ }
+ } else {
+ info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+ }
+ }
+ }
+
+ /* check TV table */
+ if (info->InternalTVOut) {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+ if (offset) {
+ if (RADEON_BIOS8(offset + 6) == 'T') {
+ info->BiosConnector[5].valid = TRUE;
+ /* assume s-video for now */
+ info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
+ info->BiosConnector[5].DACType = DAC_TVDAC;
+ info->BiosConnector[5].TMDSType = TMDS_NONE;
+ info->BiosConnector[5].DDCType = DDC_NONE_DETECTED;
+ }
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+ for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ if (info->BiosConnector[i].valid) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+ i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+ info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+ }
+ }
+
+ return TRUE;
+}
+
+Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR (pScrn);
+
+ if(!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios)
+ return RADEONGetATOMConnectorInfoFromBIOS(pScrn);
+ else
+ return RADEONGetLegacyConnectorInfoFromBIOS(pScrn);
+}
+
+#if 0
Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR (pScrn);
@@ -350,6 +519,98 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
}
return TRUE;
}
+#endif
+
+Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int offset, refclk, stds;
+
+ if (!info->VBIOS) return FALSE;
+
+ if (info->IsAtomBios) {
+ /* no idea where TV table is on ATOM bios */
+ return FALSE;
+ } else {
+ offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+ if (offset) {
+ if (RADEON_BIOS8(offset + 6) == 'T') {
+ switch (RADEON_BIOS8(offset + 7) & 0xf) {
+ case 1:
+ radeon_output->tvStd = TV_STD_NTSC;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
+ break;
+ case 2:
+ radeon_output->tvStd = TV_STD_PAL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
+ break;
+ case 3:
+ radeon_output->tvStd = TV_STD_PAL_M;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
+ break;
+ case 4:
+ radeon_output->tvStd = TV_STD_PAL_60;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
+ break;
+ case 5:
+ radeon_output->tvStd = TV_STD_NTSC_J;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
+ break;
+ case 6:
+ radeon_output->tvStd = TV_STD_SCART_PAL;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
+ break;
+ default:
+ radeon_output->tvStd = TV_STD_NTSC;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
+ break;
+ }
+
+ refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
+ if (refclk == 0)
+ radeon_output->TVRefClk = 29.498928713; /* MHz */
+ else if (refclk == 1)
+ radeon_output->TVRefClk = 28.636360000;
+ else if (refclk == 2)
+ radeon_output->TVRefClk = 14.318180000;
+ else if (refclk == 3)
+ radeon_output->TVRefClk = 27.000000000;
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
+ stds = RADEON_BIOS8(offset + 10) & 0x1f;
+ if (stds & TV_STD_NTSC) {
+ radeon_output->SupportedTVStds |= TV_STD_NTSC;
+ ErrorF("NTSC ");
+ }
+ if (stds & TV_STD_PAL) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL;
+ ErrorF("PAL ");
+ }
+ if (stds & TV_STD_PAL_M) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+ ErrorF("PAL-M ");
+ }
+ if (stds & TV_STD_PAL_60) {
+ radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+ ErrorF("PAL-60 ");
+ }
+ if (stds & TV_STD_NTSC_J) {
+ radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+ ErrorF("NTSC-J ");
+ }
+ if (stds & TV_STD_SCART_PAL) {
+ radeon_output->SupportedTVStds |= TV_STD_SCART_PAL;
+ ErrorF("SCART-PAL");
+ }
+ ErrorF("\n");
+
+ return TRUE;
+ } else
+ return FALSE;
+ }
+ }
+}
/* Read PLL parameters from BIOS block. Default to typical values if there
is no BIOS. */
diff --git a/src/radeon_output.c b/src/radeon_output.c
index fa6fb4f..d0225aa 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -611,6 +611,7 @@ radeon_mode_valid(xf86OutputPtr output,
if (radeon_output->type == OUTPUT_STV ||
radeon_output->type == OUTPUT_CTV) {
+ /* FIXME: Update when more modes are added */
if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
return MODE_OK;
else
@@ -1630,6 +1631,27 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
}
}
+static void
+RADEONGetTVInfo(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+
+ radeon_output->hPos = 0;
+ radeon_output->vPos = 0;
+ radeon_output->hSize = 0;
+
+ if (RADEONGetTVInfoFromBIOS(output)) return;
+
+ /* set some reasonable defaults */
+ radeon_output->tvStd = TV_STD_NTSC;
+ radeon_output->TVRefClk = 27.000000000;
+ radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+
+}
+
void RADEONInitConnector(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
@@ -1657,12 +1679,11 @@ void RADEONInitConnector(xf86OutputPtr o
if (radeon_output->type == OUTPUT_DVI) {
RADEONGetTMDSInfo(output);
+ }
- // FIXME -- this should be done in detect or getmodes
- /*if (i == 0)
- RADEONGetHardCodedEDIDFromBIOS(output);*/
-
- /*RADEONUpdatePanelSize(output);*/
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ RADEONGetTVInfo(output);
}
if (radeon_output->DACType == DAC_TVDAC) {
@@ -1688,15 +1709,14 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
* If not, we may have problem -- need to use MonitorLayout option.
*/
for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+ info->BiosConnector[i].valid = FALSE;
info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
info->BiosConnector[i].DACType = DAC_UNKNOWN;
info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
}
- if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
- ((info->BiosConnector[0].DDCType == 0) &&
- (info->BiosConnector[1].DDCType == 0))) {
+ if (!RADEONGetConnectorInfoFromBIOS(pScrn)) {
if (info->IsMobility) {
/* Below is the most common setting, but may not be true */
#if defined(__powerpc__)
@@ -1712,6 +1732,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
info->BiosConnector[1].DACType = DAC_PRIMARY;
info->BiosConnector[1].TMDSType = TMDS_EXT;
info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+
} else {
/* Below is the most common setting, but may not be true */
info->BiosConnector[0].DDCType = DDC_DVI;
@@ -1725,6 +1746,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
}
+ if (info->InternalTVOut) {
+ info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
+ info->BiosConnector[2].DACType = DAC_TVDAC;
+ info->BiosConnector[2].TMDSType = TMDS_NONE;
+ info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+ }
+
/* Some cards have the DDC lines swapped and we have no way to
* detect it yet (Mac cards)
*/
@@ -1766,7 +1794,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
}
for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
- if (info->BiosConnector[i].ConnectorType != CONNECTOR_NONE) {
+ if (info->BiosConnector[i].valid) {
RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
if (!radeon_output) {
return FALSE;
@@ -1851,98 +1879,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
}
}
- /* if it's a mobility make sure we have a LVDS port */
- if (info->IsMobility) {
- if (info->IsAtomBios) {
- if (info->BiosConnector[0].ConnectorType != CONNECTOR_LVDS_ATOM &&
- info->BiosConnector[1].ConnectorType != CONNECTOR_LVDS_ATOM) {
- /* add LVDS port */
- RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
- if (!radeon_output) {
- return FALSE;
- }
- radeon_output->MonType = MT_UNKNOWN;
- radeon_output->DDCType = DDC_LCD;
- radeon_output->DACType = DAC_NONE;
- radeon_output->TMDSType = TMDS_NONE;
- radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
- RADEONSetOutputType(pScrn, radeon_output);
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
- if (!output) {
- return FALSE;
- }
- output->driver_private = radeon_output;
- output->possible_crtcs = 1;
- output->possible_clones = 0;
-
- RADEONInitConnector(output);
-
- }
- } else {
- if (info->BiosConnector[0].ConnectorType != CONNECTOR_PROPRIETARY &&
- info->BiosConnector[1].ConnectorType != CONNECTOR_PROPRIETARY) {
- /* add LVDS port */
- RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
- if (!radeon_output) {
- return FALSE;
- }
- radeon_output->MonType = MT_UNKNOWN;
- radeon_output->DDCType = DDC_LCD;
- radeon_output->DACType = DAC_NONE;
- radeon_output->TMDSType = TMDS_NONE;
- radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
- RADEONSetOutputType(pScrn, radeon_output);
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
- if (!output) {
- return FALSE;
- }
- output->driver_private = radeon_output;
- output->possible_crtcs = 1;
- output->possible_clones = 0;
-
- RADEONInitConnector(output);
- }
- }
- }
-
- /* add TV out */
-#if 0
- if (info->InternalTVOut) {
- /* need to check the bios tables to see if we really have tv out and what type we have */
- RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
- if (!radeon_output) {
- return FALSE;
- }
- /* hard code type for now */
- radeon_output->MonType = MT_STV;
- radeon_output->DDCType = DDC_NONE_DETECTED;
- radeon_output->DACType = DAC_TVDAC;
- radeon_output->TMDSType = TMDS_NONE;
-
- /* hard code type for now */
- if (info->IsAtomBios)
- radeon_output->ConnectorType = CONNECTOR_STV_ATOM;
- else
- radeon_output->ConnectorType = CONNECTOR_STV;
-
- radeon_output->tvStd = TV_STD_NTSC;
- radeon_output->hPos = 0;
- radeon_output->vPos = 0;
- radeon_output->hSize = 0;
-
- RADEONSetOutputType(pScrn, radeon_output);
- output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
- if (!output) {
- return FALSE;
- }
- output->driver_private = radeon_output;
- output->possible_crtcs = 1 | 2;
- output->possible_clones = 0;
-
- RADEONInitConnector(output);
- }
-#endif
-
return TRUE;
}
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index f0df341..27b78cc 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -140,13 +140,12 @@ typedef enum
/* standards */
typedef enum
{
- TV_STD_NTSC,
- TV_STD_PAL,
- TV_STD_PAL_M,
- TV_STD_PAL_60,
- TV_STD_NTSC_J,
- TV_STD_PAL_CN,
- TV_STD_PAL_N
+ TV_STD_NTSC = 1,
+ TV_STD_PAL = 2,
+ TV_STD_PAL_M = 4,
+ TV_STD_PAL_60 = 8,
+ TV_STD_NTSC_J = 16,
+ TV_STD_SCART_PAL = 32,
} TVStd;
typedef struct _RADEONCrtcPrivateRec {
@@ -167,6 +166,7 @@ typedef struct {
RADEONDacType DACType;
RADEONTmdsType TMDSType;
RADEONConnectorType ConnectorType;
+ Bool valid;
} RADEONBIOSConnector;
typedef struct _RADEONOutputPrivateRec {
@@ -201,10 +201,12 @@ typedef struct _RADEONOutputPrivateRec {
int hPos;
int vPos;
int hSize;
+ float TVRefClk;
+ int SupportedTVStds;
} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
#define RADEON_MAX_CRTC 2
-#define RADEON_MAX_BIOS_CONNECTOR 2
+#define RADEON_MAX_BIOS_CONNECTOR 8
typedef struct
{
diff-tree b61a49f2a5401560f85e11bcdd005287433cad12 (from 288fa627274cb399059262d4f8bd844fc220a042)
Author: Alex Deucher <alex at botch2.com>
Date: Fri Aug 3 19:27:59 2007 -0400
RADEON: Change indexing of TV constants table in preparation for standard re-work
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index b802234..ec355e2 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -202,7 +202,11 @@ static Bool RADEONInitTVRestarts(xf86Out
CARD16 hInc;
const TVModeConstants *constPtr;
- constPtr = &availableTVModes[radeon_output->tvStd];
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
hTotal = constPtr->horTotal;
vTotal = constPtr->verTotal;
@@ -292,7 +296,12 @@ void RADEONInitTVRegisters(xf86OutputPtr
const CARD16 *hor_timing;
const CARD16 *vert_timing;
- constPtr = &availableTVModes[radeon_output->tvStd];
+
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
save->tv_crc_cntl = 0;
@@ -536,7 +545,11 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
const TVModeConstants *constPtr;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- constPtr = &availableTVModes[radeon_output->tvStd];
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
@@ -562,7 +575,11 @@ void RADEONAdjustPLLRegistersForTV(ScrnI
const TVModeConstants *constPtr;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- constPtr = &availableTVModes[radeon_output->tvStd];
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN;
@@ -609,7 +626,11 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
const TVModeConstants *constPtr;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- constPtr = &availableTVModes[radeon_output->tvStd];
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
@@ -635,7 +656,11 @@ void RADEONAdjustPLL2RegistersForTV(Scrn
const TVModeConstants *constPtr;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
- constPtr = &availableTVModes[radeon_output->tvStd];
+ /* FIXME: need to revisit this when we add more modes */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ constPtr = &availableTVModes[0];
+ else
+ constPtr = &availableTVModes[1];
save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */
diff-tree 288fa627274cb399059262d4f8bd844fc220a042 (from b66a1bc7994b33d349c1519761e431959311c85f)
Author: Alex Deucher <alex at botch2.com>
Date: Thu Aug 2 02:37:16 2007 -0400
RADEON: avoid a divide by 0 and only save tv out regs if the chip has them
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a7f5831..c1f0c3c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4612,6 +4612,9 @@ static CARD8 RADEONComputePLLGain(CARD16
{
unsigned vcoFreq;
+ if (!ref_div)
+ return 1;
+
vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
/*
@@ -5417,6 +5420,8 @@ static void RADEONSavePalette(ScrnInfoPt
/* Save state that defines current video mode */
static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"RADEONSaveMode(%p)\n", save);
@@ -5428,7 +5433,8 @@ static void RADEONSaveMode(ScrnInfoPtr p
RADEONSaveDACRegisters(pScrn, save);
RADEONSaveCrtc2Registers(pScrn, save);
RADEONSavePLL2Registers(pScrn, save);
- RADEONSaveTVRegisters(pScrn, save);
+ if (info->InternalTVOut)
+ RADEONSaveTVRegisters(pScrn, save);
/*RADEONSavePalette(pScrn, save);*/
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff-tree b66a1bc7994b33d349c1519761e431959311c85f (from d86592c8d5ce45d81d8a726c263e870e94fbcf11)
Author: Alex Deucher <alex at botch2.com>
Date: Thu Aug 2 02:11:20 2007 -0400
RADEON: fix tv-out enable/disable
diff --git a/src/radeon_display.c b/src/radeon_display.c
index bca0ac1..da2b82f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -317,9 +317,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
RADEONOutputPrivatePtr radeon_output;
radeon_output = output->driver_private;
- ErrorF("enable montype: %d\n", radeon_output->MonType);
-
if (bEnable) {
+ ErrorF("enable montype: %d\n", radeon_output->MonType);
if (radeon_output->MonType == MT_CRT) {
if (radeon_output->DACType == DAC_PRIMARY) {
tmp = INREG(RADEON_CRTC_EXT_CNTL);
@@ -362,20 +361,11 @@ void RADEONEnableDisplay(xf86OutputPtr o
save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
} else if (radeon_output->MonType == MT_STV ||
radeon_output->MonType == MT_CTV) {
-#if 1
- /* TV_MASTER_CNTL ??? */
-
- /* XXX: FIXME: STV vs CTV and DACPD bits */
- tmp = INREG(RADEON_TV_DAC_CNTL);
- tmp |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
- tmp &= ~RADEON_TV_DAC_BGSLEEP;
- OUTREG(RADEON_TV_DAC_CNTL, tmp);
- save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
- save->tv_dac_cntl &= ~RADEON_TV_DAC_BGSLEEP;
-#endif
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
}
} else {
- if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) {
+ ErrorF("disable montype: %d\n", radeon_output->MonType);
+ if (radeon_output->MonType == MT_CRT) {
if (radeon_output->DACType == DAC_PRIMARY) {
tmp = INREG(RADEON_CRTC_EXT_CNTL);
tmp &= ~RADEON_CRTC_CRT_ON;
@@ -395,9 +385,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
}
}
RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
- }
-
- if (radeon_output->MonType == MT_DFP || radeon_output->MonType == NONE) {
+ } else if (radeon_output->MonType == MT_DFP) {
if (radeon_output->TMDSType == TMDS_INT) {
tmp = INREG(RADEON_FP_GEN_CNTL);
tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
@@ -409,10 +397,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
OUTREG(RADEON_FP2_GEN_CNTL, tmp);
save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
}
- }
-
- if (radeon_output->MonType == MT_LCD ||
- (radeon_output->MonType == NONE && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+ } else if (radeon_output->MonType == MT_LCD) {
unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
if (info->IsMobility || info->IsIGP) {
/* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -429,21 +414,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
if (info->IsMobility || info->IsIGP) {
OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
- }
-
- if (radeon_output->MonType == MT_STV ||
- radeon_output->MonType == MT_CTV) {
-#if 1
-
- /* TV_MASTER_CNTL ??? */
-
- tmp = INREG(RADEON_TV_DAC_CNTL);
- tmp &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
- tmp |= RADEON_TV_DAC_BGSLEEP;
- OUTREG(RADEON_TV_DAC_CNTL, tmp);
- save->tv_dac_cntl &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
- save->tv_dac_cntl |= RADEON_TV_DAC_BGSLEEP;
-#endif
+ } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
}
}
}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 64abf80..a7f5831 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4541,7 +4541,6 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
RADEONRestoreTVRestarts(pScrn, restore);
ErrorF("Restore Timing Tables\n");
-
RADEONRestoreTVTimingTables(pScrn, restore);
@@ -4554,12 +4553,9 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
- /*OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);*/
-
OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
- /* XXX: taken care of in EnableDisplay() */
OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
ErrorF("Leaving Restore TV\n");
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 38fbcd0..b802234 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -405,17 +405,14 @@ void RADEONInitTVRegisters(xf86OutputPtr
tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
save->tv_timing_cntl = tmp;
- /* XXX: taken care of in enabledisplay() */
- save->tv_dac_cntl = /*RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
- |*/ (8 << 16) | (6 << 20);
+ save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
if (radeon_output->tvStd == TV_STD_NTSC)
save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
else
save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
-#if 1
- /* XXX: taken care of in enabledisplay() */
+#if 0
save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
| RADEON_TV_DAC_BDACPD);
diff-tree d86592c8d5ce45d81d8a726c263e870e94fbcf11 (from 971feb34843225030fff05b3f9d3801534fbf2d4)
Author: Alex Deucher <alex at botch2.com>
Date: Thu Aug 2 00:50:51 2007 -0400
RADEON: add missing break
diff --git a/src/radeon_output.c b/src/radeon_output.c
index d3bb344..fa6fb4f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -997,6 +997,7 @@ radeon_mode_set(xf86OutputPtr output, Di
if (radeon_crtc->crtc_id == 0)
RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
+ break;
case MT_DFP:
if (radeon_crtc->crtc_id == 0)
RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
diff-tree 971feb34843225030fff05b3f9d3801534fbf2d4 (from 98d7e00437bea78e03180eb30ff30de3455d9d1a)
Author: Alex Deucher <alex at botch2.com>
Date: Thu Aug 2 00:50:04 2007 -0400
RADEON: move tv dac enable to enabledisplay()
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 059dfca..bca0ac1 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -362,18 +362,16 @@ void RADEONEnableDisplay(xf86OutputPtr o
save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
} else if (radeon_output->MonType == MT_STV ||
radeon_output->MonType == MT_CTV) {
-#if 0
+#if 1
/* TV_MASTER_CNTL ??? */
/* XXX: FIXME: STV vs CTV and DACPD bits */
tmp = INREG(RADEON_TV_DAC_CNTL);
- tmp |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
- tmp &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
- | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ tmp |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+ tmp &= ~RADEON_TV_DAC_BGSLEEP;
OUTREG(RADEON_TV_DAC_CNTL, tmp);
- save->tv_dac_cntl |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
- save->tv_dac_cntl &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
- | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+ save->tv_dac_cntl &= ~RADEON_TV_DAC_BGSLEEP;
#endif
}
} else {
@@ -435,15 +433,16 @@ void RADEONEnableDisplay(xf86OutputPtr o
if (radeon_output->MonType == MT_STV ||
radeon_output->MonType == MT_CTV) {
+#if 1
/* TV_MASTER_CNTL ??? */
-#if 0
+
tmp = INREG(RADEON_TV_DAC_CNTL);
- tmp &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
- tmp |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ tmp &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+ tmp |= RADEON_TV_DAC_BGSLEEP;
OUTREG(RADEON_TV_DAC_CNTL, tmp);
- save->tv_dac_cntl &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
- save->tv_dac_cntl |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ save->tv_dac_cntl &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+ save->tv_dac_cntl |= RADEON_TV_DAC_BGSLEEP;
#endif
}
}
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index e4e6763..38fbcd0 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -406,8 +406,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
save->tv_timing_cntl = tmp;
/* XXX: taken care of in enabledisplay() */
- save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
- | (8 << 16) | (6 << 20);
+ save->tv_dac_cntl = /*RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
+ |*/ (8 << 16) | (6 << 20);
if (radeon_output->tvStd == TV_STD_NTSC)
save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
diff-tree 98d7e00437bea78e03180eb30ff30de3455d9d1a (from 5c549c1d42f7bbc556942af13aff2661fae856f2)
Author: Alex Deucher <alex at botch2.com>
Date: Thu Aug 2 00:20:50 2007 -0400
RADEON: limit tv modes to the only one we can program at the moment
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2790ddf..d3bb344 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -609,6 +609,14 @@ radeon_mode_valid(xf86OutputPtr output,
{
RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ if (radeon_output->type == OUTPUT_STV ||
+ radeon_output->type == OUTPUT_CTV) {
+ if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
+ return MODE_OK;
+ else
+ return MODE_CLOCK_RANGE;
+ }
+
if (radeon_output->type != OUTPUT_LVDS)
return MODE_OK;
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 001d013..e4e6763 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -141,7 +141,7 @@ static const CARD16 vert_timing_PAL[] =
**********************************************************************/
static const TVModeConstants availableTVModes[] =
{
- {
+ {
800, /* horResolution */
600, /* verResolution */
TV_STD_NTSC, /* standard */
@@ -156,7 +156,7 @@ static const TVModeConstants availableTV
4, /* crtcPLL_postDiv */
1022, /* pixToTV */
},
- {
+ {
800, /* horResolution */
600, /* verResolution */
TV_STD_PAL, /* standard */
diff-tree 5c549c1d42f7bbc556942af13aff2661fae856f2 (from b03978028fd975eb6946503d3a56a49c5a67f339)
Author: Alex Deucher <alex at botch2.com>
Date: Wed Aug 1 23:45:07 2007 -0400
RADEON: remove unused elements
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index b700b1e..001d013 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -46,11 +46,8 @@ typedef struct
unsigned defRestart;
CARD16 crtcPLL_N;
CARD8 crtcPLL_M;
- Bool crtcPLL_divBy2;
- CARD8 crtcPLL_byteClkDiv;
CARD8 crtcPLL_postDiv;
unsigned pixToTV;
- CARD8 byteClkDelay;
} TVModeConstants;
static const CARD16 hor_timing_NTSC[] =
@@ -156,11 +153,8 @@ static const TVModeConstants availableTV
625592, /* defRestart */
592, /* crtcPLL_N */
91, /* crtcPLL_M */
- TRUE, /* crtcPLL_divBy2 */
- 0, /* crtcPLL_byteClkDiv */
4, /* crtcPLL_postDiv */
1022, /* pixToTV */
- 1, /* byteClkDelay */
},
{
800, /* horResolution */
@@ -174,11 +168,8 @@ static const TVModeConstants availableTV
696700, /* defRestart */
1382, /* crtcPLL_N */
231, /* crtcPLL_M */
- TRUE, /* crtcPLL_divBy2 */
- 0, /* crtcPLL_byteClkDiv */
4, /* crtcPLL_postDiv */
759, /* pixToTV */
- 1, /* byteClkDelay */
}
};
diff-tree b03978028fd975eb6946503d3a56a49c5a67f339 (from cf54222f1fa37366b2c2b39c82f8afc02f32e63c)
Author: Alex Deucher <alex at botch2.com>
Date: Wed Aug 1 22:39:16 2007 -0400
RADEON: convert hard coded tv out values to calculations
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7c5bef4..64abf80 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4311,7 +4311,7 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
break;
i++;
}
- while (i < 100000);
+ while (i < 10000);
/*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
@@ -4334,7 +4334,7 @@ static CARD32 RADEONReadTVFIFO(ScrnInfoP
break;
i++;
}
- while (i < 100000);
+ while (i < 10000);
/*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
@@ -4353,15 +4353,12 @@ static CARD16 RADEONGetHTimingTablesAddr
case 0:
hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
break;
-
case 1:
hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
break;
-
case 2:
hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
break;
-
default:
/* Of course, this should never happen */
hTable = 0;
@@ -4378,15 +4375,12 @@ static CARD16 RADEONGetVTimingTablesAddr
case 0:
vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
break;
-
case 1:
vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
break;
-
case 2:
vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
break;
-
default:
/* Of course, this should never happen */
vTable = 0;
@@ -5359,7 +5353,7 @@ static void RADEONSaveTVRegisters(ScrnIn
ErrorF("Save TV timing tables\n");
- RADEONSaveTimingTables(pScrn, save);
+ RADEONSaveTVTimingTables(pScrn, save);
ErrorF("TV Save done\n");
}
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 2a9daf3..b700b1e 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -44,25 +44,16 @@ typedef struct
CARD16 horSyncStart;
CARD16 verSyncStart;
unsigned defRestart;
- CARD32 vScalerCntl1;
- CARD32 yRiseCntl;
- CARD32 ySawtoothCntl;
CARD16 crtcPLL_N;
CARD8 crtcPLL_M;
Bool crtcPLL_divBy2;
CARD8 crtcPLL_byteClkDiv;
CARD8 crtcPLL_postDiv;
- Bool use888RGB; /* False: RGB data is 565 packed (2 bytes/pixel) */
- /* True : RGB data is 888 packed (3 bytes/pixel) */
unsigned pixToTV;
CARD8 byteClkDelay;
- CARD32 tvoDataDelayA;
- CARD32 tvoDataDelayB;
- const CARD16 *horTimingTable;
- const CARD16 *verTimingTable;
} TVModeConstants;
-static const CARD16 horTimingNTSC_BIOS[] =
+static const CARD16 hor_timing_NTSC[] =
{
0x0007,
0x003f,
@@ -84,7 +75,7 @@ static const CARD16 horTimingNTSC_BIOS[]
0
};
-static const CARD16 verTimingNTSC_BIOS[] =
+static const CARD16 vert_timing_NTSC[] =
{
0x2001,
0x200d,
@@ -102,7 +93,7 @@ static const CARD16 verTimingNTSC_BIOS[]
0
};
-static const CARD16 horTimingPAL_BIOS[] =
+static const CARD16 hor_timing_PAL[] =
{
0x0007,
0x0058,
@@ -124,7 +115,7 @@ static const CARD16 horTimingPAL_BIOS[]
0
};
-static const CARD16 verTimingPAL_BIOS[] =
+static const CARD16 vert_timing_PAL[] =
{
0x2001,
0x200c,
@@ -163,21 +154,13 @@ static const TVModeConstants availableTV
824, /* horSyncStart */
632, /* verSyncStart */
625592, /* defRestart */
- 0x0900b46b, /* vScalerCntl1 */
- 0x00012c00, /* yRiseCntl */
- 0x10002d1a, /* ySawtoothCntl */
592, /* crtcPLL_N */
91, /* crtcPLL_M */
TRUE, /* crtcPLL_divBy2 */
0, /* crtcPLL_byteClkDiv */
4, /* crtcPLL_postDiv */
- FALSE, /* use888RGB */
1022, /* pixToTV */
1, /* byteClkDelay */
- 0x0a0b0907, /* tvoDataDelayA */
- 0x060a090a, /* tvoDataDelayB */
- horTimingNTSC_BIOS, /* horTimingTable */
- verTimingNTSC_BIOS /* verTimingTable */
},
{
800, /* horResolution */
@@ -189,26 +172,23 @@ static const TVModeConstants availableTV
824, /* horSyncStart */
669, /* verSyncStart */
696700, /* defRestart */
- 0x09009097, /* vScalerCntl1 */
- 0x000007da, /* yRiseCntl */
- 0x10002426, /* ySawtoothCntl */
1382, /* crtcPLL_N */
231, /* crtcPLL_M */
TRUE, /* crtcPLL_divBy2 */
0, /* crtcPLL_byteClkDiv */
4, /* crtcPLL_postDiv */
- FALSE, /* use888RGB */
759, /* pixToTV */
1, /* byteClkDelay */
- 0x0a0b0907, /* tvoDataDelayA */
- 0x060a090a, /* tvoDataDelayB */
- horTimingPAL_BIOS, /* horTimingTable */
- verTimingPAL_BIOS /* verTimingTable */
}
};
#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 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 };
+
/* Compute F,V,H restarts from default restart position and hPos & vPos
* Return TRUE when code timing table was changed
@@ -241,13 +221,17 @@ static Bool RADEONInitTVRestarts(xf86Out
else
fTotal = PAL_TV_VFTOTAL + 1;
- /*
- * Adjust positions 1&2 in hor. code timing table
- */
+ /* Adjust positions 1&2 in hor. code timing table */
hOffset = radeon_output->hPos * H_POS_UNIT;
- p1 = constPtr->horTimingTable[ H_TABLE_POS1 ];
- p2 = constPtr->horTimingTable[ H_TABLE_POS2 ];
+ if (radeon_output->tvStd == TV_STD_NTSC) {
+ p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
+ p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
+ } else {
+ p1 = hor_timing_PAL[ H_TABLE_POS1 ];
+ p2 = hor_timing_PAL[ H_TABLE_POS2 ];
+ }
+
p1 = (CARD16)((int)p1 + hOffset);
p2 = (CARD16)((int)p2 - hOffset);
@@ -311,8 +295,11 @@ void RADEONInitTVRegisters(xf86OutputPtr
RADEONOutputPrivatePtr radeon_output = output->driver_private;
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned i;
+ unsigned long vert_space, flicker_removal;
CARD32 tmp;
const TVModeConstants *constPtr;
+ const CARD16 *hor_timing;
+ const CARD16 *vert_timing;
constPtr = &availableTVModes[radeon_output->tvStd];
@@ -361,7 +348,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
| RADEON_CMP_BLU_EN
| RADEON_DAC_DITHER_EN);
- save->tv_rgb_cntl = 0x007b0004;
+ save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN | RADEON_TVOUT_SCALE_EN
+ | (0x0b << 16) | (0x07 << 20));
if (IsPrimary) {
if (radeon_output->Flags & RADEON_USE_RMX)
@@ -375,14 +363,59 @@ void RADEONInitTVRegisters(xf86OutputPtr
save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE;
save->tv_sync_size = constPtr->horResolution + 8;
-
- tmp = (constPtr->vScalerCntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
+ else
+ vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
+
+ save->tv_vscaler_cntl1 = RADEON_Y_W_EN;
+ save->tv_vscaler_cntl1 =
+ (save->tv_vscaler_cntl1 & 0xe3ff0000) | (vert_space * (1 << FRAC_BITS) / 10000);
+ save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+ if (constPtr->horResolution == 1024)
+ save->tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
+ else
+ save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ flicker_removal =
+ (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
+ else
+ flicker_removal =
+ (float) constPtr->verTotal * 2.0 / PAL_TV_LINES_PER_FRAME + 0.5;
+
+ if (flicker_removal < 3)
+ flicker_removal = 3;
+ for (i = 0; i < 6; ++i) {
+ if (flicker_removal == SLOPE_limit[i])
+ break;
+ }
+ save->tv_y_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_y_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_y_rise_cntl =
+ RADEON_Y_RISE_PING_PONG
+ | (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
+
+ save->tv_vscaler_cntl2 = ((save->tv_vscaler_cntl2 & 0x00fffff0)
+ | (0x10 << 24)
+ | RADEON_DITHER_MODE
+ | RADEON_Y_OUTPUT_DITHER_EN
+ | RADEON_UV_OUTPUT_DITHER_EN
+ | RADEON_UV_TO_BUF_DITHER_EN);
+
+ tmp = (save->tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
save->tv_timing_cntl = tmp;
+ /* XXX: taken care of in enabledisplay() */
save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
- | RADEON_TV_MONITOR_DETECT_EN
| (8 << 16) | (6 << 20);
if (radeon_output->tvStd == TV_STD_NTSC)
@@ -390,15 +423,16 @@ void RADEONInitTVRegisters(xf86OutputPtr
else
save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
-#if 0
+#if 1
+ /* XXX: taken care of in enabledisplay() */
save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
| RADEON_TV_DAC_BDACPD);
- if (MonType == MT_CTV) {
+ if (radeon_output->MonType == MT_CTV) {
save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD;
}
- if (MonType == MT_STV) {
+ if (radeon_output->MonType == MT_STV) {
save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
RADEON_TV_DAC_GDACPD);
}
@@ -428,26 +462,23 @@ void RADEONInitTVRegisters(xf86OutputPtr
else
save->tv_ftotal = PAL_TV_VFTOTAL;
- save->tv_vscaler_cntl1 = constPtr->vScalerCntl1;
- save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
-
- save->tv_vscaler_cntl2 = 0x10000000;
-
save->tv_vtotal = constPtr->verTotal - 1;
- save->tv_y_fall_cntl = RADEON_Y_FALL_PING_PONG | RADEON_Y_COEF_EN;
- save->tv_y_fall_cntl |= 0x80000400;
-
- save->tv_y_rise_cntl = constPtr->yRiseCntl;
- save->tv_y_saw_tooth_cntl = constPtr->ySawtoothCntl;
+ if (radeon_output->tvStd == TV_STD_NTSC) {
+ hor_timing = hor_timing_NTSC;
+ vert_timing = vert_timing_NTSC;
+ } else {
+ hor_timing = hor_timing_PAL;
+ vert_timing = vert_timing_PAL;
+ }
for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
- if ((save->h_code_timing[ i ] = constPtr->horTimingTable[ i ]) == 0)
+ if ((save->h_code_timing[ i ] = hor_timing[ i ]) == 0)
break;
}
for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
- if ((save->v_code_timing[ i ] = constPtr->verTimingTable[ i ]) == 0)
+ if ((save->v_code_timing[ i ] = vert_timing[ i ]) == 0)
break;
}
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
index 829efba..5c8c8c9 100644
--- a/src/radeon_tv.h
+++ b/src/radeon_tv.h
@@ -49,3 +49,8 @@
#define PAL_TV_LINES_PER_FRAME 625
#define PAL_TV_ZERO_H_SIZE 473200
#define PAL_TV_H_SIZE_UNIT 9360
+
+
+#define VERT_LEAD_IN_LINES 2
+#define FRAC_BITS 0xe
+#define FRAC_MASK 0x3fff
diff-tree cf54222f1fa37366b2c2b39c82f8afc02f32e63c (from 22d460d3ad991223aa1fbd7e5edeb45e36c65dc0)
Author: Alex Deucher <alex at botch2.com>
Date: Tue Jul 31 02:01:49 2007 -0400
RADEON: more fixes...
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 20d43ff..7c5bef4 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4409,14 +4409,14 @@ static void RADEONRestoreTVTimingTables(
hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
- /* OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
| RADEON_CRT_ASYNC_RST
| RADEON_RESTART_PHASE_FIX
| RADEON_CRT_FIFO_CE_EN
| RADEON_TV_FIFO_CE_EN
- | RADEON_TV_ON));*/
+ | RADEON_TV_ON));
- OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
+ /*OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);*/
for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
@@ -4509,20 +4509,6 @@ static void RADEONRestoreTVOutputStd(Scr
OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
}
-/* Test if tv output would be enabled with a given value in TV_DAC_CNTL */
-static Bool RADEONTVIsOn(CARD32 tv_dac_cntl)
-{
- /* XXX: Fixme for STV vs. CTV */
- if (tv_dac_cntl & RADEON_TV_DAC_BGSLEEP)
- return FALSE;
- else if ((tv_dac_cntl &
- (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD)) ==
- (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD))
- return FALSE;
- else
- return TRUE;
-}
-
/* Restore TV out regs */
void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
@@ -4562,9 +4548,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
ErrorF("Restore Timing Tables\n");
- /* Timing tables are only restored when tv output is active */
- if (RADEONTVIsOn(restore->tv_dac_cntl))
- RADEONRestoreTVTimingTables(pScrn, restore);
+ RADEONRestoreTVTimingTables(pScrn, restore);
OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
@@ -5304,7 +5288,15 @@ static void RADEONSaveTVTimingTables(Scr
/*
* Reset FIFO arbiter in order to be able to access FIFO RAM
*/
- OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON));
+
+ /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
ErrorF("saveTimingTables: reading timing tables\n");
@@ -5364,14 +5356,10 @@ static void RADEONSaveTVRegisters(ScrnIn
save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
-
- /*
- * Read H/V code timing tables (current tables only are saved)
- * This step is skipped when tv output is disabled in current RT state
- * (see RADEONRestoreTVRegisters)
- */
- if (RADEONTVIsOn(save->tv_dac_cntl))
- RADEONSaveTimingTables(pScrn, save);
+
+ ErrorF("Save TV timing tables\n");
+
+ RADEONSaveTimingTables(pScrn, save);
ErrorF("TV Save done\n");
}
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index a0e680b..2a9daf3 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -456,8 +456,6 @@ void RADEONInitTVRegisters(xf86OutputPtr
*/
RADEONInitTVRestarts(output, save, mode);
- /*save->hw_debug = 0x00000200;*/
-
save->dac_cntl &= ~RADEON_DAC_TVO_EN;
if (IS_R300_VARIANT)
diff-tree 22d460d3ad991223aa1fbd7e5edeb45e36c65dc0 (from 4822a2b837334f408f962646ab5ea4f8b0335ac9)
Author: Alex Deucher <alex at botch2.com>
Date: Tue Jul 31 01:28:05 2007 -0400
RADEON: fix name of tv output
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 9c11bf6..2790ddf 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1297,9 +1297,9 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
case CONNECTOR_DVI_D:
output = OUTPUT_DVI; break;
case CONNECTOR_CTV:
- output = OUTPUT_STV; break;
- case CONNECTOR_STV:
output = OUTPUT_CTV; break;
+ case CONNECTOR_STV:
+ output = OUTPUT_STV; break;
case CONNECTOR_NONE:
case CONNECTOR_UNSUPPORTED:
default:
diff-tree 4822a2b837334f408f962646ab5ea4f8b0335ac9 (from fe494c9db2995bb8ce7a028ecf9626e0cb0cf506)
Author: Alex Deucher <alex at botch2.com>
Date: Tue Jul 31 01:18:40 2007 -0400
RADEON: tv-out fixes. works now. tested on rv350.
VT siwtch is busted, and xrandr doesn't play nice yet.
uncomment code in radeon_output.c to test.
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 74711ce..20d43ff 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4298,7 +4298,7 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 tmp;
-
+ int i = 0;
OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
@@ -4307,26 +4307,35 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
do {
tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+ break;
+ i++;
}
- while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);
+ while (i < 100000);
+ /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
}
-/* Read from RT FIFO RAM */
+/* Read from TV FIFO RAM */
static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
CARD32 tmp;
+ int i = 0;
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
do {
tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
- }
- while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);
+ if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+ break;
+ i++;
+ }
+ while (i < 100000);
+ /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
@@ -4400,12 +4409,14 @@ static void RADEONRestoreTVTimingTables(
hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
- OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ /* OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
| RADEON_CRT_ASYNC_RST
| RADEON_RESTART_PHASE_FIX
| RADEON_CRT_FIFO_CE_EN
| RADEON_TV_FIFO_CE_EN
- | RADEON_TV_ON));
+ | RADEON_TV_ON));*/
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
@@ -4416,7 +4427,7 @@ static void RADEONRestoreTVTimingTables(
for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
- RADEONWriteFIFO(pScrn, vTable, tmp);
+ RADEONWriteTVFIFO(pScrn, vTable, tmp);
if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
break;
}
@@ -4553,7 +4564,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
/* Timing tables are only restored when tv output is active */
if (RADEONTVIsOn(restore->tv_dac_cntl))
- RADEONRestoreTimingTables(pScrn, restore);
+ RADEONRestoreTVTimingTables(pScrn, restore);
OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
diff --git a/src/radeon_output.c b/src/radeon_output.c
index d0a12dd..9c11bf6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1025,9 +1025,16 @@ radeon_detect(xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- radeon_output->MonType = MT_UNKNOWN;
- RADEONConnectorFindMonitor(pScrn, output);
+
+ /* assume tv is connected for now */
+ if (radeon_output->type == OUTPUT_STV) {
+ radeon_output->MonType = MT_STV;
+ } else if (radeon_output->type == OUTPUT_CTV) {
+ radeon_output->MonType = MT_CTV;
+ } else {
+ radeon_output->MonType = MT_UNKNOWN;
+ RADEONConnectorFindMonitor(pScrn, output);
+ }
/* force montype based on output property */
if (radeon_output->type == OUTPUT_DVI) {
@@ -1888,6 +1895,45 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
}
}
}
+
+ /* add TV out */
+#if 0
+ if (info->InternalTVOut) {
+ /* need to check the bios tables to see if we really have tv out and what type we have */
+ RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+ if (!radeon_output) {
+ return FALSE;
+ }
+ /* hard code type for now */
+ radeon_output->MonType = MT_STV;
+ radeon_output->DDCType = DDC_NONE_DETECTED;
+ radeon_output->DACType = DAC_TVDAC;
+ radeon_output->TMDSType = TMDS_NONE;
+
+ /* hard code type for now */
+ if (info->IsAtomBios)
+ radeon_output->ConnectorType = CONNECTOR_STV_ATOM;
+ else
+ radeon_output->ConnectorType = CONNECTOR_STV;
+
+ radeon_output->tvStd = TV_STD_NTSC;
+ radeon_output->hPos = 0;
+ radeon_output->vPos = 0;
+ radeon_output->hSize = 0;
+
+ RADEONSetOutputType(pScrn, radeon_output);
+ output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+ if (!output) {
+ return FALSE;
+ }
+ output->driver_private = radeon_output;
+ output->possible_crtcs = 1 | 2;
+ output->possible_clones = 0;
+
+ RADEONInitConnector(output);
+ }
+#endif
+
return TRUE;
}
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 5acc4ff..a0e680b 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -333,7 +333,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
| RADEON_AUD_ASYNC_RST
| RADEON_DVS_ASYNC_RST
| RADEON_CRT_FIFO_CE_EN
- | RADEON_TV_FIFO_CE_EN);
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON);
save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
| RADEON_SYNC_TIP_LEVEL
diff-tree fe494c9db2995bb8ce7a028ecf9626e0cb0cf506 (from 6b9b7a7bdc290d07de9b226691ec8025af8db896)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Jul 29 15:26:34 2007 -0400
RADEON: add info about tv out code and authorship
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 1d0b2c6..5acc4ff 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -1,3 +1,7 @@
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi at lycos.com>
+ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
index 179b87b..829efba 100644
--- a/src/radeon_tv.h
+++ b/src/radeon_tv.h
@@ -1,4 +1,9 @@
/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi at lycos.com>
+ */
+
+/*
* Maximum length of horizontal/vertical code timing tables for state storage
*/
#define MAX_H_CODE_TIMING_LEN 32
diff-tree 6b9b7a7bdc290d07de9b226691ec8025af8db896 (from 8d043db1817d94edeb72ab208dfea60026715d48)
Author: Alex Deucher <alex at botch2.com>
Date: Sun Jul 29 15:23:14 2007 -0400
RADEON: Initial pass at integrated tv out support
Based on the GATOS tv-out support by Federico Ulivi <fulivi at lycos.com>
and information from ati with substantial rework by myself.
Code is not actually hooked up yet.
diff --git a/src/Makefile.am b/src/Makefile.am
index 24665a4..709b98c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,7 +80,7 @@ radeon_drv_la_SOURCES = \
radeon_accel.c radeon_cursor.c radeon_dga.c \
radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
- radeon_crtc.c radeon_output.c radeon_modes.c \
+ radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
@@ -181,6 +181,7 @@ EXTRA_DIST = \
radeon_sarea.h \
radeon_version.h \
radeon_video.h \
+ radeon_tv.h \
theatre200.h \
theatre_detect.h \
theatre.h \
diff --git a/src/radeon.h b/src/radeon.h
index 96c4632..7792f31 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -65,6 +65,8 @@
#include "xf86xv.h"
#include "radeon_probe.h"
+#include "radeon_tv.h"
+
/* DRI support */
#ifdef XF86DRI
#define _XF86DRI_SERVER_
@@ -300,12 +302,54 @@ typedef struct {
CARD32 palette[256];
CARD32 palette2[256];
- CARD32 tv_dac_cntl;
-
CARD32 rs480_unk_e30;
CARD32 rs480_unk_e34;
CARD32 rs480_unk_e38;
CARD32 rs480_unk_e3c;
+
+ /* TV out registers */
+ CARD32 tv_master_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_cntl1;
+ 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_cntl;
+ CARD32 tv_pll_fine_cntl;
+ 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_y_saw_tooth_cntl;
+ CARD32 tv_y_rise_cntl;
+ CARD32 tv_y_fall_cntl;
+ CARD32 tv_uv_adr;
+ CARD32 tv_upsamp_and_gain_cntl;
+ CARD32 tv_gain_limit_settings;
+ CARD32 tv_linear_gain_settings;
+ CARD32 tv_crc_cntl;
+ CARD32 tv_sync_cntl;
+ CARD32 gpiopad_a;
+ CARD32 pll_test_cntl;
+
+ CARD16 h_code_timing[MAX_H_CODE_TIMING_LEN];
+ CARD16 v_code_timing[MAX_V_CODE_TIMING_LEN];
+
} RADEONSaveRec, *RADEONSavePtr;
typedef struct {
@@ -752,6 +796,8 @@ typedef struct {
Bool crtc_on;
Bool crtc2_on;
+ Bool InternalTVOut;
+
Rotation rotation;
void (*PointerMoved)(int, int, int);
CreateScreenResourcesProcPtr CreateScreenResources;
@@ -903,6 +949,17 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, i
void
RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
+extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary);
+
#ifdef XF86DRI
#ifdef USE_XAA
extern void RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 3518c9c..cbb50d8 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -753,6 +753,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
ScrnInfoPtr pScrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ xf86OutputPtr output;
+ RADEONOutputPrivatePtr radeon_output;
RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONMonitorType montype = MT_NONE;
Bool tilingOld = info->tilingEnabled;
@@ -775,8 +777,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
}
for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ output = xf86_config->output[i];
+ radeon_output = output->driver_private;
if (output->crtc == crtc) {
montype = radeon_output->MonType;
@@ -816,7 +818,20 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
}
break;
}
-
+
+ if (montype == MT_STV || montype == MT_CTV) {
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ break;
+ case 1:
+ RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+ break;
+ }
+ }
+
ErrorF("restore memmap\n");
RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
ErrorF("restore common\n");
@@ -837,6 +852,10 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
break;
}
+ /* pixclks_cntl handles tv-out clock routing */
+ if (montype == MT_STV || montype == MT_CTV)
+ RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+
if (info->DispPriority)
RADEONInitDispBandwidth(pScrn);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 79fb352..059dfca 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -360,12 +360,27 @@ void RADEONEnableDisplay(xf86OutputPtr o
OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
- }
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+#if 0
+ /* TV_MASTER_CNTL ??? */
+
+ /* XXX: FIXME: STV vs CTV and DACPD bits */
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ tmp |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+ tmp &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
+ | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+ save->tv_dac_cntl |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+ save->tv_dac_cntl &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
+ | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+#endif
+ }
} else {
if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) {
if (radeon_output->DACType == DAC_PRIMARY) {
tmp = INREG(RADEON_CRTC_EXT_CNTL);
- tmp &= ~RADEON_CRTC_CRT_ON;
+ tmp &= ~RADEON_CRTC_CRT_ON;
OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
} else if (radeon_output->DACType == DAC_TVDAC) {
@@ -417,6 +432,20 @@ void RADEONEnableDisplay(xf86OutputPtr o
OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
}
}
+
+ if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+
+ /* TV_MASTER_CNTL ??? */
+#if 0
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ tmp &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+ tmp |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+ save->tv_dac_cntl &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+ save->tv_dac_cntl |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+#endif
+ }
}
}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e9a0954..74711ce 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -128,9 +128,9 @@ static void RADEONAdjustMemMapRegisters(
DisplayModePtr
RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-/* psuedo xinerama support */
-extern Bool RADEONnoPanoramiXExtension;
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+ unsigned nWaitLoops, unsigned cntThreshold);
static const OptionInfoRec RADEONOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
@@ -1497,6 +1497,7 @@ static Bool RADEONPreInitChipType(ScrnIn
info->IsIGP = FALSE;
info->IsDellServer = FALSE;
info->HasSingleDAC = FALSE;
+ info->InternalTVOut = TRUE;
switch (info->Chipset) {
case PCI_CHIP_RADEON_LY:
case PCI_CHIP_RADEON_LZ:
@@ -1556,6 +1557,7 @@ static Bool RADEONPreInitChipType(ScrnIn
case PCI_CHIP_R200_QL:
case PCI_CHIP_R200_QM:
info->ChipFamily = CHIP_FAMILY_R200;
+ info->InternalTVOut = FALSE;
break;
case PCI_CHIP_RADEON_LW:
@@ -1738,6 +1740,7 @@ static Bool RADEONPreInitChipType(ScrnIn
/* Original Radeon/7200 */
info->ChipFamily = CHIP_FAMILY_RADEON;
pRADEONEnt->HasCRTC2 = FALSE;
+ info->InternalTVOut = FALSE;
}
@@ -4101,6 +4104,9 @@ void RADEONRestoreDACRegisters(ScrnInfoP
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ if (IS_R300_VARIANT)
+ OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
+
OUTREGP(RADEON_DAC_CNTL,
restore->dac_cntl,
RADEON_DAC_RANGE_CNTL |
@@ -4108,14 +4114,14 @@ void RADEONRestoreDACRegisters(ScrnInfoP
OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
- //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
(info->ChipFamily != CHIP_FAMILY_R200))
OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+
if ((info->ChipFamily == CHIP_FAMILY_R200) ||
IS_R300_VARIANT) {
- OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
} else {
OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
@@ -4273,7 +4279,6 @@ void RADEONRestoreRMXRegisters(ScrnInfoP
void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
if (info->IsMobility) {
@@ -4286,6 +4291,291 @@ void RADEONRestoreLVDSRegisters(ScrnInfo
}
+/* Write to TV FIFO RAM */
+static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
+ CARD32 value)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+
+
+ OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ }
+ while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+/* Read from RT FIFO RAM */
+static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ }
+ while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+
+ return INREG(RADEON_TV_HOST_READ_DATA);
+}
+
+/* Get FIFO addresses of horizontal & vertical code timing tables from
+ * settings of uv_adr register.
+ */
+static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 hTable;
+
+ switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+ break;
+
+ case 1:
+ hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+ break;
+
+ case 2:
+ hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+ break;
+
+ default:
+ /* Of course, this should never happen */
+ hTable = 0;
+ break;
+ }
+ return hTable;
+}
+
+static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 vTable;
+
+ switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+ break;
+
+ case 1:
+ vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+ break;
+
+ case 2:
+ vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+ break;
+
+ default:
+ /* Of course, this should never happen */
+ vTable = 0;
+ break;
+ }
+ return vTable;
+}
+
+/* Restore horizontal/vertical timing code tables */
+static void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
+ hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON));
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
+ tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
+ RADEONWriteTVFIFO(pScrn, hTable, tmp);
+ if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
+ tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
+ RADEONWriteFIFO(pScrn, vTable, tmp);
+ if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* restore TV PLLs */
+static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+ OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 300, 160, 27);
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+}
+
+/* Restore TV horizontal/vertical settings */
+static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+ OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
+ OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
+ OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
+
+ OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
+ OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
+
+ OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+ OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
+ OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+
+ OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
+ OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
+ OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
+}
+
+/* restore TV RESTART registers */
+static void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
+ OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
+ OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
+}
+
+/* restore tv standard & output muxes */
+static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
+
+ OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+ OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+
+ OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
+}
+
+/* Test if tv output would be enabled with a given value in TV_DAC_CNTL */
+static Bool RADEONTVIsOn(CARD32 tv_dac_cntl)
+{
+ /* XXX: Fixme for STV vs. CTV */
+ if (tv_dac_cntl & RADEON_TV_DAC_BGSLEEP)
+ return FALSE;
+ else if ((tv_dac_cntl &
+ (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD)) ==
+ (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+/* Restore TV out regs */
+void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ ErrorF("Entering Restore TV\n");
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX
+ | RADEON_TV_FIFO_ASYNC_RST));
+
+ /* Temporarily turn the TV DAC off */
+ OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
+ | RADEON_TV_DAC_BGSLEEP
+ | RADEON_TV_DAC_RDACPD
+ | RADEON_TV_DAC_GDACPD
+ | RADEON_TV_DAC_BDACPD));
+
+ ErrorF("Restore TV PLL\n");
+ RADEONRestoreTVPLLRegisters(pScrn, restore);
+
+ ErrorF("Restore TVHV\n");
+ RADEONRestoreTVHVRegisters(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX));
+
+ ErrorF("Restore TV Restarts\n");
+ RADEONRestoreTVRestarts(pScrn, restore);
+
+ ErrorF("Restore Timing Tables\n");
+
+ /* Timing tables are only restored when tv output is active */
+ if (RADEONTVIsOn(restore->tv_dac_cntl))
+ RADEONRestoreTimingTables(pScrn, restore);
+
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX));
+
+ ErrorF("Restore TV standard\n");
+ RADEONRestoreTVOutputStd(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+ /*OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);*/
+
+ OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
+ OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
+
+ /* XXX: taken care of in EnableDisplay() */
+ OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+ ErrorF("Leaving Restore TV\n");
+}
+
static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
{
int i = 0;
@@ -4360,6 +4650,39 @@ static CARD8 RADEONComputePLLGain(CARD16
return 1;
}
+/* Wait for PLLs to lock */
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+ unsigned nWaitLoops, unsigned cntThreshold)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 savePLLTest;
+ unsigned i;
+ unsigned j;
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+
+ savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
+
+ /* XXX: these should probably be OUTPLL to avoid various PLL errata */
+
+ OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+
+ for (i = 0; i < nTests; i++) {
+ OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+
+ for (j = 0; j < nWaitLoops; j++)
+ if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
+ break;
+ }
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
/* Write PLL registers */
void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
RADEONSavePtr restore)
@@ -4733,6 +5056,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
/* Write out state to define a new video mode */
void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -4765,6 +5089,8 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
RADEONRestoreFP2Registers(pScrn, restore);
RADEONRestoreLVDSRegisters(pScrn, restore);
RADEONRestoreDACRegisters(pScrn, restore);
+ if (info->InternalTVOut)
+ RADEONRestoreTVRegisters(pScrn, restore);
#if 0
RADEONRestorePalette(pScrn, &info->SavedReg);
@@ -4884,6 +5210,8 @@ static void RADEONSaveDACRegisters(ScrnI
save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
save->disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
save->dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+ save->gpiopad_a = INREG(RADEON_GPIOPAD_A);
+
}
/* Read flat panel registers */
@@ -4948,6 +5276,95 @@ static void RADEONSaveCrtc2Registers(Scr
}
+/* Save horizontal/vertical timing code tables */
+static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
+ hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
+
+ /*
+ * Reset FIFO arbiter in order to be able to access FIFO RAM
+ */
+ OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);
+
+ ErrorF("saveTimingTables: reading timing tables\n");
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, hTable--);
+ save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff);
+ save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
+
+ if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, vTable++);
+ save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff);
+ save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
+
+ if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* read TV regs */
+static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ unsigned i;
+
+ ErrorF("Entering TV Save\n");
+
+ save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
+ save->tv_frestart = INREG(RADEON_TV_FRESTART);
+ save->tv_hrestart = INREG(RADEON_TV_HRESTART);
+ save->tv_vrestart = INREG(RADEON_TV_VRESTART);
+ save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
+ save->tv_hdisp = INREG(RADEON_TV_HDISP);
+ save->tv_hstart = INREG(RADEON_TV_HSTART);
+ save->tv_htotal = INREG(RADEON_TV_HTOTAL);
+ save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
+ save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+ save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
+ save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
+ save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
+ save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+ save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
+ save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
+ save->tv_vdisp = INREG(RADEON_TV_VDISP);
+ save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
+ save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
+ save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
+ save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
+ save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
+ save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
+ save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
+
+ save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+
+ /*
+ * Read H/V code timing tables (current tables only are saved)
+ * This step is skipped when tv output is disabled in current RT state
+ * (see RADEONRestoreTVRegisters)
+ */
+ if (RADEONTVIsOn(save->tv_dac_cntl))
+ RADEONSaveTimingTables(pScrn, save);
+
+ ErrorF("TV Save done\n");
+}
+
/* Read PLL registers */
static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
@@ -5016,12 +5433,13 @@ static void RADEONSaveMode(ScrnInfoPtr p
RADEONSaveMemMapRegisters(pScrn, save);
RADEONSaveCommonRegisters(pScrn, save);
- RADEONSavePLLRegisters (pScrn, save);
- RADEONSaveCrtcRegisters (pScrn, save);
- RADEONSaveFPRegisters (pScrn, save);
- RADEONSaveDACRegisters (pScrn, save);
- RADEONSaveCrtc2Registers (pScrn, save);
- RADEONSavePLL2Registers (pScrn, save);
+ RADEONSavePLLRegisters(pScrn, save);
+ RADEONSaveCrtcRegisters(pScrn, save);
+ RADEONSaveFPRegisters(pScrn, save);
+ RADEONSaveDACRegisters(pScrn, save);
+ RADEONSaveCrtc2Registers(pScrn, save);
+ RADEONSavePLL2Registers(pScrn, save);
+ RADEONSaveTVRegisters(pScrn, save);
/*RADEONSavePalette(pScrn, save);*/
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 66d8a7f..a5e1cc4 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -78,6 +78,17 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
}
+static DisplayModePtr RADEONTVModes(xf86OutputPtr output)
+{
+ DisplayModePtr new = NULL;
+
+ /* just a place holder */
+ new = xf86CVTMode(800, 600, 60.00, FALSE, FALSE);
+ new->type = M_T_DRIVER | M_T_PREFERRED;
+
+ return new;
+}
+
/* This is used only when no mode is specified for FP and no ddc is
* available. We force it to native mode, if possible.
*/
@@ -286,6 +297,10 @@ RADEONProbeOutputModes(xf86OutputPtr out
modes = xf86OutputGetEDIDModes (output);
return modes;
}
+ if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+ modes = RADEONTVModes(output);
+ return modes;
+ }
if (radeon_output->type == OUTPUT_LVDS) {
/* okay we got DDC info */
if (output->MonInfo) {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index e431bf5..d0a12dd 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -46,6 +46,7 @@
#include "radeon_macros.h"
#include "radeon_probe.h"
#include "radeon_version.h"
+#include "radeon_tv.h"
const char *MonTypeName[7] = {
@@ -890,7 +891,7 @@ RADEONInitTvDacCntl(ScrnInfoPtr pScrn, R
save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
RADEON_TV_DAC_NHOLD |
RADEON_TV_DAC_STD_PS2);
- // info->tv_dac_adj);
+
}
static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
@@ -902,6 +903,9 @@ static void RADEONInitDAC2Registers(xf86
/*0x0028023;*/
RADEONInitTvDacCntl(pScrn, save);
+ if (IS_R300_VARIANT)
+ save->gpiopad_a = info->SavedReg.gpiopad_a | 1;
+
if (IsPrimary) {
save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
if (IS_R300_VARIANT) {
@@ -961,6 +965,9 @@ RADEONInitOutputRegisters(ScrnInfoPtr pS
} else {
RADEONInitFP2Registers(output, save, mode, IsPrimary);
}
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+ RADEONInitTVRegisters(output, save, mode, IsPrimary);
}
}
@@ -993,6 +1000,12 @@ radeon_mode_set(xf86OutputPtr output, Di
RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
}
break;
+ case MT_STV:
+ case MT_CTV:
+ ErrorF("restore tv\n");
+ RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+ RADEONRestoreTVRegisters(pScrn, &info->ModeReg);
+ break;
default:
ErrorF("restore dac\n");
RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
@@ -1041,8 +1054,12 @@ radeon_detect(xf86OutputPtr output)
switch(radeon_output->MonType) {
case MT_LCD:
- case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break;
- default: output->subpixel_order = SubPixelNone; break;
+ case MT_DFP:
+ output->subpixel_order = SubPixelHorizontalRGB;
+ break;
+ default:
+ output->subpixel_order = SubPixelNone;
+ break;
}
return XF86OutputStatusConnected;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 0dceca9..f0df341 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -137,6 +137,18 @@ typedef enum
OUTPUT_CTV,
} RADEONOutputType;
+/* standards */
+typedef enum
+{
+ TV_STD_NTSC,
+ TV_STD_PAL,
+ TV_STD_PAL_M,
+ TV_STD_PAL_60,
+ TV_STD_NTSC_J,
+ TV_STD_PAL_CN,
+ TV_STD_PAL_N
+} TVStd;
+
typedef struct _RADEONCrtcPrivateRec {
#ifdef USE_XAA
FBLinearPtr rotate_mem_xaa;
@@ -184,6 +196,11 @@ typedef struct _RADEONOutputPrivateRec {
int PanelPwrDly;
int DotClock;
RADEONTMDSPll tmds_pll[4];
+ /* TV out */
+ TVStd tvStd;
+ int hPos;
+ int vPos;
+ int hSize;
} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
#define RADEON_MAX_CRTC 2
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 5fdda45..db2057a 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -467,6 +467,7 @@
# define RADEON_DAC_PDWN (1 << 15)
# define RADEON_DAC_MASK_ALL (0xff << 24)
#define RADEON_DAC_CNTL2 0x007c
+# define RADEON_DAC2_TV_CLK_SEL (0 << 1)
# define RADEON_DAC2_DAC_CLK_SEL (1 << 0)
# define RADEON_DAC2_DAC2_CLK_SEL (1 << 1)
# define RADEON_DAC2_PALETTE_ACC_CTL (1 << 5)
@@ -486,9 +487,11 @@
# 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_STD_MASK (3 << 8)
+# define RADEON_TV_DAC_STD_PAL (0 << 8)
# define RADEON_TV_DAC_STD_NTSC (1 << 8)
-# define RADEON_TV_DAC_STD_MASK 0x0300
-# define RADEON_TV_DAC_STD_PS2 0x0200
+# define RADEON_TV_DAC_STD_PS2 (2 << 8)
+# define RADEON_TV_DAC_STD_RS343 (3 << 8)
# define RADEON_TV_DAC_BGSLEEP (1 << 6)
# define RADEON_TV_DAC_BGADJ_MASK (0xf << 16)
# define RADEON_TV_DAC_DACADJ_MASK (0xf << 20)
@@ -507,9 +510,9 @@
# define RADEON_DISP_DAC2_SOURCE_MASK 0x0c
# define RADEON_DISP_DAC_SOURCE_CRTC2 0x01
# define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04
-# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03<<2)
+# define RADEON_DISP_TVDAC_SOURCE_MASK (0x03 << 2)
# define RADEON_DISP_TVDAC_SOURCE_CRTC 0x0
-# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01<<2)
+# define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2)
# 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
@@ -537,12 +540,12 @@
# define RADEON_DISP_ALPHA_MODE_KEY 0
# define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1
# define RADEON_DISP_ALPHA_MODE_GLOBAL 2
-# define RADEON_DISP_RGB_OFFSET_EN (1<<8)
+# define RADEON_DISP_RGB_OFFSET_EN (1 << 8)
# define RADEON_DISP_GRPH_ALPHA_MASK (0xff << 16)
# define RADEON_DISP_OV0_ALPHA_MASK (0xff << 24)
# define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9)
#define RADEON_DISP2_MERGE_CNTL 0x0d68
-# define RADEON_DISP2_RGB_OFFSET_EN (1<<8)
+# define RADEON_DISP2_RGB_OFFSET_EN (1 << 8)
#define RADEON_DISP_LIN_TRANS_GRPH_A 0x0d80
#define RADEON_DISP_LIN_TRANS_GRPH_B 0x0d84
#define RADEON_DISP_LIN_TRANS_GRPH_C 0x0d88
@@ -844,6 +847,7 @@
# define RADEON_HDP_SOFT_RESET (1 << 26)
# define RADEON_HDP_APER_CNTL (1 << 23)
#define RADEON_HTOTAL_CNTL 0x0009 /* PLL */
+# define RADEON_HTOT_CNTL_VGA_EN (1 << 28)
#define RADEON_HTOTAL2_CNTL 0x002e /* PLL */
/* Multimedia I2C bus */
@@ -1267,6 +1271,7 @@
# define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23)
#define RADEON_PLANE_3D_MASK_C 0x1d44
#define RADEON_PLL_TEST_CNTL 0x0013 /* PLL */
+# define RADEON_PLL_MASK_READ_B (1 << 9)
#define RADEON_PMI_CAP_ID 0x0f5c /* PCI */
#define RADEON_PMI_DATA 0x0f63 /* PCI */
#define RADEON_PMI_NXT_CAP_PTR 0x0f5d /* PCI */
@@ -3080,9 +3085,14 @@
# define RADEON_TV_ASYNC_RST (1 << 0)
# define RADEON_CRT_ASYNC_RST (1 << 1)
# define RADEON_RESTART_PHASE_FIX (1 << 3)
+# define RADEON_TV_FIFO_ASYNC_RST (1 << 4)
+# define RADEON_VIN_ASYNC_RST (1 << 5)
+# define RADEON_AUD_ASYNC_RST (1 << 6)
+# define RADEON_DVS_ASYNC_RST (1 << 7)
# 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_ON (1 << 31)
#define RADEON_TV_PRE_DAC_MUX_CNTL 0x0888
# define RADEON_Y_RED_EN (1 << 0)
# define RADEON_C_GRN_EN (1 << 1)
@@ -3100,7 +3110,14 @@
# 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_TVOUT_SCALE_EN (1 << 26)
#define RADEON_TV_SYNC_CNTL 0x0808
+# define RADEON_SYNC_OE (1 << 0)
+# define RADEON_SYNC_OUT (1 << 1)
+# define RADEON_SYNC_IN (1 << 2)
+# define RADEON_SYNC_PUB (1 << 3)
+# define RADEON_SYNC_PD (1 << 4)
+# define RADEON_TV_SYNC_IO_DRIVE (1 << 5)
#define RADEON_TV_HTOTAL 0x080c
#define RADEON_TV_HDISP 0x0810
#define RADEON_TV_HSTART 0x0818
@@ -3116,10 +3133,23 @@
#define RADEON_TV_HOST_READ_DATA 0x0840
#define RADEON_TV_HOST_WRITE_DATA 0x0844
#define RADEON_TV_HOST_RD_WT_CNTL 0x0848
+# define RADEON_HOST_FIFO_RD (1 << 12)
+# define RADEON_HOST_FIFO_RD_ACK (1 << 13)
+# define RADEON_HOST_FIFO_WT (1 << 14)
+# define RADEON_HOST_FIFO_WT_ACK (1 << 15)
#define RADEON_TV_VSCALER_CNTL1 0x084c
+# define RADEON_UV_INC_MASK 0xffff
+# define RADEON_UV_INC_SHIFT 0
+# define RADEON_Y_W_EN (1 << 24)
# 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_H_INC_MASK 0xfff
+# define RADEON_H_INC_SHIFT 0
+# define RADEON_REQ_Y_FIRST (1 << 19)
+# define RADEON_FORCE_BURST_ALWAYS (1 << 21)
+# define RADEON_UV_POST_SCALE_BYPASS (1 << 23)
+# define RADEON_UV_OUTPUT_POST_SCALE_SHIFT 24
#define RADEON_TV_VSCALER_CNTL2 0x0854
# define RADEON_DITHER_MODE (1 << 0)
# define RADEON_Y_OUTPUT_DITHER_EN (1 << 1)
@@ -3127,27 +3157,65 @@
# 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_Y_COEF_EN (1 << 17)
#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_YUPSAMP_EN (1 << 0)
+# define RADEON_UVUPSAMP_EN (1 << 2)
#define RADEON_TV_GAIN_LIMIT_SETTINGS 0x0868
+# define RADEON_Y_GAIN_LIMIT_SHIFT 0
+# define RADEON_UV_GAIN_LIMIT_SHIFT 16
#define RADEON_TV_LINEAR_GAIN_SETTINGS 0x086c
+# define RADEON_Y_GAIN_SHIFT 0
+# define RADEON_UV_GAIN_SHIFT 16
#define RADEON_TV_MODULATOR_CNTL1 0x0870
+# define RADEON_YFLT_EN (1 << 2)
+# define RADEON_UVFLT_EN (1 << 3)
# define RADEON_ALT_PHASE_EN (1 << 6)
# define RADEON_SYNC_TIP_LEVEL (1 << 7)
+# define RADEON_BLANK_LEVEL_SHIFT 8
+# define RADEON_SET_UP_LEVEL_SHIFT 16
+# define RADEON_SLEW_RATE_LIMIT (1 << 23)
+# define RADEON_CY_FILT_BLEND_SHIFT 28
#define RADEON_TV_MODULATOR_CNTL2 0x0874
#define RADEON_TV_CRC_CNTL 0x0890
#define RADEON_TV_UV_ADR 0x08ac
+# define RADEON_MAX_UV_ADR_MASK 0x000000ff
+# define RADEON_MAX_UV_ADR_SHIFT 0
+# define RADEON_TABLE1_BOT_ADR_MASK 0x0000ff00
+# define RADEON_TABLE1_BOT_ADR_SHIFT 8
+# define RADEON_TABLE3_TOP_ADR_MASK 0x00ff0000
+# define RADEON_TABLE3_TOP_ADR_SHIFT 16
+# define RADEON_HCODE_TABLE_SEL_MASK 0x06000000
+# define RADEON_HCODE_TABLE_SEL_SHIFT 25
+# define RADEON_VCODE_TABLE_SEL_MASK 0x18000000
+# define RADEON_VCODE_TABLE_SEL_SHIFT 27
+# define RADEON_TV_MAX_FIFO_ADDR 0x1a7
+# define RADEON_TV_MAX_FIFO_ADDR_INTERNAL 0x1ff
#define RADEON_TV_PLL_FINE_CNTL 0x0020 /* PLL */
#define RADEON_TV_PLL_CNTL 0x0021 /* PLL */
+# define RADEON_TV_M0LO_MASK 0xff
+# define RADEON_TV_M0HI_MASK 0x3
+# define RADEON_TV_M0HI_SHIFT 18
+# define RADEON_TV_N0LO_MASK 0xff
+# define RADEON_TV_N0LO_SHIFT 8
+# define RADEON_TV_N0HI_MASK 0x3
+# define RADEON_TV_N0HI_SHIFT 21
+# define RADEON_TV_P_MASK 0xf
+# define RADEON_TV_P_SHIFT 24
# 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_RESET (1 << 1)
# define RADEON_TVPLL_SLEEP (1 << 3)
# define RADEON_TVPLL_REFCLK_SEL (1 << 4)
+# define RADEON_TVPDC_SHIFT 14
+# define RADEON_TVPDC_MASK (3 << 14)
+# define RADEON_TVPLL_TEST_DIS (1 << 31)
+# define RADEON_TVCLK_SRC_SEL_TVPLL (1 << 30)
+#define RADEON_GPIOPAD_A 0x019c
#define RADEON_RS480_UNK_e30 0xe30
#define RADEON_RS480_UNK_e34 0xe34
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
new file mode 100644
index 0000000..1d0b2c6
--- /dev/null
+++ b/src/radeon_tv.c
@@ -0,0 +1,656 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+
+/**********************************************************************
+ *
+ * ModeConstants
+ *
+ * Storage of constants related to a single video mode
+ *
+ **********************************************************************/
+
+typedef struct
+{
+ CARD16 horResolution;
+ CARD16 verResolution;
+ TVStd standard;
+ CARD16 horTotal;
+ CARD16 verTotal;
+ CARD16 horStart;
+ CARD16 horSyncStart;
+ CARD16 verSyncStart;
+ unsigned defRestart;
+ CARD32 vScalerCntl1;
+ CARD32 yRiseCntl;
+ CARD32 ySawtoothCntl;
+ CARD16 crtcPLL_N;
+ CARD8 crtcPLL_M;
+ Bool crtcPLL_divBy2;
+ CARD8 crtcPLL_byteClkDiv;
+ CARD8 crtcPLL_postDiv;
+ Bool use888RGB; /* False: RGB data is 565 packed (2 bytes/pixel) */
+ /* True : RGB data is 888 packed (3 bytes/pixel) */
+ unsigned pixToTV;
+ CARD8 byteClkDelay;
+ CARD32 tvoDataDelayA;
+ CARD32 tvoDataDelayB;
+ const CARD16 *horTimingTable;
+ const CARD16 *verTimingTable;
+} TVModeConstants;
+
+static const CARD16 horTimingNTSC_BIOS[] =
+{
+ 0x0007,
+ 0x003f,
+ 0x0263,
+ 0x0a24,
+ 0x2a6b,
+ 0x0a36,
+ 0x126d, /* H_TABLE_POS1 */
+ 0x1bfe,
+ 0x1a8f, /* H_TABLE_POS2 */
+ 0x1ec7,
+ 0x3863,
+ 0x1bfe,
+ 0x1bfe,
+ 0x1a2a,
+ 0x1e95,
+ 0x0e31,
+ 0x201b,
+ 0
+};
+
+static const CARD16 verTimingNTSC_BIOS[] =
+{
+ 0x2001,
+ 0x200d,
+ 0x1006,
+ 0x0c06,
+ 0x1006,
+ 0x1818,
+ 0x21e3,
+ 0x1006,
+ 0x0c06,
+ 0x1006,
+ 0x1817,
+ 0x21d4,
+ 0x0002,
+ 0
+};
+
+static const CARD16 horTimingPAL_BIOS[] =
+{
+ 0x0007,
+ 0x0058,
+ 0x027c,
+ 0x0a31,
+ 0x2a77,
+ 0x0a95,
+ 0x124f, /* H_TABLE_POS1 */
+ 0x1bfe,
+ 0x1b22, /* H_TABLE_POS2 */
+ 0x1ef9,
+ 0x387c,
+ 0x1bfe,
+ 0x1bfe,
+ 0x1b31,
+ 0x1eb5,
+ 0x0e43,
+ 0x201b,
+ 0
+};
+
+static const CARD16 verTimingPAL_BIOS[] =
+{
+ 0x2001,
+ 0x200c,
+ 0x1005,
+ 0x0c05,
+ 0x1005,
+ 0x1401,
+ 0x1821,
+ 0x2240,
+ 0x1005,
+ 0x0c05,
+ 0x1005,
+ 0x1401,
+ 0x1822,
+ 0x2230,
+ 0x0002,
+ 0
+};
+
+/**********************************************************************
+ *
+ * availableModes
+ *
+ * Table of all allowed modes for tv output
+ *
+ **********************************************************************/
+static const TVModeConstants availableTVModes[] =
+{
+ {
+ 800, /* horResolution */
+ 600, /* verResolution */
+ TV_STD_NTSC, /* standard */
+ 990, /* horTotal */
+ 740, /* verTotal */
+ 813, /* horStart */
+ 824, /* horSyncStart */
+ 632, /* verSyncStart */
+ 625592, /* defRestart */
+ 0x0900b46b, /* vScalerCntl1 */
+ 0x00012c00, /* yRiseCntl */
+ 0x10002d1a, /* ySawtoothCntl */
+ 592, /* crtcPLL_N */
+ 91, /* crtcPLL_M */
+ TRUE, /* crtcPLL_divBy2 */
+ 0, /* crtcPLL_byteClkDiv */
+ 4, /* crtcPLL_postDiv */
+ FALSE, /* use888RGB */
+ 1022, /* pixToTV */
+ 1, /* byteClkDelay */
+ 0x0a0b0907, /* tvoDataDelayA */
+ 0x060a090a, /* tvoDataDelayB */
+ horTimingNTSC_BIOS, /* horTimingTable */
+ verTimingNTSC_BIOS /* verTimingTable */
+ },
+ {
+ 800, /* horResolution */
+ 600, /* verResolution */
+ TV_STD_PAL, /* standard */
+ 1144, /* horTotal */
+ 706, /* verTotal */
+ 812, /* horStart */
+ 824, /* horSyncStart */
+ 669, /* verSyncStart */
+ 696700, /* defRestart */
+ 0x09009097, /* vScalerCntl1 */
+ 0x000007da, /* yRiseCntl */
+ 0x10002426, /* ySawtoothCntl */
+ 1382, /* crtcPLL_N */
+ 231, /* crtcPLL_M */
+ TRUE, /* crtcPLL_divBy2 */
+ 0, /* crtcPLL_byteClkDiv */
+ 4, /* crtcPLL_postDiv */
+ FALSE, /* use888RGB */
+ 759, /* pixToTV */
+ 1, /* byteClkDelay */
+ 0x0a0b0907, /* tvoDataDelayA */
+ 0x060a090a, /* tvoDataDelayB */
+ horTimingPAL_BIOS, /* horTimingTable */
+ verTimingPAL_BIOS /* verTimingTable */
+ }
+};
+
+#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ]))
+
+
+/* Compute F,V,H restarts from default restart position and hPos & vPos
+ * Return TRUE when code timing table was changed
+ */
+static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int restart;
+ unsigned hTotal;
+ unsigned vTotal;
+ unsigned fTotal;
+ int vOffset;
+ int hOffset;
+ CARD16 p1;
+ CARD16 p2;
+ Bool hChanged;
+ CARD16 hInc;
+ const TVModeConstants *constPtr;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ hTotal = constPtr->horTotal;
+ vTotal = constPtr->verTotal;
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ fTotal = NTSC_TV_VFTOTAL + 1;
+ else
+ fTotal = PAL_TV_VFTOTAL + 1;
+
+ /*
+ * Adjust positions 1&2 in hor. code timing table
+ */
+ hOffset = radeon_output->hPos * H_POS_UNIT;
+
+ p1 = constPtr->horTimingTable[ H_TABLE_POS1 ];
+ p2 = constPtr->horTimingTable[ H_TABLE_POS2 ];
+
+ p1 = (CARD16)((int)p1 + hOffset);
+ p2 = (CARD16)((int)p2 - hOffset);
+
+ hChanged = (p1 != save->h_code_timing[ H_TABLE_POS1 ] ||
+ p2 != save->h_code_timing[ H_TABLE_POS2 ]);
+
+ save->h_code_timing[ H_TABLE_POS1 ] = p1;
+ save->h_code_timing[ H_TABLE_POS2 ] = p2;
+
+ /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
+ hOffset = (hOffset * (int)(constPtr->pixToTV)) / 1000;
+
+ /* Adjust restart */
+ restart = constPtr->defRestart;
+
+ /*
+ * Convert vPos TV lines to n. of CRTC pixels
+ * Be verrrrry careful when mixing signed & unsigned values in C..
+ */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
+ else
+ vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
+
+ restart -= vOffset + hOffset;
+
+ ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n",
+ constPtr->defRestart , radeon_output->hPos , radeon_output->vPos , p1 , p2 , restart);
+
+ save->tv_hrestart = restart % hTotal;
+ restart /= hTotal;
+ save->tv_vrestart = restart % vTotal;
+ restart /= vTotal;
+ save->tv_frestart = restart % fTotal;
+
+ ErrorF("computeRestarts: F/H/V=%u,%u,%u\n",
+ save->tv_frestart , save->tv_vrestart , save->tv_hrestart);
+
+ /* Compute H_INC from hSize */
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
+ (radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
+ else
+ hInc = (CARD16)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) /
+ (radeon_output->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
+
+ save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) |
+ ((CARD32)hInc << RADEON_H_INC_SHIFT);
+
+ ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , radeon_output->hSize , hInc);
+
+ return hChanged;
+}
+
+/* intit TV-out regs */
+void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned i;
+ CARD32 tmp;
+ const TVModeConstants *constPtr;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ save->tv_crc_cntl = 0;
+
+ save->tv_gain_limit_settings = (0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) |
+ (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT);
+
+ save->tv_hdisp = constPtr->horResolution - 1;
+ save->tv_hstart = constPtr->horStart;
+ save->tv_htotal = constPtr->horTotal - 1;
+
+ save->tv_linear_gain_settings = (0x100 << RADEON_UV_GAIN_SHIFT) |
+ (0x100 << RADEON_Y_GAIN_SHIFT);
+
+ save->tv_master_cntl = (RADEON_RESTART_PHASE_FIX
+ | RADEON_VIN_ASYNC_RST
+ | RADEON_AUD_ASYNC_RST
+ | RADEON_DVS_ASYNC_RST
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN);
+
+ save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
+ | RADEON_SYNC_TIP_LEVEL
+ | RADEON_YFLT_EN
+ | RADEON_UVFLT_EN
+ | (0x3b << RADEON_BLANK_LEVEL_SHIFT)
+ | (0x6 << RADEON_CY_FILT_BLEND_SHIFT);
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT);
+ else
+ save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
+ | (0x3b << RADEON_SET_UP_LEVEL_SHIFT);
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ save->tv_modulator_cntl2 = 0x00000191;
+ else
+ save->tv_modulator_cntl2 = 0x003e01b2;
+
+ save->pll_test_cntl = 0;
+
+ save->tv_pre_dac_mux_cntl = (RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_DAC_DITHER_EN);
+
+ save->tv_rgb_cntl = 0x007b0004;
+
+ if (IsPrimary) {
+ if (radeon_output->Flags & RADEON_USE_RMX)
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
+ else
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
+ } else {
+ save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
+ }
+
+ save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE;
+
+ save->tv_sync_size = constPtr->horResolution + 8;
+
+ tmp = (constPtr->vScalerCntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+ tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
+ tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
+ save->tv_timing_cntl = tmp;
+
+ save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
+ | RADEON_TV_MONITOR_DETECT_EN
+ | (8 << 16) | (6 << 20);
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+ else
+ save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
+
+#if 0
+ save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
+ | RADEON_TV_DAC_BDACPD);
+
+ if (MonType == MT_CTV) {
+ save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD;
+ }
+
+ if (MonType == MT_STV) {
+ save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD);
+ }
+#endif
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+ (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+ ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+ (((NTSC_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+ ((NTSC_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+ else
+ save->tv_pll_cntl = (PAL_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+ (((PAL_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+ ((PAL_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+ (((PAL_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+ ((PAL_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+
+ save->tv_upsamp_and_gain_cntl = RADEON_YUPSAMP_EN | RADEON_UVUPSAMP_EN;
+
+ save->tv_uv_adr = 0xc8;
+
+ save->tv_vdisp = constPtr->verResolution - 1;
+
+ if (radeon_output->tvStd == TV_STD_NTSC)
+ save->tv_ftotal = NTSC_TV_VFTOTAL;
+ else
+ save->tv_ftotal = PAL_TV_VFTOTAL;
+
+ save->tv_vscaler_cntl1 = constPtr->vScalerCntl1;
+ save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+
+ save->tv_vscaler_cntl2 = 0x10000000;
+
+ save->tv_vtotal = constPtr->verTotal - 1;
+
+ save->tv_y_fall_cntl = RADEON_Y_FALL_PING_PONG | RADEON_Y_COEF_EN;
+ save->tv_y_fall_cntl |= 0x80000400;
+
+ save->tv_y_rise_cntl = constPtr->yRiseCntl;
+ save->tv_y_saw_tooth_cntl = constPtr->ySawtoothCntl;
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
+ if ((save->h_code_timing[ i ] = constPtr->horTimingTable[ i ]) == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
+ if ((save->v_code_timing[ i ] = constPtr->verTimingTable[ i ]) == 0)
+ break;
+ }
+
+ /*
+ * This must be called AFTER loading timing tables as they are modified by this function
+ */
+ RADEONInitTVRestarts(output, save, mode);
+
+ /*save->hw_debug = 0x00000200;*/
+
+ save->dac_cntl &= ~RADEON_DAC_TVO_EN;
+
+ if (IS_R300_VARIANT)
+ save->gpiopad_a = info->SavedReg.gpiopad_a & ~1;
+
+ if (IsPrimary) {
+ save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC
+ | RADEON_DISP_TV_SOURCE_CRTC);
+ if (info->ChipFamily >= CHIP_FAMILY_R200) {
+ save->disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2;
+ } else {
+ save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+ }
+ } else {
+ save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC;
+
+ if (info->ChipFamily >= CHIP_FAMILY_R200) {
+ save->disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2;
+ } else {
+ save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+ }
+ }
+}
+
+
+/* Set hw registers for a new h/v position & h size */
+static void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ Bool reloadTable;
+ RADEONSavePtr restore = &info->ModeReg;
+
+ reloadTable = RADEONInitTVRestarts(output, restore, mode);
+
+ RADEONRestoreTVRestarts(pScrn, restore);
+
+ OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ if (reloadTable) {
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX);
+
+ RADEONRestoreTVTimingTables(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+ }
+}
+
+void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+ (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+ save->crtc_h_sync_strt_wid = (save->crtc_h_sync_strt_wid
+ & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+ (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+ (constPtr->horSyncStart & 7);
+
+ save->crtc_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+ ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+ save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+ ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+ save->disp_merge_cntl |= RADEON_DISP_RGB_OFFSET_EN;
+}
+
+void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ unsigned postDiv;
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN;
+
+ save->ppll_ref_div = constPtr->crtcPLL_M;
+
+ switch (constPtr->crtcPLL_postDiv) {
+ case 1:
+ postDiv = 0;
+ break;
+ case 2:
+ postDiv = 1;
+ break;
+ case 3:
+ postDiv = 4;
+ break;
+ case 4:
+ postDiv = 2;
+ break;
+ case 6:
+ postDiv = 6;
+ break;
+ case 8:
+ postDiv = 3;
+ break;
+ case 12:
+ postDiv = 7;
+ break;
+ case 16:
+ default:
+ postDiv = 5;
+ break;
+ }
+
+ save->ppll_div_3 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+ save->pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
+ save->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+
+}
+
+void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+ (((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+ save->crtc2_h_sync_strt_wid = (save->crtc2_h_sync_strt_wid
+ & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+ (((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+ (constPtr->horSyncStart & 7);
+
+ save->crtc2_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+ ((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+ save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+ ((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+ save->disp2_merge_cntl |= RADEON_DISP2_RGB_OFFSET_EN;
+}
+
+void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output)
+{
+ unsigned postDiv;
+ const TVModeConstants *constPtr;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ constPtr = &availableTVModes[radeon_output->tvStd];
+
+ save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */
+
+ save->p2pll_ref_div = constPtr->crtcPLL_M;
+
+ switch (constPtr->crtcPLL_postDiv) {
+ case 1:
+ postDiv = 0;
+ break;
+ case 2:
+ postDiv = 1;
+ break;
+ case 3:
+ postDiv = 4;
+ break;
+ case 4:
+ postDiv = 2;
+ break;
+ case 6:
+ postDiv = 6;
+ break;
+ case 8:
+ postDiv = 3;
+ break;
+ case 12:
+ postDiv = 7;
+ break;
+ case 16:
+ default:
+ postDiv = 5;
+ break;
+ }
+
+ save->p2pll_div_0 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+ save->pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
+ save->pixclks_cntl |= (RADEON_PIX2CLK_SRC_SEL_P2PLLCLK
+ | RADEON_PIXCLK_TV_SRC_SEL);
+
+}
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
new file mode 100644
index 0000000..179b87b
--- /dev/null
+++ b/src/radeon_tv.h
@@ -0,0 +1,46 @@
+/*
+ * Maximum length of horizontal/vertical code timing tables for state storage
+ */
+#define MAX_H_CODE_TIMING_LEN 32
+#define MAX_V_CODE_TIMING_LEN 32
+
+/*
+ * Limits of h/v positions (hPos & vPos)
+ */
+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
+
+/*
+ * Unit for hPos (in TV clock periods)
+ */
+#define H_POS_UNIT 10
+
+/*
+ * Indexes in h. code timing table for horizontal line position adjustment
+ */
+#define H_TABLE_POS1 6
+#define H_TABLE_POS2 8
+
+/*
+ * Limits of hor. size (hSize)
+ */
+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
+
+/* tv standard constants */
+#define NTSC_TV_PLL_M 22
+#define NTSC_TV_PLL_N 175
+#define NTSC_TV_PLL_P 5
+#define NTSC_TV_CLOCK_T 233
+#define NTSC_TV_VFTOTAL 1
+#define NTSC_TV_LINES_PER_FRAME 525
+#define NTSC_TV_ZERO_H_SIZE 479166
+#define NTSC_TV_H_SIZE_UNIT 9478
+
+#define PAL_TV_PLL_M 113
+#define PAL_TV_PLL_N 668
+#define PAL_TV_PLL_P 3
+#define PAL_TV_CLOCK_T 188
+#define PAL_TV_VFTOTAL 3
+#define PAL_TV_LINES_PER_FRAME 625
+#define PAL_TV_ZERO_H_SIZE 473200
+#define PAL_TV_H_SIZE_UNIT 9360
diff-tree 8d043db1817d94edeb72ab208dfea60026715d48 (from 62f06d89da3f7160d5e4df8d7ce6fe1a94e9d07c)
Author: Alex Deucher <alex at botch2.com>
Date: Wed Jul 25 20:37:58 2007 -0400
RADEON: Compute PLL VCO gain
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d82e912..e9a0954 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4332,12 +4332,45 @@ static void RADEONPLL2WriteUpdate(ScrnIn
~(RADEON_P2PLL_ATOMIC_UPDATE_W));
}
+static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
+ CARD16 fb_div)
+{
+ unsigned vcoFreq;
+
+ vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
+
+ /*
+ * This is horribly crude: the VCO frequency range is divided into
+ * 3 parts, each part having a fixed PLL gain value.
+ */
+ if (vcoFreq >= 30000)
+ /*
+ * [300..max] MHz : 7
+ */
+ return 7;
+ else if (vcoFreq >= 18000)
+ /*
+ * [180..300) MHz : 4
+ */
+ return 4;
+ else
+ /*
+ * [0..180) MHz : 1
+ */
+ return 1;
+}
+
/* Write PLL registers */
void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
+ RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
+ CARD8 pllGain;
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
if (info->IsMobility) {
/* A temporal workaround for the occational blanking on certain laptop panels.
@@ -4365,10 +4398,12 @@ void RADEONRestorePLLRegisters(ScrnInfoP
RADEON_PPLL_CNTL,
RADEON_PPLL_RESET
| RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN,
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
~(RADEON_PPLL_RESET
| RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_PVG_MASK));
OUTREGP(RADEON_CLOCK_CNTL_INDEX,
RADEON_PLL_DIV_SEL,
@@ -4443,8 +4478,16 @@ void RADEONRestorePLLRegisters(ScrnInfoP
/* Write PLL2 registers */
void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
+ RADEONSavePtr restore)
{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD8 pllGain;
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
+
+
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_CPUCLK,
~(RADEON_PIX2CLK_SRC_SEL_MASK));
@@ -4452,9 +4495,11 @@ void RADEONRestorePLL2Registers(ScrnInfo
OUTPLLP(pScrn,
RADEON_P2PLL_CNTL,
RADEON_P2PLL_RESET
- | RADEON_P2PLL_ATOMIC_UPDATE_EN,
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN
+ | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
~(RADEON_P2PLL_RESET
- | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN
+ | RADEON_P2PLL_PVG_MASK));
OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 9423bca..5fdda45 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -1225,6 +1225,8 @@
#define RADEON_P2PLL_CNTL 0x002a /* P2PLL */
# define RADEON_P2PLL_RESET (1 << 0)
# define RADEON_P2PLL_SLEEP (1 << 1)
+# define RADEON_P2PLL_PVG_MASK (7 << 11)
+# define RADEON_P2PLL_PVG_SHIFT 11
# define RADEON_P2PLL_ATOMIC_UPDATE_EN (1 << 16)
# define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
# define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18)
@@ -1274,6 +1276,8 @@
#define RADEON_PPLL_CNTL 0x0002 /* PLL */
# define RADEON_PPLL_RESET (1 << 0)
# define RADEON_PPLL_SLEEP (1 << 1)
+# define RADEON_PPLL_PVG_MASK (7 << 11)
+# define RADEON_PPLL_PVG_SHIFT 11
# define RADEON_PPLL_ATOMIC_UPDATE_EN (1 << 16)
# define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
# define RADEON_PPLL_ATOMIC_UPDATE_VSYNC (1 << 18)
diff-tree 62f06d89da3f7160d5e4df8d7ce6fe1a94e9d07c (from 9cc3ab8320162f371bba15dc131f23c5de2013fc)
Author: Alex Deucher <alex at botch2.com>
Date: Wed Jul 25 20:22:25 2007 -0400
RADEON: write out saved vclk and pixclk values
diff --git a/src/radeon.h b/src/radeon.h
index c759b75..96c4632 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -281,7 +281,7 @@ typedef struct {
unsigned ppll_ref_div;
unsigned ppll_div_3;
CARD32 htotal_cntl;
- CARD32 vclk_cntl;
+ CARD32 vclk_ecp_cntl;
/* Computed values for PLL2 */
CARD32 dot_clock_freq_2;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 5bd2338..3518c9c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -670,7 +670,7 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn
save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
save->htotal_cntl = 0;
- save->vclk_cntl = (info->SavedReg.vclk_cntl &
+ save->vclk_ecp_cntl = (info->SavedReg.vclk_ecp_cntl &
~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 36e14ff..d82e912 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4431,9 +4431,10 @@ void RADEONRestorePLLRegisters(ScrnInfoP
usleep(50000); /* Let the clock to lock */
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+ /* OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
RADEON_VCLK_SRC_SEL_PPLLCLK,
- ~(RADEON_VCLK_SRC_SEL_MASK));
+ ~(RADEON_VCLK_SRC_SEL_MASK));*/
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);
ErrorF("finished PLL1\n");
@@ -4493,9 +4494,10 @@ void RADEONRestorePLL2Registers(ScrnInfo
usleep(5000); /* Let the clock to lock */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+ /*OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK));*/
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
ErrorF("finished PLL2\n");
@@ -4907,7 +4909,7 @@ static void RADEONSavePLLRegisters(ScrnI
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);
+ save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
"Read: 0x%08x 0x%08x 0x%08lx\n",
More information about the xorg-commit
mailing list