aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSlava Grigorev <slava.grigorev@amd.com>2016-01-26 17:35:57 -0500
committerAlex Deucher <alexander.deucher@amd.com>2016-01-27 12:50:25 -0500
commitfe6fc1f132b4300c1f6defd43a5d673eb60a820d (patch)
tree8fec06b5d46d630d6887efc148f0b5d9b90dd4f5
parenta64c9dab1c4d05c87ec8a1cb9b48915816462143 (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.c10
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h5
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c37
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
1109union 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
1117static 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
1109bool radeon_atom_get_clock_info(struct drm_device *dev) 1134bool 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
1275union 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
1283bool radeon_atombios_sideport_present(struct radeon_device *rdev) 1304bool 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;