diff options
author | Slava Grigorev <slava.grigorev@amd.com> | 2016-01-26 17:35:57 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-01-27 12:50:25 -0500 |
commit | fe6fc1f132b4300c1f6defd43a5d673eb60a820d (patch) | |
tree | 8fec06b5d46d630d6887efc148f0b5d9b90dd4f5 | |
parent | a64c9dab1c4d05c87ec8a1cb9b48915816462143 (diff) |
drm/radeon: fix DP audio support for APU with DCE4.1 display engine
Properly setup the DFS divider for DP audio for DCE4.1.
Signed-off-by: Slava Grigorev <slava.grigorev@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_hdmi.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_atombios.c | 37 |
3 files changed, 44 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 9953356fe263..3cf04a2f44bb 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -289,6 +289,16 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev, | |||
289 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 289 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
290 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 290 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
291 | */ | 291 | */ |
292 | if (ASIC_IS_DCE41(rdev)) { | ||
293 | unsigned int div = (RREG32(DCE41_DENTIST_DISPCLK_CNTL) & | ||
294 | DENTIST_DPREFCLK_WDIVIDER_MASK) >> | ||
295 | DENTIST_DPREFCLK_WDIVIDER_SHIFT; | ||
296 | div = radeon_audio_decode_dfs_div(div); | ||
297 | |||
298 | if (div) | ||
299 | clock = 100 * clock / div; | ||
300 | } | ||
301 | |||
292 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); | 302 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); |
293 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); | 303 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); |
294 | } | 304 | } |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 4aa5f755572b..13b6029d65cc 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -511,6 +511,11 @@ | |||
511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc | 511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc |
512 | # define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) | 512 | # define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) |
513 | 513 | ||
514 | #define DCE41_DENTIST_DISPCLK_CNTL 0x049c | ||
515 | # define DENTIST_DPREFCLK_WDIVIDER(x) (((x) & 0x7f) << 24) | ||
516 | # define DENTIST_DPREFCLK_WDIVIDER_MASK (0x7f << 24) | ||
517 | # define DENTIST_DPREFCLK_WDIVIDER_SHIFT 24 | ||
518 | |||
514 | /* DCE 4.0 AFMT */ | 519 | /* DCE 4.0 AFMT */ |
515 | #define HDMI_CONTROL 0x7030 | 520 | #define HDMI_CONTROL 0x7030 |
516 | # define HDMI_KEEPOUT_MODE (1 << 0) | 521 | # define HDMI_KEEPOUT_MODE (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 9a9363a7e5b9..de9a2ffcf5f7 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1106,6 +1106,31 @@ union firmware_info { | |||
1106 | ATOM_FIRMWARE_INFO_V2_2 info_22; | 1106 | ATOM_FIRMWARE_INFO_V2_2 info_22; |
1107 | }; | 1107 | }; |
1108 | 1108 | ||
1109 | union igp_info { | ||
1110 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | ||
1111 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | ||
1112 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
1113 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
1114 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8; | ||
1115 | }; | ||
1116 | |||
1117 | static void radeon_atombios_get_dentist_vco_freq(struct radeon_device *rdev) | ||
1118 | { | ||
1119 | struct radeon_mode_info *mode_info = &rdev->mode_info; | ||
1120 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | ||
1121 | union igp_info *igp_info; | ||
1122 | u8 frev, crev; | ||
1123 | u16 data_offset; | ||
1124 | |||
1125 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | ||
1126 | &frev, &crev, &data_offset)) { | ||
1127 | igp_info = (union igp_info *)(mode_info->atom_context->bios + | ||
1128 | data_offset); | ||
1129 | rdev->clock.vco_freq = | ||
1130 | le32_to_cpu(igp_info->info_6.ulDentistVCOFreq); | ||
1131 | } | ||
1132 | } | ||
1133 | |||
1109 | bool radeon_atom_get_clock_info(struct drm_device *dev) | 1134 | bool radeon_atom_get_clock_info(struct drm_device *dev) |
1110 | { | 1135 | { |
1111 | struct radeon_device *rdev = dev->dev_private; | 1136 | struct radeon_device *rdev = dev->dev_private; |
@@ -1260,6 +1285,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
1260 | if (ASIC_IS_DCE8(rdev)) | 1285 | if (ASIC_IS_DCE8(rdev)) |
1261 | rdev->clock.vco_freq = | 1286 | rdev->clock.vco_freq = |
1262 | le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq); | 1287 | le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq); |
1288 | else if (ASIC_IS_DCE5(rdev)) | ||
1289 | rdev->clock.vco_freq = rdev->clock.current_dispclk; | ||
1290 | else if (ASIC_IS_DCE41(rdev)) | ||
1291 | radeon_atombios_get_dentist_vco_freq(rdev); | ||
1263 | else | 1292 | else |
1264 | rdev->clock.vco_freq = rdev->clock.current_dispclk; | 1293 | rdev->clock.vco_freq = rdev->clock.current_dispclk; |
1265 | 1294 | ||
@@ -1272,14 +1301,6 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
1272 | return false; | 1301 | return false; |
1273 | } | 1302 | } |
1274 | 1303 | ||
1275 | union igp_info { | ||
1276 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | ||
1277 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | ||
1278 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
1279 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
1280 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8; | ||
1281 | }; | ||
1282 | |||
1283 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1304 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
1284 | { | 1305 | { |
1285 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1306 | struct radeon_mode_info *mode_info = &rdev->mode_info; |