diff options
author | Slava Grigorev <slava.grigorev@amd.com> | 2014-12-05 13:38:31 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-01-22 10:42:10 -0500 |
commit | a85d682a6578a3bd02c95afb4ef527fa0897bb69 (patch) | |
tree | f701ab1882ec512584f0b7a5b21575394c0f421c /drivers/gpu/drm | |
parent | 7991d6650117064ae1d2b215b5cbb4112711ed5e (diff) |
radeon/audio: consolidate audio_set_dto() functions
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Slava Grigorev <slava.grigorev@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/dce3_1_afmt.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/dce6_afmt.c | 39 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen_hdmi.c | 92 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/evergreend.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 80 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_audio.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_audio.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 10 |
8 files changed, 226 insertions, 100 deletions
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index f7b26592c74f..6cb2f1171539 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -113,6 +113,60 @@ void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder, | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | void dce3_2_audio_set_dto(struct radeon_device *rdev, | ||
117 | struct radeon_crtc *crtc, unsigned int clock) | ||
118 | { | ||
119 | struct radeon_encoder *radeon_encoder; | ||
120 | struct radeon_encoder_atom_dig *dig; | ||
121 | unsigned int max_ratio = clock / 24000; | ||
122 | u32 dto_phase; | ||
123 | u32 wallclock_ratio; | ||
124 | u32 dto_cntl; | ||
125 | |||
126 | if (!crtc) | ||
127 | return; | ||
128 | |||
129 | radeon_encoder = to_radeon_encoder(crtc->encoder); | ||
130 | dig = radeon_encoder->enc_priv; | ||
131 | |||
132 | if (!dig) | ||
133 | return; | ||
134 | |||
135 | if (max_ratio >= 8) { | ||
136 | dto_phase = 192 * 1000; | ||
137 | wallclock_ratio = 3; | ||
138 | } else if (max_ratio >= 4) { | ||
139 | dto_phase = 96 * 1000; | ||
140 | wallclock_ratio = 2; | ||
141 | } else if (max_ratio >= 2) { | ||
142 | dto_phase = 48 * 1000; | ||
143 | wallclock_ratio = 1; | ||
144 | } else { | ||
145 | dto_phase = 24 * 1000; | ||
146 | wallclock_ratio = 0; | ||
147 | } | ||
148 | |||
149 | /* Express [24MHz / target pixel clock] as an exact rational | ||
150 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
151 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
152 | */ | ||
153 | if (dig->dig_encoder == 0) { | ||
154 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
155 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
156 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
157 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
158 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); | ||
159 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
160 | } else { | ||
161 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
162 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
163 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
164 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
165 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); | ||
166 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
167 | } | ||
168 | } | ||
169 | |||
116 | /* | 170 | /* |
117 | * update the info frames with the data from the current display mode | 171 | * update the info frames with the data from the current display mode |
118 | */ | 172 | */ |
@@ -139,7 +193,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m | |||
139 | dig->afmt->pin = radeon_audio_get_pin(encoder); | 193 | dig->afmt->pin = radeon_audio_get_pin(encoder); |
140 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | 194 | radeon_audio_enable(rdev, dig->afmt->pin, 0); |
141 | 195 | ||
142 | r600_audio_set_dto(encoder, mode->clock); | 196 | radeon_audio_set_dto(encoder, mode->clock); |
143 | 197 | ||
144 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, | 198 | WREG32(HDMI0_VBI_PACKET_CONTROL + offset, |
145 | HDMI0_NULL_SEND); /* send null packets when required */ | 199 | HDMI0_NULL_SEND); /* send null packets when required */ |
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index c4ff60f005d2..1c870060c29b 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c | |||
@@ -248,3 +248,42 @@ void dce6_audio_enable(struct radeon_device *rdev, | |||
248 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, | 248 | WREG32_ENDPOINT(pin->offset, AZ_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, |
249 | enable_mask ? AUDIO_ENABLED : 0); | 249 | enable_mask ? AUDIO_ENABLED : 0); |
250 | } | 250 | } |
251 | |||
252 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
253 | struct radeon_crtc *crtc, unsigned int clock) | ||
254 | { | ||
255 | /* Two dtos; generally use dto0 for HDMI */ | ||
256 | u32 value = 0; | ||
257 | |||
258 | if (crtc) | ||
259 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); | ||
260 | |||
261 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); | ||
262 | |||
263 | /* Express [24MHz / target pixel clock] as an exact rational | ||
264 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
265 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
266 | */ | ||
267 | WREG32(DCCG_AUDIO_DTO0_PHASE, 24000); | ||
268 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); | ||
269 | } | ||
270 | |||
271 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, | ||
272 | struct radeon_crtc *crtc, unsigned int clock) | ||
273 | { | ||
274 | /* Two dtos; generally use dto1 for DP */ | ||
275 | u32 value = 0; | ||
276 | value |= DCCG_AUDIO_DTO_SEL; | ||
277 | |||
278 | if (crtc) | ||
279 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); | ||
280 | |||
281 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); | ||
282 | |||
283 | /* Express [24MHz / target pixel clock] as an exact rational | ||
284 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
285 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
286 | */ | ||
287 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); | ||
288 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock); | ||
289 | } | ||
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index 2f29918ee49f..38b1c51cce4d 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c | |||
@@ -218,54 +218,74 @@ static void evergreen_hdmi_update_avi_infoframe(struct drm_encoder *encoder, | |||
218 | frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); | 218 | frame[0xC] | (frame[0xD] << 8) | (header[1] << 24)); |
219 | } | 219 | } |
220 | 220 | ||
221 | static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) | 221 | void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, |
222 | struct radeon_crtc *crtc, unsigned int clock) | ||
222 | { | 223 | { |
223 | struct drm_device *dev = encoder->dev; | 224 | unsigned int max_ratio = clock / 24000; |
224 | struct radeon_device *rdev = dev->dev_private; | ||
225 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
226 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
227 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); | ||
228 | u32 base_rate = 24000; | ||
229 | u32 max_ratio = clock / base_rate; | ||
230 | u32 dto_phase; | 225 | u32 dto_phase; |
231 | u32 dto_modulo = clock; | ||
232 | u32 wallclock_ratio; | 226 | u32 wallclock_ratio; |
233 | u32 dto_cntl; | 227 | u32 value; |
234 | 228 | ||
235 | if (!dig || !dig->afmt) | 229 | if (max_ratio >= 8) { |
236 | return; | 230 | dto_phase = 192 * 1000; |
237 | 231 | wallclock_ratio = 3; | |
238 | if (ASIC_IS_DCE6(rdev)) { | 232 | } else if (max_ratio >= 4) { |
239 | dto_phase = 24 * 1000; | 233 | dto_phase = 96 * 1000; |
234 | wallclock_ratio = 2; | ||
235 | } else if (max_ratio >= 2) { | ||
236 | dto_phase = 48 * 1000; | ||
237 | wallclock_ratio = 1; | ||
240 | } else { | 238 | } else { |
241 | if (max_ratio >= 8) { | 239 | dto_phase = 24 * 1000; |
242 | dto_phase = 192 * 1000; | 240 | wallclock_ratio = 0; |
243 | wallclock_ratio = 3; | ||
244 | } else if (max_ratio >= 4) { | ||
245 | dto_phase = 96 * 1000; | ||
246 | wallclock_ratio = 2; | ||
247 | } else if (max_ratio >= 2) { | ||
248 | dto_phase = 48 * 1000; | ||
249 | wallclock_ratio = 1; | ||
250 | } else { | ||
251 | dto_phase = 24 * 1000; | ||
252 | wallclock_ratio = 0; | ||
253 | } | ||
254 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
255 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
256 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
257 | } | 241 | } |
258 | 242 | ||
259 | /* XXX two dtos; generally use dto0 for hdmi */ | 243 | value = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; |
244 | value |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
245 | value &= ~DCCG_AUDIO_DTO1_USE_512FBR_DTO; | ||
246 | WREG32(DCCG_AUDIO_DTO0_CNTL, value); | ||
247 | |||
248 | /* Two dtos; generally use dto0 for HDMI */ | ||
249 | value = 0; | ||
250 | |||
251 | if (crtc) | ||
252 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); | ||
253 | |||
254 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); | ||
255 | |||
260 | /* Express [24MHz / target pixel clock] as an exact rational | 256 | /* Express [24MHz / target pixel clock] as an exact rational |
261 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 257 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE |
262 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 258 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator |
263 | */ | 259 | */ |
264 | WREG32(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL(radeon_crtc->crtc_id)); | ||
265 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | 260 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); |
266 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | 261 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock); |
267 | } | 262 | } |
268 | 263 | ||
264 | void dce4_dp_audio_set_dto(struct radeon_device *rdev, | ||
265 | struct radeon_crtc *crtc, unsigned int clock) | ||
266 | { | ||
267 | u32 value; | ||
268 | |||
269 | value = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
270 | value |= DCCG_AUDIO_DTO1_USE_512FBR_DTO; | ||
271 | WREG32(DCCG_AUDIO_DTO1_CNTL, value); | ||
272 | |||
273 | /* Two dtos; generally use dto1 for DP */ | ||
274 | value = 0; | ||
275 | value |= DCCG_AUDIO_DTO_SEL; | ||
276 | |||
277 | if (crtc) | ||
278 | value |= DCCG_AUDIO_DTO0_SOURCE_SEL(crtc->crtc_id); | ||
279 | |||
280 | WREG32(DCCG_AUDIO_DTO_SOURCE, value); | ||
281 | |||
282 | /* Express [24MHz / target pixel clock] as an exact rational | ||
283 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | ||
284 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | ||
285 | */ | ||
286 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000); | ||
287 | WREG32(DCCG_AUDIO_DTO1_MODULE, rdev->clock.max_pixel_clock * 10); | ||
288 | } | ||
269 | 289 | ||
270 | /* | 290 | /* |
271 | * update the info frames with the data from the current display mode | 291 | * update the info frames with the data from the current display mode |
@@ -302,7 +322,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode | |||
302 | dig->afmt->pin = radeon_audio_get_pin(encoder); | 322 | dig->afmt->pin = radeon_audio_get_pin(encoder); |
303 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | 323 | radeon_audio_enable(rdev, dig->afmt->pin, 0); |
304 | 324 | ||
305 | evergreen_audio_set_dto(encoder, mode->clock); | 325 | radeon_audio_set_dto(encoder, mode->clock); |
306 | 326 | ||
307 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, | 327 | WREG32(HDMI_VBI_PACKET_CONTROL + offset, |
308 | HDMI_NULL_SEND); /* send null packets when required */ | 328 | HDMI_NULL_SEND); /* send null packets when required */ |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index b066d6711b8d..ee83d2a88750 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -509,6 +509,7 @@ | |||
509 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 | 509 | #define DCCG_AUDIO_DTO1_MODULE 0x05c4 |
510 | #define DCCG_AUDIO_DTO1_LOAD 0x05c8 | 510 | #define DCCG_AUDIO_DTO1_LOAD 0x05c8 |
511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc | 511 | #define DCCG_AUDIO_DTO1_CNTL 0x05cc |
512 | # define DCCG_AUDIO_DTO1_USE_512FBR_DTO (1 << 3) | ||
512 | 513 | ||
513 | /* DCE 4.0 AFMT */ | 514 | /* DCE 4.0 AFMT */ |
514 | #define HDMI_CONTROL 0x7030 | 515 | #define HDMI_CONTROL 0x7030 |
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 1c49f4d2945a..30580d1a14f0 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c | |||
@@ -380,73 +380,29 @@ void r600_hdmi_audio_workaround(struct drm_encoder *encoder) | |||
380 | value, ~HDMI0_AUDIO_TEST_EN); | 380 | value, ~HDMI0_AUDIO_TEST_EN); |
381 | } | 381 | } |
382 | 382 | ||
383 | void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) | 383 | void r600_hdmi_audio_set_dto(struct radeon_device *rdev, |
384 | struct radeon_crtc *crtc, unsigned int clock) | ||
384 | { | 385 | { |
385 | struct drm_device *dev = encoder->dev; | 386 | struct radeon_encoder *radeon_encoder; |
386 | struct radeon_device *rdev = dev->dev_private; | 387 | struct radeon_encoder_atom_dig *dig; |
387 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
388 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | ||
389 | u32 base_rate = 24000; | ||
390 | u32 max_ratio = clock / base_rate; | ||
391 | u32 dto_phase; | ||
392 | u32 dto_modulo = clock; | ||
393 | u32 wallclock_ratio; | ||
394 | u32 dto_cntl; | ||
395 | 388 | ||
396 | if (!dig || !dig->afmt) | 389 | if (!crtc) |
397 | return; | 390 | return; |
398 | 391 | ||
399 | if (max_ratio >= 8) { | 392 | radeon_encoder = to_radeon_encoder(crtc->encoder); |
400 | dto_phase = 192 * 1000; | 393 | dig = radeon_encoder->enc_priv; |
401 | wallclock_ratio = 3; | ||
402 | } else if (max_ratio >= 4) { | ||
403 | dto_phase = 96 * 1000; | ||
404 | wallclock_ratio = 2; | ||
405 | } else if (max_ratio >= 2) { | ||
406 | dto_phase = 48 * 1000; | ||
407 | wallclock_ratio = 1; | ||
408 | } else { | ||
409 | dto_phase = 24 * 1000; | ||
410 | wallclock_ratio = 0; | ||
411 | } | ||
412 | 394 | ||
413 | /* there are two DTOs selected by DCCG_AUDIO_DTO_SELECT. | 395 | if (!dig) |
414 | * doesn't matter which one you use. Just use the first one. | 396 | return; |
415 | */ | 397 | |
416 | /* XXX two dtos; generally use dto0 for hdmi */ | 398 | if (dig->dig_encoder == 0) { |
417 | /* Express [24MHz / target pixel clock] as an exact rational | 399 | WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100); |
418 | * number (coefficient of two integer numbers. DCCG_AUDIO_DTOx_PHASE | 400 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); |
419 | * is the numerator, DCCG_AUDIO_DTOx_MODULE is the denominator | 401 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ |
420 | */ | ||
421 | if (ASIC_IS_DCE32(rdev)) { | ||
422 | if (dig->dig_encoder == 0) { | ||
423 | dto_cntl = RREG32(DCCG_AUDIO_DTO0_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
424 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
425 | WREG32(DCCG_AUDIO_DTO0_CNTL, dto_cntl); | ||
426 | WREG32(DCCG_AUDIO_DTO0_PHASE, dto_phase); | ||
427 | WREG32(DCCG_AUDIO_DTO0_MODULE, dto_modulo); | ||
428 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
429 | } else { | ||
430 | dto_cntl = RREG32(DCCG_AUDIO_DTO1_CNTL) & ~DCCG_AUDIO_DTO_WALLCLOCK_RATIO_MASK; | ||
431 | dto_cntl |= DCCG_AUDIO_DTO_WALLCLOCK_RATIO(wallclock_ratio); | ||
432 | WREG32(DCCG_AUDIO_DTO1_CNTL, dto_cntl); | ||
433 | WREG32(DCCG_AUDIO_DTO1_PHASE, dto_phase); | ||
434 | WREG32(DCCG_AUDIO_DTO1_MODULE, dto_modulo); | ||
435 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
436 | } | ||
437 | } else { | 402 | } else { |
438 | /* according to the reg specs, this should DCE3.2 only, but in | 403 | WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100); |
439 | * practice it seems to cover DCE2.0/3.0/3.1 as well. | 404 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); |
440 | */ | 405 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ |
441 | if (dig->dig_encoder == 0) { | ||
442 | WREG32(DCCG_AUDIO_DTO0_PHASE, base_rate * 100); | ||
443 | WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100); | ||
444 | WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */ | ||
445 | } else { | ||
446 | WREG32(DCCG_AUDIO_DTO1_PHASE, base_rate * 100); | ||
447 | WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100); | ||
448 | WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */ | ||
449 | } | ||
450 | } | 406 | } |
451 | } | 407 | } |
452 | 408 | ||
@@ -477,7 +433,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod | |||
477 | dig->afmt->pin = radeon_audio_get_pin(encoder); | 433 | dig->afmt->pin = radeon_audio_get_pin(encoder); |
478 | radeon_audio_enable(rdev, dig->afmt->pin, 0); | 434 | radeon_audio_enable(rdev, dig->afmt->pin, 0); |
479 | 435 | ||
480 | r600_audio_set_dto(encoder, mode->clock); | 436 | radeon_audio_set_dto(encoder, mode->clock); |
481 | 437 | ||
482 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, | 438 | WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset, |
483 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ | 439 | HDMI0_AUDIO_SAMPLE_SEND | /* send audio packets */ |
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c index e6c73f8206b2..2a2bf5b5b805 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.c +++ b/drivers/gpu/drm/radeon/radeon_audio.c | |||
@@ -62,6 +62,18 @@ void dce6_afmt_write_latency_fields(struct drm_encoder *encoder, | |||
62 | struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); | 62 | struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); |
63 | struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); | 63 | struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); |
64 | void dce6_afmt_select_pin(struct drm_encoder *encoder); | 64 | void dce6_afmt_select_pin(struct drm_encoder *encoder); |
65 | void r600_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
66 | struct radeon_crtc *crtc, unsigned int clock); | ||
67 | void dce3_2_audio_set_dto(struct radeon_device *rdev, | ||
68 | struct radeon_crtc *crtc, unsigned int clock); | ||
69 | void dce4_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
70 | struct radeon_crtc *crtc, unsigned int clock); | ||
71 | void dce4_dp_audio_set_dto(struct radeon_device *rdev, | ||
72 | struct radeon_crtc *crtc, unsigned int clock); | ||
73 | void dce6_hdmi_audio_set_dto(struct radeon_device *rdev, | ||
74 | struct radeon_crtc *crtc, unsigned int clock); | ||
75 | void dce6_dp_audio_set_dto(struct radeon_device *rdev, | ||
76 | struct radeon_crtc *crtc, unsigned int clock); | ||
65 | 77 | ||
66 | static const u32 pin_offsets[7] = | 78 | static const u32 pin_offsets[7] = |
67 | { | 79 | { |
@@ -85,6 +97,12 @@ static void radeon_audio_wreg(struct radeon_device *rdev, u32 offset, | |||
85 | WREG32(reg, v); | 97 | WREG32(reg, v); |
86 | } | 98 | } |
87 | 99 | ||
100 | static struct radeon_audio_basic_funcs r600_funcs = { | ||
101 | .endpoint_rreg = radeon_audio_rreg, | ||
102 | .endpoint_wreg = radeon_audio_wreg, | ||
103 | .enable = r600_audio_enable, | ||
104 | }; | ||
105 | |||
88 | static struct radeon_audio_basic_funcs dce32_funcs = { | 106 | static struct radeon_audio_basic_funcs dce32_funcs = { |
89 | .endpoint_rreg = radeon_audio_rreg, | 107 | .endpoint_rreg = radeon_audio_rreg, |
90 | .endpoint_wreg = radeon_audio_wreg, | 108 | .endpoint_wreg = radeon_audio_wreg, |
@@ -103,16 +121,23 @@ static struct radeon_audio_basic_funcs dce6_funcs = { | |||
103 | .enable = dce6_audio_enable, | 121 | .enable = dce6_audio_enable, |
104 | }; | 122 | }; |
105 | 123 | ||
124 | static struct radeon_audio_funcs r600_hdmi_funcs = { | ||
125 | .get_pin = r600_audio_get_pin, | ||
126 | .set_dto = r600_hdmi_audio_set_dto, | ||
127 | }; | ||
128 | |||
106 | static struct radeon_audio_funcs dce32_hdmi_funcs = { | 129 | static struct radeon_audio_funcs dce32_hdmi_funcs = { |
107 | .get_pin = r600_audio_get_pin, | 130 | .get_pin = r600_audio_get_pin, |
108 | .write_sad_regs = dce3_2_afmt_write_sad_regs, | 131 | .write_sad_regs = dce3_2_afmt_write_sad_regs, |
109 | .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, | 132 | .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, |
133 | .set_dto = dce3_2_audio_set_dto, | ||
110 | }; | 134 | }; |
111 | 135 | ||
112 | static struct radeon_audio_funcs dce32_dp_funcs = { | 136 | static struct radeon_audio_funcs dce32_dp_funcs = { |
113 | .get_pin = r600_audio_get_pin, | 137 | .get_pin = r600_audio_get_pin, |
114 | .write_sad_regs = dce3_2_afmt_write_sad_regs, | 138 | .write_sad_regs = dce3_2_afmt_write_sad_regs, |
115 | .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, | 139 | .write_speaker_allocation = dce3_2_afmt_dp_write_speaker_allocation, |
140 | .set_dto = dce3_2_audio_set_dto, | ||
116 | }; | 141 | }; |
117 | 142 | ||
118 | static struct radeon_audio_funcs dce4_hdmi_funcs = { | 143 | static struct radeon_audio_funcs dce4_hdmi_funcs = { |
@@ -120,6 +145,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = { | |||
120 | .write_sad_regs = evergreen_hdmi_write_sad_regs, | 145 | .write_sad_regs = evergreen_hdmi_write_sad_regs, |
121 | .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, | 146 | .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, |
122 | .write_latency_fields = dce4_afmt_write_latency_fields, | 147 | .write_latency_fields = dce4_afmt_write_latency_fields, |
148 | .set_dto = dce4_hdmi_audio_set_dto, | ||
123 | }; | 149 | }; |
124 | 150 | ||
125 | static struct radeon_audio_funcs dce4_dp_funcs = { | 151 | static struct radeon_audio_funcs dce4_dp_funcs = { |
@@ -127,6 +153,7 @@ static struct radeon_audio_funcs dce4_dp_funcs = { | |||
127 | .write_sad_regs = evergreen_hdmi_write_sad_regs, | 153 | .write_sad_regs = evergreen_hdmi_write_sad_regs, |
128 | .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, | 154 | .write_speaker_allocation = dce4_afmt_dp_write_speaker_allocation, |
129 | .write_latency_fields = dce4_afmt_write_latency_fields, | 155 | .write_latency_fields = dce4_afmt_write_latency_fields, |
156 | .set_dto = dce4_dp_audio_set_dto, | ||
130 | }; | 157 | }; |
131 | 158 | ||
132 | static struct radeon_audio_funcs dce6_hdmi_funcs = { | 159 | static struct radeon_audio_funcs dce6_hdmi_funcs = { |
@@ -135,6 +162,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = { | |||
135 | .write_sad_regs = dce6_afmt_write_sad_regs, | 162 | .write_sad_regs = dce6_afmt_write_sad_regs, |
136 | .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, | 163 | .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, |
137 | .write_latency_fields = dce6_afmt_write_latency_fields, | 164 | .write_latency_fields = dce6_afmt_write_latency_fields, |
165 | .set_dto = dce6_hdmi_audio_set_dto, | ||
138 | }; | 166 | }; |
139 | 167 | ||
140 | static struct radeon_audio_funcs dce6_dp_funcs = { | 168 | static struct radeon_audio_funcs dce6_dp_funcs = { |
@@ -143,6 +171,7 @@ static struct radeon_audio_funcs dce6_dp_funcs = { | |||
143 | .write_sad_regs = dce6_afmt_write_sad_regs, | 171 | .write_sad_regs = dce6_afmt_write_sad_regs, |
144 | .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, | 172 | .write_speaker_allocation = dce6_afmt_dp_write_speaker_allocation, |
145 | .write_latency_fields = dce6_afmt_write_latency_fields, | 173 | .write_latency_fields = dce6_afmt_write_latency_fields, |
174 | .set_dto = dce6_dp_audio_set_dto, | ||
146 | }; | 175 | }; |
147 | 176 | ||
148 | static void radeon_audio_interface_init(struct radeon_device *rdev) | 177 | static void radeon_audio_interface_init(struct radeon_device *rdev) |
@@ -155,10 +184,14 @@ static void radeon_audio_interface_init(struct radeon_device *rdev) | |||
155 | rdev->audio.funcs = &dce4_funcs; | 184 | rdev->audio.funcs = &dce4_funcs; |
156 | rdev->audio.hdmi_funcs = &dce4_hdmi_funcs; | 185 | rdev->audio.hdmi_funcs = &dce4_hdmi_funcs; |
157 | rdev->audio.dp_funcs = &dce4_dp_funcs; | 186 | rdev->audio.dp_funcs = &dce4_dp_funcs; |
158 | } else { | 187 | } else if (ASIC_IS_DCE32(rdev)) { |
159 | rdev->audio.funcs = &dce32_funcs; | 188 | rdev->audio.funcs = &dce32_funcs; |
160 | rdev->audio.hdmi_funcs = &dce32_hdmi_funcs; | 189 | rdev->audio.hdmi_funcs = &dce32_hdmi_funcs; |
161 | rdev->audio.dp_funcs = &dce32_dp_funcs; | 190 | rdev->audio.dp_funcs = &dce32_dp_funcs; |
191 | } else { | ||
192 | rdev->audio.funcs = &r600_funcs; | ||
193 | rdev->audio.hdmi_funcs = &r600_hdmi_funcs; | ||
194 | rdev->audio.dp_funcs = 0; | ||
162 | } | 195 | } |
163 | } | 196 | } |
164 | 197 | ||
@@ -393,3 +426,13 @@ void radeon_audio_fini(struct radeon_device *rdev) | |||
393 | 426 | ||
394 | rdev->audio.enabled = false; | 427 | rdev->audio.enabled = false; |
395 | } | 428 | } |
429 | |||
430 | void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock) | ||
431 | { | ||
432 | struct radeon_device *rdev = encoder->dev->dev_private; | ||
433 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | ||
434 | struct radeon_crtc *crtc = to_radeon_crtc(encoder->crtc); | ||
435 | |||
436 | if (radeon_encoder->audio && radeon_encoder->audio->set_dto) | ||
437 | radeon_encoder->audio->set_dto(rdev, crtc, clock); | ||
438 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h index 5844993a1edb..06b80de7cdbe 100644 --- a/drivers/gpu/drm/radeon/radeon_audio.h +++ b/drivers/gpu/drm/radeon/radeon_audio.h | |||
@@ -51,6 +51,8 @@ struct radeon_audio_funcs | |||
51 | struct cea_sad *sads, int sad_count); | 51 | struct cea_sad *sads, int sad_count); |
52 | void (*write_speaker_allocation)(struct drm_encoder *encoder, | 52 | void (*write_speaker_allocation)(struct drm_encoder *encoder, |
53 | u8 *sadb, int sad_count); | 53 | u8 *sadb, int sad_count); |
54 | void (*set_dto)(struct radeon_device *rdev, | ||
55 | struct radeon_crtc *crtc, unsigned int clock); | ||
54 | }; | 56 | }; |
55 | 57 | ||
56 | int radeon_audio_init(struct radeon_device *rdev); | 58 | int radeon_audio_init(struct radeon_device *rdev); |
@@ -69,5 +71,6 @@ void radeon_audio_select_pin(struct drm_encoder *encoder); | |||
69 | void radeon_audio_enable(struct radeon_device *rdev, | 71 | void radeon_audio_enable(struct radeon_device *rdev, |
70 | struct r600_audio_pin *pin, u8 enable_mask); | 72 | struct r600_audio_pin *pin, u8 enable_mask); |
71 | void radeon_audio_fini(struct radeon_device *rdev); | 73 | void radeon_audio_fini(struct radeon_device *rdev); |
74 | void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); | ||
72 | 75 | ||
73 | #endif | 76 | #endif |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 84999242c747..cbd91d226f3c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -901,6 +901,16 @@ | |||
901 | /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ | 901 | /* 0x6e98, 0x7a98, 0x10698, 0x11298, 0x11e98, 0x12a98 */ |
902 | #define CRTC_STATUS_FRAME_COUNT 0x6e98 | 902 | #define CRTC_STATUS_FRAME_COUNT 0x6e98 |
903 | 903 | ||
904 | /* Audio clocks */ | ||
905 | #define DCCG_AUDIO_DTO_SOURCE 0x05ac | ||
906 | # define DCCG_AUDIO_DTO0_SOURCE_SEL(x) ((x) << 0) /* crtc0 - crtc5 */ | ||
907 | # define DCCG_AUDIO_DTO_SEL (1 << 4) /* 0=dto0 1=dto1 */ | ||
908 | |||
909 | #define DCCG_AUDIO_DTO0_PHASE 0x05b0 | ||
910 | #define DCCG_AUDIO_DTO0_MODULE 0x05b4 | ||
911 | #define DCCG_AUDIO_DTO1_PHASE 0x05b8 | ||
912 | #define DCCG_AUDIO_DTO1_MODULE 0x05bc | ||
913 | |||
904 | #define AFMT_AUDIO_SRC_CONTROL 0x713c | 914 | #define AFMT_AUDIO_SRC_CONTROL 0x713c |
905 | #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) | 915 | #define AFMT_AUDIO_SRC_SELECT(x) (((x) & 7) << 0) |
906 | /* AFMT_AUDIO_SRC_SELECT | 916 | /* AFMT_AUDIO_SRC_SELECT |