Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 832eafaf authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: change audio enable logic



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>
parent d7eb0a09
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -278,13 +278,15 @@ static int dce6_audio_chipset_supported(struct radeon_device *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,
		       bool enable)
{
	if (!pin)
		return;

	WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOTPLUG_CONTROL,
			enable ? AUDIO_ENABLED : 0);
	DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id);
}

static const u32 pin_offsets[7] =
@@ -323,7 +325,8 @@ int dce6_audio_init(struct radeon_device *rdev)
		rdev->audio.pin[i].connected = false;
		rdev->audio.pin[i].offset = pin_offsets[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;
+15 −11
Original line number Diff line number Diff line
@@ -306,6 +306,15 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
		return;
	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);

	WREG32(HDMI_VBI_PACKET_CONTROL + offset,
@@ -409,12 +418,16 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
	WREG32(AFMT_RAMP_CONTROL1 + offset, 0x007FFFFF);
	WREG32(AFMT_RAMP_CONTROL2 + 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)
{
	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;

@@ -427,15 +440,6 @@ void evergreen_hdmi_enable(struct drm_encoder *encoder, bool enable)
	if (!enable && !dig->afmt->enabled)
		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;

	DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",
+8 −6
Original line number Diff line number Diff line
@@ -142,12 +142,15 @@ void r600_audio_update_hdmi(struct work_struct *work)
}

/* 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,
		       bool enable)
{
	u32 value = 0;

	if (!pin)
		return;

	if (ASIC_IS_DCE4(rdev)) {
		if (enable) {
			value |= 0x81000000; /* Required to enable audio */
@@ -158,7 +161,6 @@ static void r600_audio_enable(struct radeon_device *rdev,
		WREG32_P(R600_AUDIO_ENABLE,
			 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)
	rdev->audio.pin[0].status_bits = 0;
	rdev->audio.pin[0].category_code = 0;
	rdev->audio.pin[0].id = 0;

	r600_audio_enable(rdev, &rdev->audio.pin[0], true);
	/* disable audio.  it will be set up later */
	r600_audio_enable(rdev, &rdev->audio.pin[0], false);

	return 0;
}
+7 −5
Original line number Diff line number Diff line
@@ -460,6 +460,10 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
		return;
	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);

	WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
@@ -531,6 +535,9 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
	WREG32(HDMI0_RAMP_CONTROL3 + offset, 0x00000001);

	r600_hdmi_audio_workaround(encoder);

	/* enable audio after to setting up hw */
	r600_audio_enable(rdev, dig->afmt->pin, true);
}

/*
@@ -651,11 +658,6 @@ void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)
	if (!enable && !dig->afmt->enabled)
		return;

	if (enable)
		dig->afmt->pin = r600_audio_get_pin(rdev);
	else
		dig->afmt->pin = NULL;

	/* Older chipsets require setting HDMI and routing manually */
	if (!ASIC_IS_DCE3(rdev)) {
		if (enable)
+6 −0
Original line number Diff line number Diff line
@@ -2747,6 +2747,12 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
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 *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