diff options
author | Alex Deucher <alex@samba.(none)> | 2007-11-26 17:34:51 -0500 |
---|---|---|
committer | Alex Deucher <alex@samba.(none)> | 2007-11-26 17:34:51 -0500 |
commit | bb8545146959b748994be055d5b3de66ec66c8b2 (patch) | |
tree | 7096acbe1f05b66a1a8dd39e60c38a53d0311987 /src/atombios_output.c | |
parent | e2bde646b864dca9056d9ecfe23a0d905647ea9a (diff) |
RADEON: first pass at TV/Component video
Untested and not likely to work just yet.
Diffstat (limited to 'src/atombios_output.c')
-rw-r--r-- | src/atombios_output.c | 208 |
1 files changed, 177 insertions, 31 deletions
diff --git a/src/atombios_output.c b/src/atombios_output.c index ecbfbdba..f84afd09 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -23,6 +23,7 @@ * * Authors: * Dave Airlie <airlied@redhat.com> + * Alex Deucher <alexdeucher@gmail.com> * */ @@ -45,23 +46,48 @@ static int atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) { + RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; disp_data.ucAction = 1; - disp_data.ucDacStandard = 1; + + if (radeon_output->MonType == MT_CRT) + disp_data.ucDacStandard = ATOM_DAC1_PS2; + else if (radeon_output->MonType == MT_CV) + disp_data.ucDacStandard = ATOM_DAC1_CV; + else if (OUTPUT_IS_TV) { + switch (radeon_output->tvStd) { + case TV_STD_NTSC: + case TV_STD_NTSC_J: + case TV_STD_PAL_60: + disp_data.ucDacStandard = ATOM_DAC1_NTSC; + break; + case TV_STD_PAL: + case TV_STD_PAL_M: + case TV_STD_SCART_PAL: + case TV_STD_SECAM: + case TV_STD_PAL_CN: + disp_data.ucDacStandard = ATOM_DAC1_PAL; + break; + default: + disp_data.ucDacStandard = ATOM_DAC1_NTSC; + break; + } + } + disp_data.usPixelClock = mode->Clock / 10; data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC1EncoderControl); data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; - + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { ErrorF("Output DAC1 setup success\n"); return ATOM_SUCCESS; } - + ErrorF("Output DAC1 setup failed\n"); return ATOM_NOT_IMPLEMENTED; @@ -70,28 +96,113 @@ atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) static int atombios_output_dac2_setup(xf86OutputPtr output, DisplayModePtr mode) { + RADEONOutputPrivatePtr radeon_output = output->driver_private; RADEONInfoPtr info = RADEONPTR(output->scrn); DAC_ENCODER_CONTROL_PS_ALLOCATION disp_data; AtomBiosArgRec data; unsigned char *space; disp_data.ucAction = 1; - disp_data.ucDacStandard = 1; + + if (radeon_output->MonType == MT_CRT) + disp_data.ucDacStandard = ATOM_DAC2_PS2; + else if (radeon_output->MonType == MT_CV) + disp_data.ucDacStandard = ATOM_DAC2_CV; + else if (OUTPUT_IS_TV) { + switch (radeon_output->tvStd) { + case TV_STD_NTSC: + case TV_STD_NTSC_J: + case TV_STD_PAL_60: + disp_data.ucDacStandard = ATOM_DAC2_NTSC; + break; + case TV_STD_PAL: + case TV_STD_PAL_M: + case TV_STD_SCART_PAL: + case TV_STD_SECAM: + case TV_STD_PAL_CN: + disp_data.ucDacStandard = ATOM_DAC2_PAL; + break; + default: + disp_data.ucDacStandard = ATOM_DAC2_NTSC; + break; + } + } + disp_data.usPixelClock = mode->Clock / 10; data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC2EncoderControl); data.exec.dataSpace = (void *)&space; data.exec.pspace = &disp_data; - + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { ErrorF("Output DAC2 setup success\n"); return ATOM_SUCCESS; } - + ErrorF("Output DAC2 setup failed\n"); return ATOM_NOT_IMPLEMENTED; } +static int +atombios_output_tv1_setup(xf86OutputPtr output, DisplayModePtr mode) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + RADEONInfoPtr info = RADEONPTR(output->scrn); + TV_ENCODER_CONTROL_PS_ALLOCATION disp_data; + AtomBiosArgRec data; + unsigned char *space; + + disp_data.sTVEncoder.ucAction = 1; + + if (radeon_output->MonType == MT_CV) + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_CV; + else { + switch (radeon_output->tvStd) { + case TV_STD_NTSC: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; + break; + case TV_STD_PAL: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; + break; + case TV_STD_PAL_M: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALM; + break; + case TV_STD_PAL_60: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL60; + break; + case TV_STD_NTSC_J: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSCJ; + break; + case TV_STD_SCART_PAL: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PAL; /* ??? */ + break; + case TV_STD_SECAM: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_SECAM; + break; + case TV_STD_PAL_CN: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_PALCN; + break; + default: + disp_data.sTVEncoder.ucTvStandard = ATOM_TV_NTSC; + break; + } + } + + disp_data.sTVEncoder.usPixelClock = mode->Clock / 10; + data.exec.index = GetIndexIntoMasterTable(COMMAND, TVEncoderControl); + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &disp_data; + + if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { + ErrorF("Output TV1 setup success\n"); + return ATOM_SUCCESS; + } + + ErrorF("Output TV1 setup failed\n"); + return ATOM_NOT_IMPLEMENTED; + +} + int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode) { @@ -251,6 +362,12 @@ atombios_device_dpms(xf86OutputPtr output, int device, int mode) case ATOM_DEVICE_LCD1_SUPPORT: index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); break; + case ATOM_DEVICE_TV1_SUPPORT: + index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); + break; + case ATOM_DEVICE_CV_SUPPORT: + index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); + break; default: return; } @@ -411,31 +528,51 @@ atombios_output_mode_set(xf86OutputPtr output, } else if (radeon_output->MonType == MT_LCD) { if (radeon_output->devices & ATOM_DEVICE_LCD1_SUPPORT) atombios_output_lvds_setup(output, adjusted_mode); + } else if (OUTPUT_IS_TV || (radeon_output->MonType == MT_CV)) { + atombios_output_dac2_setup(output, adjusted_mode); + atombios_output_tv1_setup(output, adjusted_mode); } + } static AtomBiosResult -atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, int dac) +atom_bios_dac_load_detect(atomBiosHandlePtr atomBIOS, xf86OutputPtr output) { - DAC_LOAD_DETECTION_PS_ALLOCATION dac_data; - AtomBiosArgRec data; - unsigned char *space; - - dac_data.sDacload.usDeviceID = 0; - dac_data.sDacload.ucDacType = 0; - dac_data.sDacload.ucMisc = 0; - - data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); - data.exec.dataSpace = (void *)&space; - data.exec.pspace = &dac_data; - - if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { - - ErrorF("Dac detection success\n"); - return ATOM_SUCCESS ; - } - - ErrorF("DAC detection failed\n"); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + DAC_LOAD_DETECTION_PS_ALLOCATION dac_data; + AtomBiosArgRec data; + unsigned char *space; + + if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { + dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT1_SUPPORT; + dac_data.sDacload.ucDacType = ATOM_DAC_A; + } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { + dac_data.sDacload.usDeviceID = ATOM_DEVICE_CRT2_SUPPORT; + dac_data.sDacload.ucDacType = ATOM_DAC_B; + } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { + dac_data.sDacload.usDeviceID = ATOM_DEVICE_CV_SUPPORT; + dac_data.sDacload.ucDacType = ATOM_DAC_B; + } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { + dac_data.sDacload.usDeviceID = ATOM_DEVICE_TV1_SUPPORT; + dac_data.sDacload.ucDacType = ATOM_DAC_B; + } else { + ErrorF("invalid output device for dac detection\n"); + return ATOM_NOT_IMPLEMENTED; + } + + dac_data.sDacload.ucMisc = 0; + + data.exec.index = GetIndexIntoMasterTable(COMMAND, DAC_LoadDetection); + data.exec.dataSpace = (void *)&space; + data.exec.pspace = &dac_data; + + if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) { + + ErrorF("Dac detection success\n"); + return ATOM_SUCCESS ; + } + + ErrorF("DAC detection failed\n"); return ATOM_NOT_IMPLEMENTED; } @@ -449,19 +586,28 @@ atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output) AtomBiosResult ret; uint32_t bios_0_scratch; - ret = atom_bios_dac_load_detect(info->atomBIOS, radeon_output->DACType); + ret = atom_bios_dac_load_detect(info->atomBIOS, output); if (ret == ATOM_SUCCESS) { - ErrorF("DAC connect %08X\n", (unsigned int)INREG(RADEON_BIOS_0_SCRATCH)); bios_0_scratch = INREG(RADEON_BIOS_0_SCRATCH); - + ErrorF("DAC connect %08X\n", (unsigned int)bios_0_scratch); + if (radeon_output->devices & ATOM_DEVICE_CRT1_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT1_COLOR) + if (bios_0_scratch & ATOM_S0_CRT1_MASK) MonType = MT_CRT; } else if (radeon_output->devices & ATOM_DEVICE_CRT2_SUPPORT) { - if (bios_0_scratch & ATOM_S0_CRT2_COLOR) + if (bios_0_scratch & ATOM_S0_CRT2_MASK) MonType = MT_CRT; + } else if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) { + if (bios_0_scratch & (ATOM_S0_CV_MASK | ATOM_S0_CV_MASK_A)) + MonType = MT_CV; + } else if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) { + if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A)) + MonType = MT_CTV; + else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A)) + MonType = MT_STV; } } + return MonType; } |