summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2007-12-30 17:40:37 +1000
committerDave Airlie <airlied@linux.ie>2007-12-30 17:40:37 +1000
commitaa7c28cbd943bb525698515d444cb5097880e364 (patch)
treee411b387e2e386092bb9ddf5a9b14f9a917883f9 /src
parent0bc3fd595a73e12a424571697d164a09a6a4c072 (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.c59
-rw-r--r--src/radeon_atombios.c32
-rw-r--r--src/radeon_atombios.h3
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_ */