diff options
author | Dave Airlie <airlied@redhat.com> | 2008-12-17 11:24:56 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2008-12-17 11:29:02 +1000 |
commit | b7fdd5da08bfec705691363b8890699c794dce53 (patch) | |
tree | 23d678e91c1535c1d7638fd39879fb4834b4ee9e | |
parent | e3b08cb59716b525b3063b184eab70e32b9d66f0 (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.h | 11 | ||||
-rw-r--r-- | src/radeon_atombios.c | 72 | ||||
-rw-r--r-- | src/radeon_atombios.h | 6 |
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; |