aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/dce6_afmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/dce6_afmt.c')
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c66
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
105void 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
105void dce6_afmt_write_speaker_allocation(struct drm_encoder *encoder) 148void 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