Patch "drm/radeon: rework audio detect (v4)" has been added to the 4.1-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
drm/radeon: rework audio detect (v4)
to the 4.1-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
drm-radeon-rework-audio-detect-v4.patch
and it can be found in the queue-4.1 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
d0ea397e22f9ad0113c1dbdaab14eded050472ebMon Sep 17 00:00:00 2001
From: Alex Deucher <[email protected]>
Date: Thu, 23 Jul 2015 10:01:09 -0400
Subject: drm/radeon: rework audio detect (v4)
From: Alex Deucher <[email protected]>
commit d0ea397e22f9ad0113c1dbdaab14eded050472eb upstream.
1. Always assign audio function pointers even if the display does not support audio. We need to properly disable the audio stream when when using a non-audio capable monitor. Fixes purple line on some hdmi monitors.
2. Check if a pin is in use by another encoder before disabling it.
v2: make sure we've fetched the edid before checking audio and
look up the encoder before calling audio_detect since connector->encoder may not be assigned yet. Separate pin and afmt. They are allocated at different times and have no dependency on eachother.
v3: fix connector fetching in encoder functions
v4: fix missed dig->pin check in dce6_afmt_write_latency_fields
bugs:
https://bugzilla.kernel.org/show_bug.cgi?id=93701
https://bugzilla.redhat.com/show_bug.cgi?id=1236337
https://bugs.freedesktop.org/show_bug.cgi?id=91041
--- drivers/gpu/drm/radeon/dce6_afmt.c | 62 +++++------- drivers/gpu/drm/radeon/radeon_audio.c | 143 ++++++++++++----------------- drivers/gpu/drm/radeon/radeon_audio.h | 3 drivers/gpu/drm/radeon/radeon_connectors.c | 18 ++- drivers/gpu/drm/radeon/radeon_mode.h | 2 5 files changed, 105 insertions(+), 123 deletions(-)
drivers/gpu/drm/radeon/dce6_afmt.c +28 -34
@@ -93,30 +93,26 @@ void dce6_afmt_select_pin(struct drm_encstruct radeon_device *rdev = encoder->dev->dev_private;struct radeon_encoder *radeon_encoder =to_radeon_encoder (encoder);struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -u32 offset; -if (!dig || !dig->afmt || !dig->afmt->pin) +if (!dig || !dig->afmt || !dig->pin)return ; - offset = dig->afmt->offset; - -WREG32 (AFMT_AUDIO_SRC_CONTROL + offset, -AFMT_AUDIO_SRC_SELECT (dig->afmt->pin->id)); +WREG32 (AFMT_AUDIO_SRC_CONTROL + dig->afmt->offset, +AFMT_AUDIO_SRC_SELECT (dig->pin->id)); }void dce6_afmt_write_latency_fields (struct drm_encoder *encoder, -struct drm_connector *connector,struct drm_display_mode *mode) +struct drm_connector *connector, +struct drm_display_mode *mode) {struct radeon_device *rdev = encoder->dev->dev_private;struct radeon_encoder *radeon_encoder =to_radeon_encoder (encoder);struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -u32 tmp =0 , offset; +u32 tmp =0 ; -if (!dig || !dig->afmt || !dig->afmt->pin) +if (!dig || !dig->afmt || !dig->pin)return ; - offset = dig->afmt->pin->offset; -if (mode->flags &DRM_MODE_FLAG_INTERLACE ) {if (connector->latency_present[1 ]) tmp = VIDEO_LIPSYNC(connector->video_latency[1]) |
@@ -130,24 +126,24 @@ void dce6_afmt_write_latency_fields(struelse tmp =VIDEO_LIPSYNC (0 ) |AUDIO_LIPSYNC (0 ); } -WREG32_ENDPOINT (offset,AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC , tmp); +WREG32_ENDPOINT (dig->pin->offset, +AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC , tmp); }void dce6_afmt_hdmi_write_speaker_allocation (struct drm_encoder *encoder, -u8 *sadb,int sad_count) +u8 *sadb,int sad_count) {struct radeon_device *rdev = encoder->dev->dev_private;struct radeon_encoder *radeon_encoder =to_radeon_encoder (encoder);struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -u32 offset, tmp; +u32 tmp; -if (!dig || !dig->afmt || !dig->afmt->pin) +if (!dig || !dig->afmt || !dig->pin)return ; - offset = dig->afmt->pin->offset; -/* program the speaker allocation */ - tmp =RREG32_ENDPOINT (offset,AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER ); + tmp =RREG32_ENDPOINT (dig->pin->offset, +AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER ); tmp &= ~(DP_CONNECTION |SPEAKER_ALLOCATION_MASK );/* set HDMI mode */ tmp |=HDMI_CONNECTION ;
@@ -155,24 +151,24 @@ void dce6_afmt_hdmi_write_speaker_alloca tmp |=SPEAKER_ALLOCATION (sadb[0 ]); else tmp |= SPEAKER_ALLOCATION(5); /* stereo */ -WREG32_ENDPOINT (offset,AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER , tmp); +WREG32_ENDPOINT (dig->pin->offset, +AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER , tmp); }void dce6_afmt_dp_write_speaker_allocation (struct drm_encoder *encoder, -u8 *sadb,int sad_count) +u8 *sadb,int sad_count) {struct radeon_device *rdev = encoder->dev->dev_private;struct radeon_encoder *radeon_encoder =to_radeon_encoder (encoder);struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; -u32 offset, tmp; +u32 tmp; -if (!dig || !dig->afmt || !dig->afmt->pin) +if (!dig || !dig->afmt || !dig->pin)return ; - offset = dig->afmt->pin->offset; -/* program the speaker allocation */ - tmp =RREG32_ENDPOINT (offset,AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER ); + tmp =RREG32_ENDPOINT (dig->pin->offset, +AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER ); tmp &= ~(HDMI_CONNECTION |SPEAKER_ALLOCATION_MASK );/* set DP mode */ tmp |=DP_CONNECTION ;
@@ -180,13 +176,13 @@ void dce6_afmt_dp_write_speaker_allocati tmp |=SPEAKER_ALLOCATION (sadb[0 ]); else tmp |= SPEAKER_ALLOCATION(5); /* stereo */ -WREG32_ENDPOINT (offset,AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER , tmp); +WREG32_ENDPOINT (dig->pin->offset, +AZ_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER , tmp); }void dce6_afmt_write_sad_regs (struct drm_encoder *encoder, -struct cea_sad *sads,int sad_count) +struct cea_sad *sads,int sad_count) { -u32 offset;int i;struct radeon_encoder *radeon_encoder =to_radeon_encoder (encoder);struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
@@ -206,11 +202,9 @@ void dce6_afmt_write_sad_regs(struct drm { AZ_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR13, HDMI_AUDIO_CODING_TYPE_WMA_PRO }, }; -if (!dig || !dig->afmt || !dig->afmt->pin) +if (!dig || !dig->afmt || !dig->pin)return ; - offset = dig->afmt->pin->offset; -for (i =0 ; i <ARRAY_SIZE (eld_reg_to_type); i++) {u32 value =0 ;u8 stereo_freqs =0 ;
@@ -237,7 +231,7 @@ void dce6_afmt_write_sad_regs(struct drm value |=SUPPORTED_FREQUENCIES_STEREO (stereo_freqs); -WREG32_ENDPOINT (offset, eld_reg_to_type[i][0 ], value); +WREG32_ENDPOINT (dig->pin->offset, eld_reg_to_type[i][0 ], value); } }
@@ -253,7 +247,7 @@ void dce6_audio_enable(struct radeon_dev }void dce6_hdmi_audio_set_dto (struct radeon_device *rdev, -struct radeon_crtc *crtc,unsigned int clock) +struct radeon_crtc *crtc,unsigned int clock) {/* Two dtos; generally use dto0 for HDMI */ u32 value =0 ;
@@ -272,7 +266,7 @@ void dce6_hdmi_audio_set_dto(struct rade }void dce6_dp_audio_set_dto (struct radeon_device *rdev, -struct radeon_crtc *crtc,unsigned int clock) +struct radeon_crtc *crtc,unsigned int clock) {/* Two dtos; generally use dto1 for DP */ u32 value =0 ;
drivers/gpu/drm/radeon/radeon_audio.c +60 -83
248 lines not on this page · raw message
drivers/gpu/drm/radeon/radeon_audio.h +2 -1
@@ -68,7 +68,8 @@ struct radeon_audio_funcsint radeon_audio_init (struct radeon_device *rdev);void radeon_audio_detect (struct drm_connector *connector, -enum drm_connector_status status); +struct drm_encoder *encoder, +enum drm_connector_status status);u32 radeon_audio_endpoint_rreg (struct radeon_device *rdev,u32 offset,u32 reg); void radeon_audio_endpoint_wreg(struct radeon_device *rdev,
drivers/gpu/drm/radeon/radeon_connectors.c +14 -4
@@ -1379,8 +1379,16 @@ out:/* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs (connector, ret); -if (radeon_audio !=0 ) -radeon_audio_detect (connector, ret); +if ((radeon_audio !=0 ) && radeon_connector->use_digital) { +const struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + + encoder = connector_funcs->best_encoder (connector); +if (encoder && (encoder->encoder_type ==DRM_MODE_ENCODER_TMDS )) { +radeon_connector_get_edid (connector); +radeon_audio_detect (connector, encoder, ret); + } + } exit:pm_runtime_mark_last_busy (connector->dev->dev);
@@ -1717,8 +1725,10 @@ radeon_dp_detect(struct drm_connector *cradeon_connector_update_scratch_regs (connector, ret); -if (radeon_audio !=0 ) -radeon_audio_detect (connector, ret); +if ((radeon_audio !=0 ) && encoder) { +radeon_connector_get_edid (connector); +radeon_audio_detect (connector, encoder, ret); + } out:pm_runtime_mark_last_busy (connector->dev->dev);
drivers/gpu/drm/radeon/radeon_mode.h +1 -1
@@ -237,7 +237,6 @@ struct radeon_afmt {int offset;bool last_buffer_filled_status;int id; -struct r600_audio_pin *pin; };struct radeon_mode_info {
@@ -439,6 +438,7 @@ struct radeon_encoder_atom_dig {uint8_t backlight_level;int panel_mode;struct radeon_afmt *afmt; +struct r600_audio_pin *pin;int active_mst_links; };
Patches currently in stable-queue which might be from [email protected] are
queue-4.1/drm-radeon-combios-add-some-validation-of-lvds-values.patch queue-4.1/drm-radeon-rework-audio-detect-v4.patch