diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/dce6_afmt.c')
-rw-r--r-- | drivers/gpu/drm/radeon/dce6_afmt.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 9fcd338c0fcf..009f46e0ce72 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -102,6 +102,49 @@ void dce6_afmt_select_pin(struct drm_encoder *encoder) | |||
102 | AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); | 102 | AFMT_AUDIO_SRC_SELECT(dig->afmt->pin->id)); |
103 | } | 103 | } |
104 | 104 | ||
105 | void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | ||
106 | struct drm_display_mode *mode) | ||
107 | { | ||
108 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
109 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
110 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
111 | struct drm_connector *connector; | ||
112 | struct radeon_connector *radeon_connector = NULL; | ||
113 | u32 tmp = 0, offset; | ||
114 | |||
115 | if (!dig->afmt->pin) | ||
116 | return; | ||
117 | |||
118 | offset = dig->afmt->pin->offset; | ||
119 | |||
120 | list_for_each_entry(connector, &encoder->dev->mode_config.connector_list, head) { | ||
121 | if (connector->encoder == encoder) { | ||
122 | radeon_connector = to_radeon_connector(connector); | ||
123 | break; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | if (!radeon_connector) { | ||
128 | DRM_ERROR("Couldn't find encoder's connector\n"); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) { | ||
133 | if (connector->latency_present[1]) | ||
134 | tmp = VIDEO_LIPSYNC(connector->video_latency[1]) | | ||
135 | AUDIO_LIPSYNC(connector->audio_latency[1]); | ||
136 | else | ||
137 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
138 | } else { | ||
139 | if (connector->latency_present[0]) | ||
140 | tmp = VIDEO_LIPSYNC(connector->video_latency[0]) | | ||
141 | AUDIO_LIPSYNC(connector->audio_latency[0]); | ||
142 | else | ||
143 | tmp = VIDEO_LIPSYNC(255) | AUDIO_LIPSYNC(255); | ||
144 | } | ||
145 | WREG32_ENDPOINT(offset, AZ_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC, tmp); | ||
146 | } | ||
147 | |||
105 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | 148 | void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) |
106 | { | 149 | { |
107 | struct radeon_device *rdev = encoder->dev->dev_private; | 150 | struct radeon_device *rdev = encoder->dev->dev_private; |
@@ -113,9 +156,6 @@ void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) | |||
113 | u8 *sadb; | 156 | u8 *sadb; |
114 | int sad_count; | 157 | int sad_count; |
115 | 158 | ||
116 | /* XXX: setting this register causes hangs on some asics */ | ||
117 | return; | ||
118 | |||
119 | if (!dig->afmt->pin) | 159 | if (!dig->afmt->pin) |
120 | return; | 160 | return; |
121 | 161 | ||
@@ -201,20 +241,30 @@ void dce6_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
201 | 241 | ||
202 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { | 242 | for (i = 0; i < ARRAY_SIZE(eld_reg_to_type); i++) { |
203 | u32 value = 0; | 243 | u32 value = 0; |
244 | u8 stereo_freqs = 0; | ||
245 | int max_channels = -1; | ||
204 | int j; | 246 | int j; |
205 | 247 | ||
206 | for (j = 0; j < sad_count; j++) { | 248 | for (j = 0; j < sad_count; j++) { |
207 | struct cea_sad *sad = &sads[j]; | 249 | struct cea_sad *sad = &sads[j]; |
208 | 250 | ||
209 | if (sad->format == eld_reg_to_type[i][1]) { | 251 | if (sad->format == eld_reg_to_type[i][1]) { |
210 | value = MAX_CHANNELS(sad->channels) | | 252 | if (sad->channels > max_channels) { |
211 | DESCRIPTOR_BYTE_2(sad->byte2) | | 253 | value = MAX_CHANNELS(sad->channels) | |
212 | SUPPORTED_FREQUENCIES(sad->freq); | 254 | DESCRIPTOR_BYTE_2(sad->byte2) | |
255 | SUPPORTED_FREQUENCIES(sad->freq); | ||
256 | max_channels = sad->channels; | ||
257 | } | ||
258 | |||
213 | if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) | 259 | if (sad->format == HDMI_AUDIO_CODING_TYPE_PCM) |
214 | value |= SUPPORTED_FREQUENCIES_STEREO(sad->freq); | 260 | stereo_freqs |= sad->freq; |
215 | break; | 261 | else |
262 | break; | ||
216 | } | 263 | } |
217 | } | 264 | } |
265 | |||
266 | value |= SUPPORTED_FREQUENCIES_STEREO(stereo_freqs); | ||
267 | |||
218 | WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); | 268 | WREG32_ENDPOINT(offset, eld_reg_to_type[i][0], value); |
219 | } | 269 | } |
220 | 270 | ||