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
This commit is contained in:
Родитель
a64c9dab1c
Коммит
fe6fc1f132
|
@ -289,6 +289,16 @@ void dce4_dp_audio_set_dto(struct radeon_device *rdev,
|
|||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
if (ASIC_IS_DCE41(rdev)) {
|
||||
unsigned int div = (RREG32(DCE41_DENTIST_DISPCLK_CNTL) &
|
||||
DENTIST_DPREFCLK_WDIVIDER_MASK) >>
|
||||
DENTIST_DPREFCLK_WDIVIDER_SHIFT;
|
||||
div = radeon_audio_decode_dfs_div(div);
|
||||
|
||||
if (div)
|
||||
clock = 100 * clock / div;
|
||||
}
|
||||
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
|
||||
}
|
||||
|
|
|
@ -511,6 +511,11 @@
|
|||
#define DCCG_AUDIO_DTO1_CNTL 0x05cc
|
||||
# define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3)
|
||||
|
||||
#define DCE41_DENTIST_DISPCLK_CNTL 0x049c
|
||||
# define DENTIST_DPREFCLK_WDIVIDER(x) (((x) & 0x7f) << 24)
|
||||
# define DENTIST_DPREFCLK_WDIVIDER_MASK (0x7f << 24)
|
||||
# define DENTIST_DPREFCLK_WDIVIDER_SHIFT 24
|
||||
|
||||
/* DCE 4.0 AFMT */
|
||||
#define HDMI_CONTROL 0x7030
|
||||
# define HDMI_KEEPOUT_MODE (1 << 0)
|
||||
|
|
|
@ -1106,6 +1106,31 @@ union firmware_info {
|
|||
ATOM_FIRMWARE_INFO_V2_2 info_22;
|
||||
};
|
||||
|
||||
union igp_info {
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO info;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
|
||||
};
|
||||
|
||||
static void radeon_atombios_get_dentist_vco_freq(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
|
||||
union igp_info *igp_info;
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
igp_info = (union igp_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
rdev->clock.vco_freq =
|
||||
le32_to_cpu(igp_info->info_6.ulDentistVCOFreq);
|
||||
}
|
||||
}
|
||||
|
||||
bool radeon_atom_get_clock_info(struct drm_device *dev)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -1260,6 +1285,10 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
|
|||
if (ASIC_IS_DCE8(rdev))
|
||||
rdev->clock.vco_freq =
|
||||
le32_to_cpu(firmware_info->info_22.ulGPUPLL_OutputFreq);
|
||||
else if (ASIC_IS_DCE5(rdev))
|
||||
rdev->clock.vco_freq = rdev->clock.current_dispclk;
|
||||
else if (ASIC_IS_DCE41(rdev))
|
||||
radeon_atombios_get_dentist_vco_freq(rdev);
|
||||
else
|
||||
rdev->clock.vco_freq = rdev->clock.current_dispclk;
|
||||
|
||||
|
@ -1272,14 +1301,6 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
|
|||
return false;
|
||||
}
|
||||
|
||||
union igp_info {
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO info;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
|
||||
struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
|
||||
};
|
||||
|
||||
bool radeon_atombios_sideport_present(struct radeon_device *rdev)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
|
|
Загрузка…
Ссылка в новой задаче