diff options
author | Dave Airlie <airlied@linux.ie> | 2007-12-30 17:40:37 +1000 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2007-12-30 17:40:37 +1000 |
commit | aa7c28cbd943bb525698515d444cb5097880e364 (patch) | |
tree | e411b387e2e386092bb9ddf5a9b14f9a917883f9 /src | |
parent | 0bc3fd595a73e12a424571697d164a09a6a4c072 (diff) |
atombios: enable support for using tv timings
enable support for the atombios tv timings selection by programming the crtc
with the tv timings if a tv is detected on the output
Diffstat (limited to 'src')
-rw-r--r-- | src/atombios_crtc.c | 59 | ||||
-rw-r--r-- | src/radeon_atombios.c | 32 | ||||
-rw-r--r-- | src/radeon_atombios.h | 3 |
3 files changed, 80 insertions, 14 deletions
diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c index ebfadd6..6769988 100644 --- a/src/atombios_crtc.c +++ b/src/atombios_crtc.c @@ -244,10 +244,12 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc, ScrnInfoPtr pScrn = crtc->scrn; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; RADEONInfoPtr info = RADEONPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; unsigned long fb_location = crtc->scrn->fbOffset + info->fbLocation; Bool tilingOld = info->tilingEnabled; - + int need_tv_timings = 0; + int i, ret; SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; memset(&crtc_timing, 0, sizeof(crtc_timing)); @@ -267,22 +269,51 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc, #endif } - crtc_timing.ucCRTC = radeon_crtc->crtc_id; - crtc_timing.usH_Total = adjusted_mode->CrtcHTotal; - crtc_timing.usH_Disp = adjusted_mode->CrtcHDisplay; - crtc_timing.usH_SyncStart = adjusted_mode->CrtcHSyncStart; - crtc_timing.usH_SyncWidth = adjusted_mode->CrtcHSyncEnd - adjusted_mode->CrtcHSyncStart; + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + RADEONOutputPrivatePtr radeon_output = output->driver_private; - crtc_timing.usV_Total = adjusted_mode->CrtcVTotal; - crtc_timing.usV_Disp = adjusted_mode->CrtcVDisplay; - crtc_timing.usV_SyncStart = adjusted_mode->CrtcVSyncStart; - crtc_timing.usV_SyncWidth = adjusted_mode->CrtcVSyncEnd - adjusted_mode->CrtcVSyncStart; + if (output->crtc == crtc) { + if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) { + if (radeon_output->tvStd == TV_STD_NTSC || + radeon_output->tvStd == TV_STD_NTSC_J || + radeon_output->tvStd == TV_STD_PAL_M) + need_tv_timings = 1; + else + need_tv_timings = 2; - if (adjusted_mode->Flags & V_NVSYNC) - crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; + } + } + } - if (adjusted_mode->Flags & V_NHSYNC) - crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; + crtc_timing.ucCRTC = radeon_crtc->crtc_id; + if (need_tv_timings) { + ret = RADEONATOMGetTVTimings(pScrn, need_tv_timings - 1, &crtc_timing, &adjusted_mode->Clock); + if (ret == FALSE) { + need_tv_timings = 0; + } else { + adjusted_mode->CrtcHDisplay = crtc_timing.usH_Disp; + } + } + + if (!need_tv_timings) { + crtc_timing.usH_Total = adjusted_mode->CrtcHTotal; + crtc_timing.usH_Disp = adjusted_mode->CrtcHDisplay; + crtc_timing.usH_SyncStart = adjusted_mode->CrtcHSyncStart; + crtc_timing.usH_SyncWidth = adjusted_mode->CrtcHSyncEnd - adjusted_mode->CrtcHSyncStart; + + crtc_timing.usV_Total = adjusted_mode->CrtcVTotal; + crtc_timing.usV_Disp = adjusted_mode->CrtcVDisplay; + crtc_timing.usV_SyncStart = adjusted_mode->CrtcVSyncStart; + crtc_timing.usV_SyncWidth = adjusted_mode->CrtcVSyncEnd - adjusted_mode->CrtcVSyncStart; + + if (adjusted_mode->Flags & V_NVSYNC) + crtc_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY; + + if (adjusted_mode->Flags & V_NHSYNC) + crtc_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY; + + } ErrorF("Mode %dx%d - %d %d %d\n", adjusted_mode->CrtcHDisplay, adjusted_mode->CrtcVDisplay, adjusted_mode->CrtcHTotal, adjusted_mode->CrtcVTotal, adjusted_mode->Flags); diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index 0c0122e..ff16368 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -1531,6 +1531,38 @@ RADEONGetATOMTVInfo(xf86OutputPtr output) } Bool +RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, uint32_t *pixel_clock) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + ATOM_ANALOG_TV_INFO *tv_info; + + tv_info = info->atomBIOS->atomDataPtr->AnalogTV_Info; + + if (index > MAX_SUPPORTED_TV_TIMING) + return FALSE; + + crtc_timing->usH_Total = tv_info->aModeTimings[index].usCRTC_H_Total; + crtc_timing->usH_Disp = tv_info->aModeTimings[index].usCRTC_H_Disp; + crtc_timing->usH_SyncStart = tv_info->aModeTimings[index].usCRTC_H_SyncStart; + crtc_timing->usH_SyncWidth = tv_info->aModeTimings[index].usCRTC_H_SyncWidth; + + crtc_timing->usV_Total = tv_info->aModeTimings[index].usCRTC_V_Total; + crtc_timing->usV_Disp = tv_info->aModeTimings[index].usCRTC_V_Disp; + crtc_timing->usV_SyncStart = tv_info->aModeTimings[index].usCRTC_V_SyncStart; + crtc_timing->usV_SyncWidth = tv_info->aModeTimings[index].usCRTC_V_SyncWidth; + + crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo; + + crtc_timing->ucOverscanRight = tv_info->aModeTimings[index].usCRTC_OverscanRight; + crtc_timing->ucOverscanLeft = tv_info->aModeTimings[index].usCRTC_OverscanLeft; + crtc_timing->ucOverscanBottom = tv_info->aModeTimings[index].usCRTC_OverscanBottom; + crtc_timing->ucOverscanTop = tv_info->aModeTimings[index].usCRTC_OverscanTop; + *pixel_clock = tv_info->aModeTimings[index].usPixelClock * 10; + + return TRUE; +} + +Bool RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR (pScrn); diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h index 111fb45..d4dc1e4 100644 --- a/src/radeon_atombios.h +++ b/src/radeon_atombios.h @@ -246,4 +246,7 @@ typedef struct _atomBiosHandle { # endif +extern Bool +RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, uint32_t *pixel_clock); + #endif /* RHD_ATOMBIOS_H_ */ |