aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_atombios.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-08-13 02:32:14 -0400
committerDave Airlie <airlied@redhat.com>2009-09-07 19:24:37 -0400
commit4ce001abafafe77e5dd943d1480fc9f87894e96f (patch)
tree4a22b42c58a80450992fcf5d7625b19fe045855b /drivers/gpu/drm/radeon/radeon_atombios.c
parent551ebd837c75fc75df81811a18b7136c39cab487 (diff)
drm/radeon/kms: add initial radeon tv-out support.
This ports the tv-out code from the DDX to KMS. adds a radeon.tv module option, radeon.tv=0 to disable tv Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_atombios.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c75
1 files changed, 68 insertions, 7 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index fcfe5c02d744..bba9b4bd8f5c 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -471,11 +471,6 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct
471 continue; 471 continue;
472 } 472 }
473 473
474 if (i == ATOM_DEVICE_TV1_INDEX) {
475 DRM_DEBUG("Skipping TV Out\n");
476 continue;
477 }
478
479 bios_connectors[i].connector_type = 474 bios_connectors[i].connector_type =
480 supported_devices_connector_convert[ci.sucConnectorInfo. 475 supported_devices_connector_convert[ci.sucConnectorInfo.
481 sbfAccess. 476 sbfAccess.
@@ -858,6 +853,72 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder)
858 return p_dac; 853 return p_dac;
859} 854}
860 855
856bool radeon_atom_get_tv_timings(struct radeon_device *rdev, int index,
857 SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION *crtc_timing,
858 int32_t *pixel_clock)
859{
860 struct radeon_mode_info *mode_info = &rdev->mode_info;
861 ATOM_ANALOG_TV_INFO *tv_info;
862 ATOM_ANALOG_TV_INFO_V1_2 *tv_info_v1_2;
863 ATOM_DTD_FORMAT *dtd_timings;
864 int data_index = GetIndexIntoMasterTable(DATA, AnalogTV_Info);
865 u8 frev, crev;
866 uint16_t data_offset;
867
868 atom_parse_data_header(mode_info->atom_context, data_index, NULL, &frev, &crev, &data_offset);
869
870 switch (crev) {
871 case 1:
872 tv_info = (ATOM_ANALOG_TV_INFO *)(mode_info->atom_context->bios + data_offset);
873 if (index > MAX_SUPPORTED_TV_TIMING)
874 return false;
875
876 crtc_timing->usH_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Total);
877 crtc_timing->usH_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_Disp);
878 crtc_timing->usH_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncStart);
879 crtc_timing->usH_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_H_SyncWidth);
880
881 crtc_timing->usV_Total = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Total);
882 crtc_timing->usV_Disp = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_Disp);
883 crtc_timing->usV_SyncStart = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncStart);
884 crtc_timing->usV_SyncWidth = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_V_SyncWidth);
885
886 crtc_timing->susModeMiscInfo = tv_info->aModeTimings[index].susModeMiscInfo;
887
888 crtc_timing->ucOverscanRight = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanRight);
889 crtc_timing->ucOverscanLeft = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanLeft);
890 crtc_timing->ucOverscanBottom = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanBottom);
891 crtc_timing->ucOverscanTop = le16_to_cpu(tv_info->aModeTimings[index].usCRTC_OverscanTop);
892 *pixel_clock = le16_to_cpu(tv_info->aModeTimings[index].usPixelClock) * 10;
893
894 if (index == 1) {
895 /* PAL timings appear to have wrong values for totals */
896 crtc_timing->usH_Total -= 1;
897 crtc_timing->usV_Total -= 1;
898 }
899 break;
900 case 2:
901 tv_info_v1_2 = (ATOM_ANALOG_TV_INFO_V1_2 *)(mode_info->atom_context->bios + data_offset);
902 if (index > MAX_SUPPORTED_TV_TIMING_V1_2)
903 return false;
904
905 dtd_timings = &tv_info_v1_2->aModeTimings[index];
906 crtc_timing->usH_Total = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHBlanking_Time);
907 crtc_timing->usH_Disp = le16_to_cpu(dtd_timings->usHActive);
908 crtc_timing->usH_SyncStart = le16_to_cpu(dtd_timings->usHActive) + le16_to_cpu(dtd_timings->usHSyncOffset);
909 crtc_timing->usH_SyncWidth = le16_to_cpu(dtd_timings->usHSyncWidth);
910 crtc_timing->usV_Total = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVBlanking_Time);
911 crtc_timing->usV_Disp = le16_to_cpu(dtd_timings->usVActive);
912 crtc_timing->usV_SyncStart = le16_to_cpu(dtd_timings->usVActive) + le16_to_cpu(dtd_timings->usVSyncOffset);
913 crtc_timing->usV_SyncWidth = le16_to_cpu(dtd_timings->usVSyncWidth);
914
915 crtc_timing->susModeMiscInfo.usAccess = le16_to_cpu(dtd_timings->susModeMiscInfo.usAccess);
916 *pixel_clock = le16_to_cpu(dtd_timings->usPixClk) * 10;
917 break;
918 }
919 return true;
920}
921
861struct radeon_encoder_tv_dac * 922struct radeon_encoder_tv_dac *
862radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) 923radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder)
863{ 924{
@@ -948,10 +1009,10 @@ void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
948 uint32_t bios_2_scratch, bios_6_scratch; 1009 uint32_t bios_2_scratch, bios_6_scratch;
949 1010
950 if (rdev->family >= CHIP_R600) { 1011 if (rdev->family >= CHIP_R600) {
951 bios_2_scratch = RREG32(R600_BIOS_0_SCRATCH); 1012 bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
952 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH); 1013 bios_6_scratch = RREG32(R600_BIOS_6_SCRATCH);
953 } else { 1014 } else {
954 bios_2_scratch = RREG32(RADEON_BIOS_0_SCRATCH); 1015 bios_2_scratch = RREG32(RADEON_BIOS_2_SCRATCH);
955 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH); 1016 bios_6_scratch = RREG32(RADEON_BIOS_6_SCRATCH);
956 } 1017 }
957 1018