diff options
-rw-r--r-- | man/radeon.man | 6 | ||||
-rw-r--r-- | src/AtomBios/includes/atombios.h | 11 | ||||
-rw-r--r-- | src/atombios_crtc.c | 2 | ||||
-rw-r--r-- | src/atombios_output.c | 53 | ||||
-rw-r--r-- | src/radeon.h | 3 | ||||
-rw-r--r-- | src/radeon_atombios.c | 109 | ||||
-rw-r--r-- | src/radeon_atombios.h | 6 | ||||
-rw-r--r-- | src/radeon_driver.c | 1 |
8 files changed, 144 insertions, 47 deletions
diff --git a/man/radeon.man b/man/radeon.man index f8526dff..19ffb94e 100644 --- a/man/radeon.man +++ b/man/radeon.man @@ -550,6 +550,12 @@ controller has passed the destination region. It reduces tearing at the cost of performance. The default is .B off. +.TP +.BI "Option \*qATOMTvOut\*q \*q" boolean \*q +This option enables experimental TV-out support for r500 and r600 atombios chips. +tv-out is experimental and may not function on these chips as well as hoped for. +The default is +.B off. .SH SEE ALSO __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__) diff --git a/src/AtomBios/includes/atombios.h b/src/AtomBios/includes/atombios.h index 9932b096..7a3afa8d 100644 --- a/src/AtomBios/includes/atombios.h +++ b/src/AtomBios/includes/atombios.h @@ -2495,6 +2495,17 @@ typedef struct _ATOM_ANALOG_TV_INFO ATOM_MODE_TIMING aModeTimings[MAX_SUPPORTED_TV_TIMING]; }ATOM_ANALOG_TV_INFO; +#define MAX_SUPPORTED_TV_TIMING_V1_2 3 + +typedef struct _ATOM_ANALOG_TV_INFO_V1_2 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + UCHAR ucTV_SupportedStandard; + UCHAR ucTV_BootUpDefaultStandard; + UCHAR ucExt_TV_ASIC_ID; + UCHAR ucExt_TV_ASIC_SlaveAddr; + ATOM_DTD_FORMAT aModeTimings[MAX_SUPPORTED_TV_TIMING]; +}ATOM_ANALOG_TV_INFO_V1_2; /**************************************************************************/ // VRAM usage and their defintions diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index 93bf94fa..9a8594a8 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -325,13 +325,11 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode, int pll_flags) spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; else if (radeon_output->DACType == DAC_TVDAC) spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; - spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_TV; } else if (radeon_output->MonType == MT_CV) { if (radeon_output->DACType == DAC_PRIMARY) spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; else if (radeon_output->DACType == DAC_TVDAC) spc3_ptr->ucTransmitterId = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; - spc3_ptr->ucEncoderMode = ATOM_ENCODER_MODE_CV; } ptr = &spc_param; diff --git a/src/atombios_output.c b/src/atombios_output.c index 396af31d..3030a10c 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -62,11 +62,6 @@ atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) 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: @@ -74,6 +69,9 @@ atombios_output_dac1_setup(xf86OutputPtr output, DisplayModePtr mode) case TV_STD_PAL_CN: disp_data.ucDacStandard = ATOM_DAC1_PAL; break; + case TV_STD_NTSC: + case TV_STD_NTSC_J: + case TV_STD_PAL_60: default: disp_data.ucDacStandard = ATOM_DAC1_NTSC; break; @@ -615,9 +613,44 @@ atombios_output_scaler_setup(xf86OutputPtr output, DisplayModePtr mode) AtomBiosArgRec data; unsigned char *space; + memset(&disp_data, 0, sizeof(disp_data)); + disp_data.ucScaler = radeon_crtc->crtc_id; - if (radeon_output->Flags & RADEON_USE_RMX) { + if (OUTPUT_IS_TV) { + switch (radeon_output->tvStd) { + case TV_STD_NTSC: + disp_data.ucTVStandard = ATOM_TV_NTSC; + break; + case TV_STD_PAL: + disp_data.ucTVStandard = ATOM_TV_PAL; + break; + case TV_STD_PAL_M: + disp_data.ucTVStandard = ATOM_TV_PALM; + break; + case TV_STD_PAL_60: + disp_data.ucTVStandard = ATOM_TV_PAL60; + break; + case TV_STD_NTSC_J: + disp_data.ucTVStandard = ATOM_TV_NTSCJ; + break; + case TV_STD_SCART_PAL: + disp_data.ucTVStandard = ATOM_TV_PAL; /* ??? */ + break; + case TV_STD_SECAM: + disp_data.ucTVStandard = ATOM_TV_SECAM; + break; + case TV_STD_PAL_CN: + disp_data.ucTVStandard = ATOM_TV_PALCN; + break; + default: + disp_data.ucTVStandard = ATOM_TV_NTSC; + break; + } + disp_data.ucEnable = SCALER_ENABLE_MULTITAP_MODE; + ErrorF("Using TV scaler %x %x\n", disp_data.ucTVStandard, disp_data.ucEnable); + + } else if (radeon_output->Flags & RADEON_USE_RMX) { ErrorF("Using RMX\n"); if (radeon_output->rmx_type == RMX_FULL) disp_data.ucEnable = ATOM_SCALER_EXPANSION; @@ -812,8 +845,8 @@ atombios_output_dpms(xf86OutputPtr output, int mode) /*ErrorF("AGD: cv dpms\n");*/ if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) atombios_device_dpms(output, ATOM_DEVICE_CV_SUPPORT, mode); - } else if (0 /*radeon_output->MonType == MT_STV || - radeon_output->MonType == MT_CTV*/) { + } else if (radeon_output->MonType == MT_STV || + radeon_output->MonType == MT_CTV) { /*ErrorF("AGD: tv dpms\n");*/ if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) atombios_device_dpms(output, ATOM_DEVICE_TV1_SUPPORT, mode); @@ -913,11 +946,11 @@ atombios_set_output_crtc_source(xf86OutputPtr output) crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS; } else if (OUTPUT_IS_TV) { if (radeon_output->devices & ATOM_DEVICE_TV1_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_TV1_INDEX; + crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_TV; } else if (radeon_output->MonType == MT_CV) { if (radeon_output->devices & ATOM_DEVICE_CV_SUPPORT) - crtc_src_param2.ucEncoderID = ATOM_DEVICE_CV_INDEX; + crtc_src_param2.ucEncoderID = ASIC_INT_TV_ENCODER_ID; crtc_src_param2.ucEncodeMode = ATOM_ENCODER_MODE_CV; } diff --git a/src/radeon.h b/src/radeon.h index 9f0e55a9..2a6f150e 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -205,7 +205,8 @@ typedef enum { OPTION_IGNORE_LID_STATUS, OPTION_DEFAULT_TVDAC_ADJ, OPTION_INT10, - OPTION_EXA_VSYNC + OPTION_EXA_VSYNC, + OPTION_ATOM_TVOUT } RADEONOpts; diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index d6125721..3cd7eae9 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -321,7 +321,7 @@ rhdAtomAnalyzeMasterDataTable(unsigned char *base, SET_DATA_TABLE(DAC_Info); SET_DATA_TABLE_VERS(LVDS_Info); SET_DATA_TABLE(TMDS_Info); - SET_DATA_TABLE(AnalogTV_Info); + SET_DATA_TABLE_VERS(AnalogTV_Info); SET_DATA_TABLE_VERS(SupportedDevicesInfo); SET_DATA_TABLE(GPIO_I2C_Info); SET_DATA_TABLE(VRAM_UsageByFirmware); @@ -1572,6 +1572,10 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) ATOM_CONNECTOR_OBJECT_TABLE *con_obj; ATOM_INTEGRATED_SYSTEM_INFO_V2 *igp_obj = NULL; int i, j; + Bool enable_tv = FALSE; + + if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE)) + enable_tv = TRUE; atomDataPtr = info->atomBIOS->atomDataPtr; if (!rhdAtomGetTableRevisionAndSize((ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->Object_Header), &crev, &frev, &size)) @@ -1702,8 +1706,10 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || info->BiosConnector[i].ConnectorType == CONNECTOR_STV || info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - //info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); - info->BiosConnector[i].valid = FALSE; + if (enable_tv) + info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); + else + info->BiosConnector[i].valid = FALSE; else info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT1_INDEX); info->BiosConnector[i].DACType = DAC_PRIMARY; @@ -1716,8 +1722,10 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn) if (info->BiosConnector[i].ConnectorType == CONNECTOR_DIN || info->BiosConnector[i].ConnectorType == CONNECTOR_STV || info->BiosConnector[i].ConnectorType == CONNECTOR_CTV) - //info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); - info->BiosConnector[i].valid = FALSE; + if (enable_tv) + info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_TV1_INDEX); + else + info->BiosConnector[i].valid = FALSE; else info->BiosConnector[i].devices |= (1 << ATOM_DEVICE_CRT2_INDEX); info->BiosConnector[i].DACType = DAC_TVDAC; @@ -1842,16 +1850,12 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) RADEONOutputPrivatePtr radeon_output = output->driver_private; ATOM_ANALOG_TV_INFO *tv_info; - tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info; + tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info.AnalogTV_Info; if (!tv_info) return FALSE; switch(tv_info->ucTV_BootUpDefaultStandard) { - case NTSC_SUPPORT: - radeon_output->default_tvStd = TV_STD_NTSC; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n"); - break; case NTSCJ_SUPPORT: radeon_output->default_tvStd = TV_STD_NTSC_J; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n"); @@ -1868,6 +1872,11 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) radeon_output->default_tvStd = TV_STD_PAL_60; xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n"); break; + default: + case NTSC_SUPPORT: + radeon_output->default_tvStd = TV_STD_NTSC; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n"); + break; } radeon_output->tvStd = radeon_output->default_tvStd; @@ -1909,29 +1918,63 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_ { RADEONInfoPtr info = RADEONPTR(pScrn); ATOM_ANALOG_TV_INFO *tv_info; + ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2; + ATOM_DTD_FORMAT *dtd_timings; + atomDataTablesPtr atomDataPtr; + uint8_t crev, frev; - tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info; - - if (index > MAX_SUPPORTED_TV_TIMING) + atomDataPtr = info->atomBIOS->atomDataPtr; + if (!rhdAtomGetTableRevisionAndSize( + (ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->AnalogTV_Info.base), + &crev,&frev,NULL)) { return FALSE; + } - crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); - crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); - crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); - crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); + switch(crev) { + case 1: + tv_info = atomDataPtr->AnalogTV_Info.AnalogTV_Info; + + if (index > MAX_SUPPORTED_TV_TIMING) + return FALSE; + + crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total); + crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp); + crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart); + crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth); + + crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); + crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); + crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); + crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); + + crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; + + crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); + crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); + crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); + crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); + *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; + break; + case 2: + tv_info_v1_2 = atomDataPtr->AnalogTV_Info.AnalogTV_Info_v1_2; + if (index > MAX_SUPPORTED_TV_TIMING_V1_2) + return FALSE; - crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total); - crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp); - crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart); - crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth); + dtd_timings = &tv_info_v1_2->aModeTimings[index]; + crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time); + crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive); + crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset); + crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth); - crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; + crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time); + crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive); + crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset); + crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth); - crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight); - crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft); - crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom); - crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop); - *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10; + crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess); + *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10; + break; + } return TRUE; } @@ -1945,6 +1988,10 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) atomDataTablesPtr atomDataPtr; uint8_t crev, frev; int i, j; + Bool enable_tv = FALSE; + + if (xf86ReturnOptValBool(info->Options, OPTION_ATOM_TVOUT, FALSE)) + enable_tv = TRUE; atomDataPtr = info->atomBIOS->atomDataPtr; @@ -1965,20 +2012,16 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) continue; } -#if 1 - if (i == ATOM_DEVICE_CV_INDEX) { + if (!enable_tv && (i == ATOM_DEVICE_CV_INDEX)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Skipping Component Video\n"); info->BiosConnector[i].valid = FALSE; continue; } -#endif -#if 1 - if (i == ATOM_DEVICE_TV1_INDEX) { + if (!enable_tv && (i == ATOM_DEVICE_TV1_INDEX)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Skipping TV-Out\n"); info->BiosConnector[i].valid = FALSE; continue; } -#endif info->BiosConnector[i].valid = TRUE; info->BiosConnector[i].load_detection = TRUE; diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index fbe8dd58..a0163598 100644 --- a/src/radeon_atombios.h +++ b/src/radeon_atombios.h @@ -199,7 +199,11 @@ typedef struct _atomDataTables ATOM_LVDS_INFO_V12 *LVDS_Info_v12; } LVDS_Info; ATOM_TMDS_INFO *TMDS_Info; - ATOM_ANALOG_TV_INFO *AnalogTV_Info; + union { + void *base; + ATOM_ANALOG_TV_INFO *AnalogTV_Info; + ATOM_ANALOG_TV_INFO_V1_2 *AnalogTV_Info_v1_2; + } AnalogTV_Info; union { void *base; ATOM_SUPPORTED_DEVICES_INFO *SupportedDevicesInfo; diff --git a/src/radeon_driver.c b/src/radeon_driver.c index d4148549..e53edbbe 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -192,6 +192,7 @@ static const OptionInfoRec RADEONOptions[] = { { OPTION_DEFAULT_TVDAC_ADJ, "DefaultTVDACAdj", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_INT10, "Int10", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_EXA_VSYNC, "EXAVSync", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_ATOM_TVOUT, "ATOMTVOut", OPTV_BOOLEAN, {0}, FALSE }, { -1, NULL, OPTV_NONE, {0}, FALSE } }; |