xf86-video-ati: Branch 'master' - 3 commits

Alex Deucher agd5f at kemper.freedesktop.org
Wed Oct 7 16:59:02 PDT 2009


 src/atombios_crtc.c   |  274 +++++++++++++++++++++-----------------------------
 src/radeon_atombios.c |   91 ++++++++++------
 src/radeon_atombios.h |    2 
 src/radeon_output.c   |   14 ++
 4 files changed, 190 insertions(+), 191 deletions(-)

New commits:
commit 02e12ae6be7bc1976f63848fa2854d320d5ab36e
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Oct 7 19:56:58 2009 -0400

    ATOM: rework crtc modeset
    
    - clean up tv timing handling
    - unify SetCRTCTiming and SetCRTCDTDTiming interfaces

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 5d95241..c901391 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -189,33 +189,48 @@ atombios_crtc_dpms(xf86CrtcPtr crtc, int mode)
 }
 
 static AtomBiosResult
-atombios_set_crtc_timing(atomBiosHandlePtr atomBIOS, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_param)
+atombios_set_crtc_timing(xf86CrtcPtr crtc, DisplayModePtr mode)
 {
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
     AtomBiosArgRec data;
     unsigned char *space;
-    SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION conv_param;
-
-    conv_param.usH_Total		= cpu_to_le16(crtc_param->usH_Total);
-    conv_param.usH_Disp			= cpu_to_le16(crtc_param->usH_Disp);
-    conv_param.usH_SyncStart		= cpu_to_le16(crtc_param->usH_SyncStart);
-    conv_param.usH_SyncWidth		= cpu_to_le16(crtc_param->usH_SyncWidth);
-    conv_param.usV_Total		= cpu_to_le16(crtc_param->usV_Total);
-    conv_param.usV_Disp			= cpu_to_le16(crtc_param->usV_Disp);
-    conv_param.usV_SyncStart		= cpu_to_le16(crtc_param->usV_SyncStart);
-    conv_param.usV_SyncWidth		= cpu_to_le16(crtc_param->usV_SyncWidth);
-    conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
-    conv_param.ucCRTC			= crtc_param->ucCRTC;
-    conv_param.ucOverscanRight		= crtc_param->ucOverscanRight;
-    conv_param.ucOverscanLeft		= crtc_param->ucOverscanLeft;
-    conv_param.ucOverscanBottom		= crtc_param->ucOverscanBottom;
-    conv_param.ucOverscanTop		= crtc_param->ucOverscanTop;
-    conv_param.ucReserved		= crtc_param->ucReserved;
+    uint16_t misc = 0;
+    SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION param;
+    memset(&param, 0, sizeof(param));
+
+    param.usH_Total		= cpu_to_le16(mode->CrtcHTotal);
+    param.usH_Disp		= cpu_to_le16(mode->CrtcHDisplay);
+    param.usH_SyncStart		= cpu_to_le16(mode->CrtcHSyncStart);
+    param.usH_SyncWidth		= cpu_to_le16(mode->CrtcHSyncEnd - mode->CrtcHSyncStart);
+    param.usV_Total		= cpu_to_le16(mode->CrtcVTotal);
+    param.usV_Disp		= cpu_to_le16(mode->CrtcVDisplay);
+    param.usV_SyncStart		= cpu_to_le16(mode->CrtcVSyncStart);
+    param.usV_SyncWidth		= cpu_to_le16(mode->CrtcVSyncEnd - mode->CrtcVSyncStart);
+
+    if (mode->Flags & V_NVSYNC)
+	misc |= ATOM_VSYNC_POLARITY;
+
+    if (mode->Flags & V_NHSYNC)
+	misc |= ATOM_HSYNC_POLARITY;
+
+    if (mode->Flags & V_CSYNC)
+	misc |= ATOM_COMPOSITESYNC;
+
+    if (mode->Flags & V_INTERLACE)
+	misc |= ATOM_INTERLACE;
+
+    if (mode->Flags & V_DBLSCAN)
+	misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+    param.susModeMiscInfo.usAccess      = cpu_to_le16(misc);
+    param.ucCRTC			= radeon_crtc->crtc_id;
 
     data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_Timing);
     data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &conv_param;
+    data.exec.pspace = &param;
 
-    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
 	ErrorF("Set CRTC Timing success\n");
 	return ATOM_SUCCESS ;
     }
@@ -225,28 +240,48 @@ atombios_set_crtc_timing(atomBiosHandlePtr atomBIOS, SET_CRTC_TIMING_PARAMETERS_
 }
 
 static AtomBiosResult
-atombios_set_crtc_dtd_timing(atomBiosHandlePtr atomBIOS, SET_CRTC_USING_DTD_TIMING_PARAMETERS *crtc_param)
+atombios_set_crtc_dtd_timing(xf86CrtcPtr crtc, DisplayModePtr mode)
 {
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
     AtomBiosArgRec data;
     unsigned char *space;
-    SET_CRTC_USING_DTD_TIMING_PARAMETERS conv_param;
-
-    conv_param.usH_Size        = cpu_to_le16(crtc_param->usH_Size);
-    conv_param.usH_Blanking_Time= cpu_to_le16(crtc_param->usH_Blanking_Time);
-    conv_param.usV_Size        = cpu_to_le16(crtc_param->usV_Size);
-    conv_param.usV_Blanking_Time= cpu_to_le16(crtc_param->usV_Blanking_Time);
-    conv_param.usH_SyncOffset= cpu_to_le16(crtc_param->usH_SyncOffset);
-    conv_param.usH_SyncWidth= cpu_to_le16(crtc_param->usH_SyncWidth);
-    conv_param.usV_SyncOffset= cpu_to_le16(crtc_param->usV_SyncOffset);
-    conv_param.usV_SyncWidth= cpu_to_le16(crtc_param->usV_SyncWidth);
-    conv_param.susModeMiscInfo.usAccess = cpu_to_le16(crtc_param->susModeMiscInfo.usAccess);
-    conv_param.ucCRTC= crtc_param->ucCRTC;
+    uint16_t misc = 0;
+    SET_CRTC_USING_DTD_TIMING_PARAMETERS param;
+    memset(&param, 0, sizeof(param));
+
+    param.usH_Size          = cpu_to_le16(mode->CrtcHDisplay);
+    param.usH_Blanking_Time = cpu_to_le16(mode->CrtcHBlankEnd - mode->CrtcHDisplay);
+    param.usV_Size          = cpu_to_le16(mode->CrtcVDisplay);
+    param.usV_Blanking_Time = cpu_to_le16(mode->CrtcVBlankEnd - mode->CrtcVDisplay);
+    param.usH_SyncOffset    = cpu_to_le16(mode->CrtcHSyncStart - mode->CrtcHDisplay);
+    param.usH_SyncWidth     = cpu_to_le16(mode->CrtcHSyncEnd - mode->CrtcHSyncStart);
+    param.usV_SyncOffset    = cpu_to_le16(mode->CrtcVSyncStart - mode->CrtcVDisplay);
+    param.usV_SyncWidth     = cpu_to_le16(mode->CrtcVSyncEnd - mode->CrtcVSyncStart);
+
+    if (mode->Flags & V_NVSYNC)
+	misc |= ATOM_VSYNC_POLARITY;
+
+    if (mode->Flags & V_NHSYNC)
+	misc |= ATOM_HSYNC_POLARITY;
+
+    if (mode->Flags & V_CSYNC)
+	misc |= ATOM_COMPOSITESYNC;
+
+    if (mode->Flags & V_INTERLACE)
+	misc |= ATOM_INTERLACE;
+
+    if (mode->Flags & V_DBLSCAN)
+	misc |= ATOM_DOUBLE_CLOCK_MODE;
+
+    param.susModeMiscInfo.usAccess = cpu_to_le16(misc);
+    param.ucCRTC= radeon_crtc->crtc_id;
 
     data.exec.index = GetIndexIntoMasterTable(COMMAND, SetCRTC_UsingDTDTiming);
     data.exec.dataSpace = (void *)&space;
-    data.exec.pspace = &conv_param;
+    data.exec.pspace = &param;
 
-    if (RHDAtomBiosFunc(atomBIOS->scrnIndex, atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+    if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
 	ErrorF("Set DTD CRTC Timing success\n");
 	return ATOM_SUCCESS ;
     }
@@ -435,106 +470,15 @@ 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;
-    int need_tv_timings = 0;
-    int i, ret;
-    SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing;
-    SET_CRTC_USING_DTD_TIMING_PARAMETERS crtc_dtd_timing;
     Bool tilingChanged = FALSE;
-    memset(&crtc_timing, 0, sizeof(crtc_timing));
-    memset(&crtc_dtd_timing, 0, sizeof(crtc_dtd_timing));
 
     if (info->allowColorTiling) {
         radeon_crtc->can_tile = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
 	tilingChanged = RADEONSetTiling(pScrn);
     }
 
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	RADEONOutputPrivatePtr radeon_output = output->driver_private;
-	radeon_tvout_ptr tvout = &radeon_output->tvout;
-
-	if (output->crtc == crtc) {
-	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
-		if (tvout->tvStd == TV_STD_NTSC ||
-		    tvout->tvStd == TV_STD_NTSC_J ||
-		    tvout->tvStd == TV_STD_PAL_M)
-		    need_tv_timings = 1;
-		else
-		    need_tv_timings = 2;
-
-	    }
-	}
-    }
-
-    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;
-	}
-    }
-
-    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;
-
-	if (adjusted_mode->Flags & V_CSYNC)
-	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
-
-	if (adjusted_mode->Flags & V_INTERLACE)
-	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
-
-	if (adjusted_mode->Flags & V_DBLSCAN)
-	    crtc_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
-
-	if (!IS_AVIVO_VARIANT && (radeon_crtc->crtc_id == 0)) {
-	    crtc_dtd_timing.ucCRTC = radeon_crtc->crtc_id;
-	    crtc_dtd_timing.usH_Size = adjusted_mode->CrtcHDisplay;
-	    crtc_dtd_timing.usV_Size = adjusted_mode->CrtcVDisplay;
-	    crtc_dtd_timing.usH_Blanking_Time = adjusted_mode->CrtcHBlankEnd - adjusted_mode->CrtcHDisplay;
-	    crtc_dtd_timing.usV_Blanking_Time = adjusted_mode->CrtcVBlankEnd - adjusted_mode->CrtcVDisplay;
-	    crtc_dtd_timing.usH_SyncOffset = adjusted_mode->CrtcHSyncStart - adjusted_mode->CrtcHDisplay;
-	    crtc_dtd_timing.usV_SyncOffset = adjusted_mode->CrtcVSyncStart - adjusted_mode->CrtcVDisplay;
-	    crtc_dtd_timing.usH_SyncWidth = adjusted_mode->CrtcHSyncEnd - adjusted_mode->CrtcHSyncStart;
-	    crtc_dtd_timing.usV_SyncWidth = adjusted_mode->CrtcVSyncEnd - adjusted_mode->CrtcVSyncStart;
-	    ErrorF("%d %d %d %d %d %d %d %d\n", crtc_dtd_timing.usH_Size, crtc_dtd_timing.usH_SyncOffset,
-		   crtc_dtd_timing.usH_SyncWidth, crtc_dtd_timing.usH_Blanking_Time,
-		   crtc_dtd_timing.usV_Size, crtc_dtd_timing.usV_SyncOffset,
-		   crtc_dtd_timing.usV_SyncWidth, crtc_dtd_timing.usV_Blanking_Time);
-
-	    if (adjusted_mode->Flags & V_NVSYNC)
-		crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_VSYNC_POLARITY;
-
-	    if (adjusted_mode->Flags & V_NHSYNC)
-		crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_HSYNC_POLARITY;
-
-	    if (adjusted_mode->Flags & V_CSYNC)
-		crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_COMPOSITESYNC;
-
-	    if (adjusted_mode->Flags & V_INTERLACE)
-		crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_INTERLACE;
-
-	    if (adjusted_mode->Flags & V_DBLSCAN)
-		crtc_dtd_timing.susModeMiscInfo.usAccess |= ATOM_DOUBLE_CLOCK_MODE;
-	}
-    }
-
     ErrorF("Mode %dx%d - %d %d %d\n", adjusted_mode->CrtcHDisplay, adjusted_mode->CrtcVDisplay,
 	   adjusted_mode->CrtcHTotal, adjusted_mode->CrtcVTotal, adjusted_mode->Flags);
 
@@ -542,9 +486,9 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
     RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
 
     atombios_crtc_set_pll(crtc, adjusted_mode);
-    atombios_set_crtc_timing(info->atomBIOS, &crtc_timing);
+    atombios_set_crtc_timing(crtc, adjusted_mode);
     if (!IS_AVIVO_VARIANT && (radeon_crtc->crtc_id == 0))
-	atombios_set_crtc_dtd_timing(info->atomBIOS, &crtc_dtd_timing);
+	atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
 
     if (IS_AVIVO_VARIANT) {
 	uint32_t fb_format;
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index d6a8333..13ef1ef 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2127,7 +2127,7 @@ RADEONGetATOMTVInfo(xf86OutputPtr output)
 }
 
 Bool
-RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock)
+RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, DisplayModePtr mode)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     ATOM_ANALOG_TV_INFO *tv_info;
@@ -2135,6 +2135,7 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
     ATOM_DTD_FORMAT *dtd_timings;
     atomDataTablesPtr atomDataPtr;
     uint8_t crev, frev;
+    uint16_t misc;
 
     atomDataPtr = info->atomBIOS->atomDataPtr;
     if (!rhdAtomGetTableRevisionAndSize(
@@ -2150,28 +2151,37 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
 	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;
+	mode->CrtcHTotal     = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
+	mode->CrtcHDisplay   = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
+	mode->CrtcHSyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
+	mode->CrtcHSyncEnd   = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart) +
+	                       le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
+
+	mode->CrtcVTotal     = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
+	mode->CrtcVDisplay   = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
+	mode->CrtcVSyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
+	mode->CrtcVSyncEnd   = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart) +
+	                       le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
+
+	mode->Flags = 0;
+	misc = le16_to_cpu(tv_info->aModeTimings[index].susModeMiscInfo.usAccess);
+	if (misc & ATOM_VSYNC_POLARITY)
+	    mode->Flags |= V_NVSYNC;
+	if (misc & ATOM_HSYNC_POLARITY)
+	    mode->Flags |= V_NHSYNC;
+	if (misc & ATOM_COMPOSITESYNC)
+	    mode->Flags |= V_CSYNC;
+	if (misc & ATOM_INTERLACE)
+	    mode->Flags |= V_INTERLACE;
+	if (misc & ATOM_DOUBLE_CLOCK_MODE)
+	    mode->Flags |= V_DBLSCAN;
+
+	mode->Clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
 
 	if (index == 1) {
 		/* PAL timings appear to have wrong values for totals */
-		crtc_timing->usH_Total -= 1;
-		crtc_timing->usV_Total -= 1;
+		mode->CrtcHTotal -= 1;
+		mode->CrtcVTotal -= 1;
 	}
 	break;
     case 2:
@@ -2180,18 +2190,31 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
 	    return FALSE;
 
 	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->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->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
-	*pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+	mode->CrtcHTotal     = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
+	mode->CrtcHDisplay   = le16_to_cpu(dtd_timings->usHActive);
+	mode->CrtcHSyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
+	mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + le16_to_cpu(dtd_timings->usHSyncWidth);
+
+	mode->CrtcVTotal     = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
+	mode->CrtcVDisplay   = le16_to_cpu(dtd_timings->usVActive);
+	mode->CrtcVSyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
+	mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + le16_to_cpu(dtd_timings->usVSyncWidth);
+
+	mode->Flags = 0;
+	misc = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
+	if (misc & ATOM_VSYNC_POLARITY)
+	    mode->Flags |= V_NVSYNC;
+	if (misc & ATOM_HSYNC_POLARITY)
+	    mode->Flags |= V_NHSYNC;
+	if (misc & ATOM_COMPOSITESYNC)
+	    mode->Flags |= V_CSYNC;
+	if (misc & ATOM_INTERLACE)
+	    mode->Flags |= V_INTERLACE;
+	if (misc & ATOM_DOUBLE_CLOCK_MODE)
+	    mode->Flags |= V_DBLSCAN;
+
+	mode->Clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
+
 	break;
     }
 
diff --git a/src/radeon_atombios.h b/src/radeon_atombios.h
index 81e5a33..d525063 100644
--- a/src/radeon_atombios.h
+++ b/src/radeon_atombios.h
@@ -270,7 +270,7 @@ typedef struct _atomBiosHandle {
 # endif
 
 extern Bool
-RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing, int32_t *pixel_clock);
+RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, DisplayModePtr mode);
 
 extern void
 RADEONATOMGetIGPInfo(ScrnInfoPtr pScrn);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 36ef1aa..75f63b7 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -575,6 +575,20 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 	    adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVDisplay + 2;
     }
 
+    if (IS_AVIVO_VARIANT || info->r4xx_atom) {
+	if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+	    radeon_tvout_ptr tvout = &radeon_output->tvout;
+	    ScrnInfoPtr pScrn = output->scrn;
+
+	    if (tvout->tvStd == TV_STD_NTSC ||
+		tvout->tvStd == TV_STD_NTSC_J ||
+		tvout->tvStd == TV_STD_PAL_M)
+		RADEONATOMGetTVTimings(pScrn, 0, adjusted_mode);
+	    else
+		RADEONATOMGetTVTimings(pScrn, 1, adjusted_mode);
+	}
+    }
+
     return TRUE;
 }
 
commit d499eeaf22f77a1294e99aa38a50aa6810bb684a
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Oct 7 17:43:11 2009 -0400

    ATOM: reorder crtc dpms based on bios recommendations

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index d4823da..5d95241 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -172,18 +172,18 @@ atombios_crtc_dpms(xf86CrtcPtr crtc, int mode)
     RADEONInfoPtr  info = RADEONPTR(crtc->scrn);
     switch (mode) {
     case DPMSModeOn:
+	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 1);
 	if (IS_DCE3_VARIANT)
 	    atombios_enable_crtc_memreq(info->atomBIOS, radeon_crtc->crtc_id, 1);
-	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 1);
 	atombios_blank_crtc(info->atomBIOS, radeon_crtc->crtc_id, 0);
 	break;
     case DPMSModeStandby:
     case DPMSModeSuspend:
     case DPMSModeOff:
 	atombios_blank_crtc(info->atomBIOS, radeon_crtc->crtc_id, 1);
-	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 0);
 	if (IS_DCE3_VARIANT)
 	    atombios_enable_crtc_memreq(info->atomBIOS, radeon_crtc->crtc_id, 0);
+	atombios_enable_crtc(info->atomBIOS, radeon_crtc->crtc_id, 0);
 	break;
     }
 }
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index 0384456..d6a8333 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -2146,15 +2146,15 @@ RADEONATOMGetTVTimings(ScrnInfoPtr pScrn, int index, SET_CRTC_TIMING_PARAMETERS_
     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);
commit 4ccd2a21f9c50515b4246f35454f76ef49006c76
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Wed Oct 7 16:30:03 2009 -0400

    ATOM: add support for AdjustDisplayPll table
    
    Depending on the output and clock, this table will
    adjust the pixelclock accordingly.

diff --git a/src/atombios_crtc.c b/src/atombios_crtc.c
index 341deb4..d4823da 100644
--- a/src/atombios_crtc.c
+++ b/src/atombios_crtc.c
@@ -269,7 +269,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
     SET_PIXEL_CLOCK_PS_ALLOCATION spc_param;
     PIXEL_CLOCK_PARAMETERS_V2 *spc2_ptr;
     PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr;
-    xf86OutputPtr output;
+    xf86OutputPtr output = NULL;
     RADEONOutputPrivatePtr radeon_output = NULL;
     radeon_encoder_ptr radeon_encoder = NULL;
     int pll_flags = 0;
@@ -320,8 +320,47 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	    pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
     }
 
-    RADEONComputePLL(&info->pll, mode->Clock, &temp, &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags);
-    sclock = temp;
+    if (IS_DCE3_VARIANT) {
+	ADJUST_DISPLAY_PLL_PS_ALLOCATION adjust_pll_param;
+
+	/* Can't really do cloning easily on DCE3 cards */
+	for (i = 0; i < xf86_config->num_output; i++) {
+	    output = xf86_config->output[i];
+	    if (output->crtc == crtc) {
+		radeon_output = output->driver_private;
+		radeon_encoder = radeon_get_encoder(output);
+		break;
+	    }
+	}
+
+	if (radeon_output == NULL) {
+	    xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
+	    return;
+	}
+
+	if (radeon_encoder == NULL) {
+	    xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No encoder assigned to output!\n");
+	    return;
+	}
+
+	memset(&adjust_pll_param, 0, sizeof(adjust_pll_param));
+	adjust_pll_param.usPixelClock = cpu_to_le16(sclock / 10);
+	adjust_pll_param.ucTransmitterID = radeon_encoder->encoder_id;
+	adjust_pll_param.ucEncodeMode = atombios_get_encoder_mode(output);
+
+	data.exec.index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
+	data.exec.dataSpace = (void *)&space;
+	data.exec.pspace = &adjust_pll_param;
+
+	ErrorF("before %d\n", adjust_pll_param.usPixelClock);
+	if (RHDAtomBiosFunc(info->atomBIOS->scrnIndex, info->atomBIOS, ATOMBIOS_EXEC, &data) == ATOM_SUCCESS) {
+	    sclock = le16_to_cpu(adjust_pll_param.usPixelClock) * 10;
+	}
+	ErrorF("after %d\n", adjust_pll_param.usPixelClock);
+    }
+
+    RADEONComputePLL(&info->pll, sclock, &temp, &fb_div, &frac_fb_div, &ref_div, &post_div, pll_flags);
+    sclock = temp; /* 10 khz */
 
     xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO,
 	       "crtc(%d) Clock: mode %d, PLL %lu\n",
@@ -331,26 +370,6 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	       radeon_crtc->crtc_id, (unsigned int)ref_div, (unsigned int)fb_div,
 	       (unsigned int)fb_div, (unsigned int)frac_fb_div, (unsigned int)post_div);
 
-    /* Can't really do cloning easily on DCE3 cards */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	output = xf86_config->output[i];
-	if (output->crtc == crtc) {
-	    radeon_output = output->driver_private;
-	    radeon_encoder = radeon_get_encoder(output);
-	    break;
-	}
-    }
-
-    if (radeon_output == NULL) {
-	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No output assigned to crtc!\n");
-	return;
-    }
-
-    if (radeon_encoder == NULL) {
-	xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR, "No encoder assigned to output!\n");
-	return;
-    }
-
     atombios_get_command_table_version(info->atomBIOS, index, &major, &minor);
 
     /*ErrorF("table is %d %d\n", major, minor);*/
@@ -360,7 +379,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	case 1:
 	case 2:
 	    spc2_ptr = (PIXEL_CLOCK_PARAMETERS_V2*)&spc_param.sPCLKInput;
-	    spc2_ptr->usPixelClock = cpu_to_le16(sclock);
+	    spc2_ptr->usPixelClock = cpu_to_le16(mode->Clock / 10);
 	    spc2_ptr->usRefDiv = cpu_to_le16(ref_div);
 	    spc2_ptr->usFbDiv = cpu_to_le16(fb_div);
 	    spc2_ptr->ucFracFbDiv = frac_fb_div;
@@ -372,7 +391,7 @@ atombios_crtc_set_pll(xf86CrtcPtr crtc, DisplayModePtr mode)
 	    break;
 	case 3:
 	    spc3_ptr = (PIXEL_CLOCK_PARAMETERS_V3*)&spc_param.sPCLKInput;
-	    spc3_ptr->usPixelClock = cpu_to_le16(sclock);
+	    spc3_ptr->usPixelClock = cpu_to_le16(mode->Clock / 10);
 	    spc3_ptr->usRefDiv = cpu_to_le16(ref_div);
 	    spc3_ptr->usFbDiv = cpu_to_le16(fb_div);
 	    spc3_ptr->ucFracFbDiv = frac_fb_div;
@@ -634,7 +653,6 @@ atombios_crtc_mode_set(xf86CrtcPtr crtc,
 
 	switch (radeon_crtc->crtc_id) {
 	case 0:
-	    ErrorF("init crtc1\n");
 	    crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL) & 0xfffff0ff;
 	    crtc_gen_cntl |= (format << 8);
 	    OUTREG(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl);


More information about the xorg-commit mailing list