Commit d6bb21f4 authored by Alex Deucher's avatar Alex Deucher Committed by Jiri Slaby

drm/radeon: change audio enable logic

commit 832eafaf upstream.

Disable audio around audio hw setup.  This may avoid
hangs on certain asics.
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent 929476d0
No related merge requests found
...@@ -226,13 +226,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev) ...@@ -226,13 +226,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *rdev)
return !ASIC_IS_NODCE(rdev); return !ASIC_IS_NODCE(rdev);
} }
static void dce6_audio_enable(struct radeon_device *rdev, void dce6_audio_enable(struct radeon_device *rdev,
struct r600_audio_pin *pin, struct r600_audio_pin *pin,
bool enable) bool enable)
{ {
if (!pin)
return;
WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL, WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL,
enable ? AUDIO_ENABLED : 0); enable ? AUDIO_ENABLED : 0);
DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id);
} }
static const u32 pin_offsets[7] = static const u32 pin_offsets[7] =
...@@ -269,7 +271,8 @@ int dce6_audio_init(struct radeon_device *rdev) ...@@ -269,7 +271,8 @@ int dce6_audio_init(struct radeon_device *rdev)
rdev->audio.pin[i].connected = false; rdev->audio.pin[i].connected = false;
rdev->audio.pin[i].offset = pin_offsets[i]; rdev->audio.pin[i].offset = pin_offsets[i];
rdev->audio.pin[i].id = i; rdev->audio.pin[i].id = i;
dce6_audio_enable(rdev, &rdev->audio.pin[i], true); /* disable audio. it will be set up later */
dce6_audio_enable(rdev, &rdev->audio.pin[i], false);
} }
return 0; return 0;
......
...@@ -257,6 +257,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode ...@@ -257,6 +257,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
return; return;
offset = dig->afmt->offset; offset = dig->afmt->offset;
/* disable audio prior to setting up hw */
if (ASIC_IS_DCE6(rdev)) {
dig->afmt->pin = dce6_audio_get_pin(rdev);
dce6_audio_enable(rdev, dig->afmt->pin, false);
} else {
dig->afmt->pin = r600_audio_get_pin(rdev);
r600_audio_enable(rdev, dig->afmt->pin, false);
}
evergreen_audio_set_dto(encoder, mode->clock); evergreen_audio_set_dto(encoder, mode->clock);
WREG32(HDMI_VBI_PACKET_CONTROL + offset, WREG32(HDMI_VBI_PACKET_CONTROL + offset,
...@@ -358,12 +367,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode ...@@ -358,12 +367,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF); WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001); WREG32(AFMT_RAMP_CONTROL2 + offset, 0x00000001);
WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001); WREG32(AFMT_RAMP_CONTROL3 + offset, 0x00000001);
/* enable audio after to setting up hw */
if (ASIC_IS_DCE6(rdev))
dce6_audio_enable(rdev, dig->afmt->pin, true);
else
r600_audio_enable(rdev, dig->afmt->pin, true);
} }
void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
{ {
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 *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
...@@ -376,15 +389,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable) ...@@ -376,15 +389,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
if (!enable && !dig->afmt->enabled) if (!enable && !dig->afmt->enabled)
return; return;
if (enable) {
if (ASIC_IS_DCE6(rdev))
dig->afmt->pin = dce6_audio_get_pin(rdev);
else
dig->afmt->pin = r600_audio_get_pin(rdev);
} else {
dig->afmt->pin = NULL;
}
dig->afmt->enabled = enable; dig->afmt->enabled = enable;
DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n", DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
......
...@@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work) ...@@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work)
} }
/* enable the audio stream */ /* enable the audio stream */
static void r600_audio_enable(struct radeon_device *rdev, void r600_audio_enable(struct radeon_device *rdev,
struct r600_audio_pin *pin, struct r600_audio_pin *pin,
bool enable) bool enable)
{ {
u32 value = 0; u32 value = 0;
if (!pin)
return;
if (ASIC_IS_DCE4(rdev)) { if (ASIC_IS_DCE4(rdev)) {
if (enable) { if (enable) {
value |= 0x81000000; /* Required to enable audio */ value |= 0x81000000; /* Required to enable audio */
...@@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev, ...@@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev,
WREG32_P(R600_AUDIO_ENABLE, WREG32_P(R600_AUDIO_ENABLE,
enable ? 0x81000000 : 0x0, ~0x81000000); enable ? 0x81000000 : 0x0, ~0x81000000);
} }
DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id);
} }
/* /*
...@@ -178,8 +180,8 @@ int r600_audio_init(struct radeon_device *rdev) ...@@ -178,8 +180,8 @@ int r600_audio_init(struct radeon_device *rdev)
rdev->audio.pin[0].status_bits = 0; rdev->audio.pin[0].status_bits = 0;
rdev->audio.pin[0].category_code = 0; rdev->audio.pin[0].category_code = 0;
rdev->audio.pin[0].id = 0; rdev->audio.pin[0].id = 0;
/* disable audio. it will be set up later */
r600_audio_enable(rdev, &rdev->audio.pin[0], true); r600_audio_enable(rdev, &rdev->audio.pin[0], false);
return 0; return 0;
} }
......
...@@ -446,6 +446,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod ...@@ -446,6 +446,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
return; return;
offset = dig->afmt->offset; offset = dig->afmt->offset;
/* disable audio prior to setting up hw */
dig->afmt->pin = r600_audio_get_pin(rdev);
r600_audio_enable(rdev, dig->afmt->pin, false);
r600_audio_set_dto(encoder, mode->clock); r600_audio_set_dto(encoder, mode->clock);
WREG32(HDMI0_VBI_PACKET_CONTROL + offset, WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
...@@ -517,6 +521,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod ...@@ -517,6 +521,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001); WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);
r600_hdmi_audio_workaround(encoder); r600_hdmi_audio_workaround(encoder);
/* enable audio after to setting up hw */
r600_audio_enable(rdev, dig->afmt->pin, true);
} }
/* /*
...@@ -637,11 +644,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable) ...@@ -637,11 +644,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
if (!enable && !dig->afmt->enabled) if (!enable && !dig->afmt->enabled)
return; return;
if (enable)
dig->afmt->pin = r600_audio_get_pin(rdev);
else
dig->afmt->pin = NULL;
/* Older chipsets require setting HDMI and routing manually */ /* Older chipsets require setting HDMI and routing manually */
if (!ASIC_IS_DCE3(rdev)) { if (!ASIC_IS_DCE3(rdev)) {
if (enable) if (enable)
......
...@@ -2717,6 +2717,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, ...@@ -2717,6 +2717,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
void r600_audio_update_hdmi(struct work_struct *work); void r600_audio_update_hdmi(struct work_struct *work);
struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev); struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev);
struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev); struct r600_audio_pin *dce6_audio_get_pin(struct radeon_device *rdev);
void r600_audio_enable(struct radeon_device *rdev,
struct r600_audio_pin *pin,
bool enable);
void dce6_audio_enable(struct radeon_device *rdev,
struct r600_audio_pin *pin,
bool enable);
/* /*
* R600 vram scratch functions * R600 vram scratch functions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment