summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-12-17 11:24:56 +1000
committerDave Airlie <airlied@redhat.com>2008-12-17 11:29:02 +1000
commitb7fdd5da08bfec705691363b8890699c794dce53 (patch)
tree23d678e91c1535c1d7638fd39879fb4834b4ee9e
parente3b08cb59716b525b3063b184eab70e32b9d66f0 (diff)
atombios: fixup parsing of TV tables on r500 and r600 cards.
The TV tables changed between for later cards.
-rw-r--r--src/AtomBios/includes/atombios.h11
-rw-r--r--src/radeon_atombios.c72
-rw-r--r--src/radeon_atombios.h6
3 files changed, 69 insertions, 20 deletions
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/radeon_atombios.c b/src/radeon_atombios.c
index d6125721..7a15c8e2 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);
@@ -1842,7 +1842,7 @@ 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;
@@ -1909,29 +1909,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),
+ &frev,&crev,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;
}
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;