radeon/audio: consolidate audio_set_dto() functions
Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Slava Grigorev <slava.grigorev@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
7991d66501
commit
a85d682a65
|
@ -113,6 +113,60 @@ void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder,
|
|||
}
|
||||
}
|
||||
|
||||
void dce3_2_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
struct radeon_encoder *radeon_encoder;
|
||||
struct radeon_encoder_atom_dig *dig;
|
||||
unsigned int max_ratio = clock / 24000;
|
||||
u32 dto_phase;
|
||||
u32 wallclock_ratio;
|
||||
u32 dto_cntl;
|
||||
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
radeon_encoder = to_radeon_encoder(crtc->encoder);
|
||||
dig = radeon_encoder->enc_priv;
|
||||
|
||||
if (!dig)
|
||||
return;
|
||||
|
||||
if (max_ratio >= 8) {
|
||||
dto_phase = 192 * 1000;
|
||||
wallclock_ratio = 3;
|
||||
} else if (max_ratio >= 4) {
|
||||
dto_phase = 96 * 1000;
|
||||
wallclock_ratio = 2;
|
||||
} else if (max_ratio >= 2) {
|
||||
dto_phase = 48 * 1000;
|
||||
wallclock_ratio = 1;
|
||||
} else {
|
||||
dto_phase = 24 * 1000;
|
||||
wallclock_ratio = 0;
|
||||
}
|
||||
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
if (dig->dig_encoder == 0) {
|
||||
dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
||||
} else {
|
||||
dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* update the info frames with the data from the current display mode
|
||||
*/
|
||||
|
@ -139,7 +193,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m
|
|||
dig->afmt->pin = radeon_audio_get_pin(encoder);
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0);
|
||||
|
||||
r600_audio_set_dto(encoder, mode->clock);
|
||||
radeon_audio_set_dto(encoder, mode->clock);
|
||||
|
||||
WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
|
||||
HDMI0_NULL_SEND); /* send null packets when required */
|
||||
|
|
|
@ -248,3 +248,42 @@ void dce6_audio_enable(struct radeon_device *rdev,
|
|||
WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
|
||||
enable_mask ? AUDIO_ENABLED : 0);
|
||||
}
|
||||
|
||||
void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
/* Two dtos; generally use dto0 for HDMI */
|
||||
u32 value = 0;
|
||||
|
||||
if (crtc)
|
||||
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
|
||||
|
||||
WREG32(DCCG_AUDIO_DTO_SOURCE, value);
|
||||
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, 24000);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
|
||||
}
|
||||
|
||||
void dce6_dp_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
/* Two dtos; generally use dto1 for DP */
|
||||
u32 value = 0;
|
||||
value |= DCCG_AUDIO_DTO_SEL;
|
||||
|
||||
if (crtc)
|
||||
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
|
||||
|
||||
WREG32(DCCG_AUDIO_DTO_SOURCE, value);
|
||||
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, clock);
|
||||
}
|
||||
|
|
|
@ -218,54 +218,74 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder,
|
|||
frame[0xC] | (frame[0xD] << 8) | (header[1] << 24));
|
||||
}
|
||||
|
||||
static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock)
|
||||
void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
|
||||
u32 base_rate = 24000;
|
||||
u32 max_ratio = clock / base_rate;
|
||||
unsigned int max_ratio = clock / 24000;
|
||||
u32 dto_phase;
|
||||
u32 dto_modulo = clock;
|
||||
u32 wallclock_ratio;
|
||||
u32 dto_cntl;
|
||||
u32 value;
|
||||
|
||||
if (!dig || !dig->afmt)
|
||||
return;
|
||||
|
||||
if (ASIC_IS_DCE6(rdev)) {
|
||||
dto_phase = 24 * 1000;
|
||||
if (max_ratio >= 8) {
|
||||
dto_phase = 192 * 1000;
|
||||
wallclock_ratio = 3;
|
||||
} else if (max_ratio >= 4) {
|
||||
dto_phase = 96 * 1000;
|
||||
wallclock_ratio = 2;
|
||||
} else if (max_ratio >= 2) {
|
||||
dto_phase = 48 * 1000;
|
||||
wallclock_ratio = 1;
|
||||
} else {
|
||||
if (max_ratio >= 8) {
|
||||
dto_phase = 192 * 1000;
|
||||
wallclock_ratio = 3;
|
||||
} else if (max_ratio >= 4) {
|
||||
dto_phase = 96 * 1000;
|
||||
wallclock_ratio = 2;
|
||||
} else if (max_ratio >= 2) {
|
||||
dto_phase = 48 * 1000;
|
||||
wallclock_ratio = 1;
|
||||
} else {
|
||||
dto_phase = 24 * 1000;
|
||||
wallclock_ratio = 0;
|
||||
}
|
||||
dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
|
||||
dto_phase = 24 * 1000;
|
||||
wallclock_ratio = 0;
|
||||
}
|
||||
|
||||
/* XXX two dtos; generally use dto0 for hdmi */
|
||||
value = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
value |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
value &= ~DCCG_AUDIO_DTO1_USE_512FBR_DTO;
|
||||
WREG32(DCCG_AUDIO_DTO0_CNTL, value);
|
||||
|
||||
/* Two dtos; generally use dto0 for HDMI */
|
||||
value = 0;
|
||||
|
||||
if (crtc)
|
||||
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
|
||||
|
||||
WREG32(DCCG_AUDIO_DTO_SOURCE, value);
|
||||
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id));
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock);
|
||||
}
|
||||
|
||||
void dce4_dp_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
value = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
value |= DCCG_AUDIO_DTO1_USE_512FBR_DTO;
|
||||
WREG32(DCCG_AUDIO_DTO1_CNTL, value);
|
||||
|
||||
/* Two dtos; generally use dto1 for DP */
|
||||
value = 0;
|
||||
value |= DCCG_AUDIO_DTO_SEL;
|
||||
|
||||
if (crtc)
|
||||
value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id);
|
||||
|
||||
WREG32(DCCG_AUDIO_DTO_SOURCE, value);
|
||||
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* update the info frames with the data from the current display mode
|
||||
|
@ -302,7 +322,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
|
|||
dig->afmt->pin = radeon_audio_get_pin(encoder);
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0);
|
||||
|
||||
evergreen_audio_set_dto(encoder, mode->clock);
|
||||
radeon_audio_set_dto(encoder, mode->clock);
|
||||
|
||||
WREG32(HDMI_VBI_PACKET_CONTROL + offset,
|
||||
HDMI_NULL_SEND); /* send null packets when required */
|
||||
|
|
|
@ -509,6 +509,7 @@
|
|||
#define DCCG_AUDIO_DTO1_MODULE 0x05c4
|
||||
#define DCCG_AUDIO_DTO1_LOAD 0x05c8
|
||||
#define DCCG_AUDIO_DTO1_CNTL 0x05cc
|
||||
# define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3)
|
||||
|
||||
/* DCE 4.0 AFMT */
|
||||
#define HDMI_CONTROL 0x7030
|
||||
|
|
|
@ -380,73 +380,29 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder)
|
|||
value, ~HDMI0_AUDIO_TEST_EN);
|
||||
}
|
||||
|
||||
void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock)
|
||||
void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
|
||||
u32 base_rate = 24000;
|
||||
u32 max_ratio = clock / base_rate;
|
||||
u32 dto_phase;
|
||||
u32 dto_modulo = clock;
|
||||
u32 wallclock_ratio;
|
||||
u32 dto_cntl;
|
||||
struct radeon_encoder *radeon_encoder;
|
||||
struct radeon_encoder_atom_dig *dig;
|
||||
|
||||
if (!dig || !dig->afmt)
|
||||
if (!crtc)
|
||||
return;
|
||||
|
||||
if (max_ratio >= 8) {
|
||||
dto_phase = 192 * 1000;
|
||||
wallclock_ratio = 3;
|
||||
} else if (max_ratio >= 4) {
|
||||
dto_phase = 96 * 1000;
|
||||
wallclock_ratio = 2;
|
||||
} else if (max_ratio >= 2) {
|
||||
dto_phase = 48 * 1000;
|
||||
wallclock_ratio = 1;
|
||||
} else {
|
||||
dto_phase = 24 * 1000;
|
||||
wallclock_ratio = 0;
|
||||
}
|
||||
radeon_encoder = to_radeon_encoder(crtc->encoder);
|
||||
dig = radeon_encoder->enc_priv;
|
||||
|
||||
/* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT.
|
||||
* doesn't matter which one you use. Just use the first one.
|
||||
*/
|
||||
/* XXX two dtos; generally use dto0 for hdmi */
|
||||
/* Express [24MHz / target pixel clock] as an exact rational
|
||||
* number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE
|
||||
* is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator
|
||||
*/
|
||||
if (ASIC_IS_DCE32(rdev)) {
|
||||
if (dig->dig_encoder == 0) {
|
||||
dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl);
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
||||
} else {
|
||||
dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK;
|
||||
dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio);
|
||||
WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl);
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
|
||||
}
|
||||
if (!dig)
|
||||
return;
|
||||
|
||||
if (dig->dig_encoder == 0) {
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
||||
} else {
|
||||
/* according to the reg specs, this should DCE3.2 only, but in
|
||||
* practice it seems to cover DCE2.0/3.0/3.1 as well.
|
||||
*/
|
||||
if (dig->dig_encoder == 0) {
|
||||
WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100);
|
||||
WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */
|
||||
} else {
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
|
||||
}
|
||||
WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100);
|
||||
WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);
|
||||
WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -477,7 +433,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
|
|||
dig->afmt->pin = radeon_audio_get_pin(encoder);
|
||||
radeon_audio_enable(rdev, dig->afmt->pin, 0);
|
||||
|
||||
r600_audio_set_dto(encoder, mode->clock);
|
||||
radeon_audio_set_dto(encoder, mode->clock);
|
||||
|
||||
WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,
|
||||
HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */
|
||||
|
|
|
@ -62,6 +62,18 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder,
|
|||
struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev);
|
||||
struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev);
|
||||
void dce6_afmt_select_pin(struct drm_encoder *encoder);
|
||||
void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
void dce3_2_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
void dce4_dp_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
void dce6_dp_audio_set_dto(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
|
||||
static const u32 pin_offsets[7] =
|
||||
{
|
||||
|
@ -85,6 +97,12 @@ static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset,
|
|||
WREG32(reg, v);
|
||||
}
|
||||
|
||||
static struct radeon_audio_basic_funcs r600_funcs = {
|
||||
.endpoint_rreg = radeon_audio_rreg,
|
||||
.endpoint_wreg = radeon_audio_wreg,
|
||||
.enable = r600_audio_enable,
|
||||
};
|
||||
|
||||
static struct radeon_audio_basic_funcs dce32_funcs = {
|
||||
.endpoint_rreg = radeon_audio_rreg,
|
||||
.endpoint_wreg = radeon_audio_wreg,
|
||||
|
@ -103,16 +121,23 @@ static struct radeon_audio_basic_funcs dce6_funcs = {
|
|||
.enable = dce6_audio_enable,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs r600_hdmi_funcs = {
|
||||
.get_pin = r600_audio_get_pin,
|
||||
.set_dto = r600_hdmi_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce32_hdmi_funcs = {
|
||||
.get_pin = r600_audio_get_pin,
|
||||
.write_sad_regs = dce3_2_afmt_write_sad_regs,
|
||||
.write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation,
|
||||
.set_dto = dce3_2_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce32_dp_funcs = {
|
||||
.get_pin = r600_audio_get_pin,
|
||||
.write_sad_regs = dce3_2_afmt_write_sad_regs,
|
||||
.write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation,
|
||||
.set_dto = dce3_2_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce4_hdmi_funcs = {
|
||||
|
@ -120,6 +145,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = {
|
|||
.write_sad_regs = evergreen_hdmi_write_sad_regs,
|
||||
.write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation,
|
||||
.write_latency_fields = dce4_afmt_write_latency_fields,
|
||||
.set_dto = dce4_hdmi_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce4_dp_funcs = {
|
||||
|
@ -127,6 +153,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = {
|
|||
.write_sad_regs = evergreen_hdmi_write_sad_regs,
|
||||
.write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation,
|
||||
.write_latency_fields = dce4_afmt_write_latency_fields,
|
||||
.set_dto = dce4_dp_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce6_hdmi_funcs = {
|
||||
|
@ -135,6 +162,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = {
|
|||
.write_sad_regs = dce6_afmt_write_sad_regs,
|
||||
.write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation,
|
||||
.write_latency_fields = dce6_afmt_write_latency_fields,
|
||||
.set_dto = dce6_hdmi_audio_set_dto,
|
||||
};
|
||||
|
||||
static struct radeon_audio_funcs dce6_dp_funcs = {
|
||||
|
@ -143,6 +171,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = {
|
|||
.write_sad_regs = dce6_afmt_write_sad_regs,
|
||||
.write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation,
|
||||
.write_latency_fields = dce6_afmt_write_latency_fields,
|
||||
.set_dto = dce6_dp_audio_set_dto,
|
||||
};
|
||||
|
||||
static void radeon_audio_interface_init(struct radeon_device *rdev)
|
||||
|
@ -155,10 +184,14 @@ static void radeon_audio_interface_init(struct radeon_device *rdev)
|
|||
rdev->audio.funcs = &dce4_funcs;
|
||||
rdev->audio.hdmi_funcs = &dce4_hdmi_funcs;
|
||||
rdev->audio.dp_funcs = &dce4_dp_funcs;
|
||||
} else {
|
||||
} else if (ASIC_IS_DCE32(rdev)) {
|
||||
rdev->audio.funcs = &dce32_funcs;
|
||||
rdev->audio.hdmi_funcs = &dce32_hdmi_funcs;
|
||||
rdev->audio.dp_funcs = &dce32_dp_funcs;
|
||||
} else {
|
||||
rdev->audio.funcs = &r600_funcs;
|
||||
rdev->audio.hdmi_funcs = &r600_hdmi_funcs;
|
||||
rdev->audio.dp_funcs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,3 +426,13 @@ void radeon_audio_fini(struct radeon_device *rdev)
|
|||
|
||||
rdev->audio.enabled = false;
|
||||
}
|
||||
|
||||
void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock)
|
||||
{
|
||||
struct radeon_device *rdev = encoder->dev->dev_private;
|
||||
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
|
||||
struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc);
|
||||
|
||||
if (radeon_encoder->audio && radeon_encoder->audio->set_dto)
|
||||
radeon_encoder->audio->set_dto(rdev, crtc, clock);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ struct radeon_audio_funcs
|
|||
struct cea_sad *sads, int sad_count);
|
||||
void (*write_speaker_allocation)(struct drm_encoder *encoder,
|
||||
u8 *sadb, int sad_count);
|
||||
void (*set_dto)(struct radeon_device *rdev,
|
||||
struct radeon_crtc *crtc, unsigned int clock);
|
||||
};
|
||||
|
||||
int radeon_audio_init(struct radeon_device *rdev);
|
||||
|
@ -69,5 +71,6 @@ void radeon_audio_select_pin(struct drm_encoder *encoder);
|
|||
void radeon_audio_enable(struct radeon_device *rdev,
|
||||
struct r600_audio_pin *pin, u8 enable_mask);
|
||||
void radeon_audio_fini(struct radeon_device *rdev);
|
||||
void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -901,6 +901,16 @@
|
|||
/* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */
|
||||
#define CRTC_STATUS_FRAME_COUNT 0x6e98
|
||||
|
||||
/* Audio clocks */
|
||||
#define DCCG_AUDIO_DTO_SOURCE 0x05ac
|
||||
# define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */
|
||||
# define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */
|
||||
|
||||
#define DCCG_AUDIO_DTO0_PHASE 0x05b0
|
||||
#define DCCG_AUDIO_DTO0_MODULE 0x05b4
|
||||
#define DCCG_AUDIO_DTO1_PHASE 0x05b8
|
||||
#define DCCG_AUDIO_DTO1_MODULE 0x05bc
|
||||
|
||||
#define AFMT_AUDIO_SRC_CONTROL 0x713c
|
||||
#define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0)
|
||||
/* AFMT_AUDIO_SRC_SELECT
|
||||
|
|
Loading…
Reference in New Issue