aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorSlava Grigorev <slava.grigorev@amd.com>2014-12-05 13:38:31 -0500
committerAlex Deucher <alexander.deucher@amd.com>2015-01-22 10:42:10 -0500
commita85d682a6578a3bd02c95afb4ef527fa0897bb69 (patch)
treef701ab1882ec512584f0b7a5b21575394c0f421c /drivers/gpu/drm
parent7991d6650117064ae1d2b215b5cbb4112711ed5e (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.c56
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c39
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c92
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c80
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c45
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.h3
-rw-r--r--drivers/gpu/drm/radeon/sid.h10
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
116void 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
252void 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
271void 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
221static void evergreen_audio_set_dto(struct drm_encoder *encoder, u32 clock) 221void 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
264void 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
383void r600_audio_set_dto(struct drm_encoder *encoder, u32 clock) 383void 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,
62struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev); 62struct r600_audio_pin* r600_audio_get_pin(struct radeon_device *rdev);
63struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev); 63struct r600_audio_pin* dce6_audio_get_pin(struct radeon_device *rdev);
64void dce6_afmt_select_pin(struct drm_encoder *encoder); 64void dce6_afmt_select_pin(struct drm_encoder *encoder);
65void r600_hdmi_audio_set_dto(struct radeon_device *rdev,
66 struct radeon_crtc *crtc, unsigned int clock);
67void dce3_2_audio_set_dto(struct radeon_device *rdev,
68 struct radeon_crtc *crtc, unsigned int clock);
69void dce4_hdmi_audio_set_dto(struct radeon_device *rdev,
70 struct radeon_crtc *crtc, unsigned int clock);
71void dce4_dp_audio_set_dto(struct radeon_device *rdev,
72 struct radeon_crtc *crtc, unsigned int clock);
73void dce6_hdmi_audio_set_dto(struct radeon_device *rdev,
74 struct radeon_crtc *crtc, unsigned int clock);
75void dce6_dp_audio_set_dto(struct radeon_device *rdev,
76 struct radeon_crtc *crtc, unsigned int clock);
65 77
66static const u32 pin_offsets[7] = 78static 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
100static 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
88static struct radeon_audio_basic_funcs dce32_funcs = { 106static 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
124static struct radeon_audio_funcs r600_hdmi_funcs = {
125 .get_pin = r600_audio_get_pin,
126 .set_dto = r600_hdmi_audio_set_dto,
127};
128
106static struct radeon_audio_funcs dce32_hdmi_funcs = { 129static 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
112static struct radeon_audio_funcs dce32_dp_funcs = { 136static 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
118static struct radeon_audio_funcs dce4_hdmi_funcs = { 143static 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
125static struct radeon_audio_funcs dce4_dp_funcs = { 151static 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
132static struct radeon_audio_funcs dce6_hdmi_funcs = { 159static 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
140static struct radeon_audio_funcs dce6_dp_funcs = { 168static 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
148static void radeon_audio_interface_init(struct radeon_device *rdev) 177static 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
430void 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
56int radeon_audio_init(struct radeon_device *rdev); 58int radeon_audio_init(struct radeon_device *rdev);
@@ -69,5 +71,6 @@ void radeon_audio_select_pin(struct drm_encoder *encoder);
69void radeon_audio_enable(struct radeon_device *rdev, 71void 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);
71void radeon_audio_fini(struct radeon_device *rdev); 73void radeon_audio_fini(struct radeon_device *rdev);
74void 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