aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorSlava Grigorev <slava.grigorev@amd.com>2014-12-06 20:19:16 -0500
committerAlex Deucher <alexander.deucher@amd.com>2015-01-22 10:42:11 -0500
commit64424d6e45aeee311a4231def7e125bcc2de0855 (patch)
treef7a6692f1f20070df377435c352cd2cd5e60cc48 /drivers/gpu
parent96ea7afbc256ce7e2b2446909f52dab357942c3c (diff)
radeon/audio: consolidate update_acr() functions (v2)
V2: fix missing dce6 callback Signed-off-by: Slava Grigorev <slava.grigorev@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/dce3_1_afmt.c38
-rw-r--r--drivers/gpu/drm/radeon/evergreen_hdmi.c46
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c129
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.c100
-rw-r--r--drivers/gpu/drm/radeon/radeon_audio.h3
5 files changed, 183 insertions, 133 deletions
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c
index 0accc5ee0e39..2a963c173cc1 100644
--- a/drivers/gpu/drm/radeon/dce3_1_afmt.c
+++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c
@@ -167,6 +167,38 @@ void dce3_2_audio_set_dto(struct radeon_device *rdev,
167 } 167 }
168} 168}
169 169
170void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset,
171 const struct radeon_hdmi_acr *acr)
172{
173 struct drm_device *dev = encoder->dev;
174 struct radeon_device *rdev = dev->dev_private;
175
176 WREG32(HDMI0_ACR_PACKET_CONTROL + offset,
177 HDMI0_ACR_SOURCE | /* select SW CTS value */
178 HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
179
180 WREG32_P(HDMI0_ACR_32_0 + offset,
181 HDMI0_ACR_CTS_32(acr->cts_32khz),
182 ~HDMI0_ACR_CTS_32_MASK);
183 WREG32_P(HDMI0_ACR_32_1 + offset,
184 HDMI0_ACR_N_32(acr->n_32khz),
185 ~HDMI0_ACR_N_32_MASK);
186
187 WREG32_P(HDMI0_ACR_44_0 + offset,
188 HDMI0_ACR_CTS_44(acr->cts_44_1khz),
189 ~HDMI0_ACR_CTS_44_MASK);
190 WREG32_P(HDMI0_ACR_44_1 + offset,
191 HDMI0_ACR_N_44(acr->n_44_1khz),
192 ~HDMI0_ACR_N_44_MASK);
193
194 WREG32_P(HDMI0_ACR_48_0 + offset,
195 HDMI0_ACR_CTS_48(acr->cts_48khz),
196 ~HDMI0_ACR_CTS_48_MASK);
197 WREG32_P(HDMI0_ACR_48_1 + offset,
198 HDMI0_ACR_N_48(acr->n_48khz),
199 ~HDMI0_ACR_N_48_MASK);
200}
201
170/* 202/*
171 * update the info frames with the data from the current display mode 203 * update the info frames with the data from the current display mode
172 */ 204 */
@@ -220,10 +252,6 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m
220 radeon_audio_write_sad_regs(encoder); 252 radeon_audio_write_sad_regs(encoder);
221 } 253 }
222 254
223 WREG32(HDMI0_ACR_PACKET_CONTROL + offset,
224 HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */
225 HDMI0_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
226
227 WREG32(HDMI0_VBI_PACKET_CONTROL + offset, 255 WREG32(HDMI0_VBI_PACKET_CONTROL + offset,
228 HDMI0_NULL_SEND | /* send null packets when required */ 256 HDMI0_NULL_SEND | /* send null packets when required */
229 HDMI0_GC_SEND | /* send general control packets */ 257 HDMI0_GC_SEND | /* send general control packets */
@@ -255,7 +283,7 @@ void dce3_1_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *m
255 } 283 }
256 284
257 radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer)); 285 radeon_update_avi_infoframe(encoder, buffer, sizeof(buffer));
258 r600_hdmi_update_ACR(encoder, mode->clock); 286 radeon_audio_update_acr(encoder, mode->clock);
259 287
260 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */ 288 /* it's unknown what these bits do excatly, but it's indeed quite useful for debugging */
261 WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF); 289 WREG32(HDMI0_RAMP_CONTROL0 + offset, 0x00FFFFFF);
diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c
index f2896e5ff055..05cef011c3af 100644
--- a/drivers/gpu/drm/radeon/evergreen_hdmi.c
+++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c
@@ -64,26 +64,34 @@ void dce4_audio_enable(struct radeon_device *rdev,
64 WREG32(AZ_HOT_PLUG_CONTROL, tmp); 64 WREG32(AZ_HOT_PLUG_CONTROL, tmp);
65} 65}
66 66
67/* 67void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset,
68 * update the N and CTS parameters for a given pixel clock rate 68 const struct radeon_hdmi_acr *acr)
69 */
70static void evergreen_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
71{ 69{
72 struct drm_device *dev = encoder->dev; 70 struct drm_device *dev = encoder->dev;
73 struct radeon_device *rdev = dev->dev_private; 71 struct radeon_device *rdev = dev->dev_private;
74 struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); 72 int bpc = 8;
75 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 73
76 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 74 if (encoder->crtc) {
77 uint32_t offset = dig->afmt->offset; 75 struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
76 bpc = radeon_crtc->bpc;
77 }
78 78
79 WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr.cts_32khz)); 79 if (bpc > 8)
80 WREG32(HDMI_ACR_32_1 + offset, acr.n_32khz); 80 WREG32(HDMI_ACR_PACKET_CONTROL + offset,
81 HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
82 else
83 WREG32(HDMI_ACR_PACKET_CONTROL + offset,
84 HDMI_ACR_SOURCE | /* select SW CTS value */
85 HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
86
87 WREG32(HDMI_ACR_32_0 + offset, HDMI_ACR_CTS_32(acr->cts_32khz));
88 WREG32(HDMI_ACR_32_1 + offset, acr->n_32khz);
81 89
82 WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr.cts_44_1khz)); 90 WREG32(HDMI_ACR_44_0 + offset, HDMI_ACR_CTS_44(acr->cts_44_1khz));
83 WREG32(HDMI_ACR_44_1 + offset, acr.n_44_1khz); 91 WREG32(HDMI_ACR_44_1 + offset, acr->n_44_1khz);
84 92
85 WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr.cts_48khz)); 93 WREG32(HDMI_ACR_48_0 + offset, HDMI_ACR_CTS_48(acr->cts_48khz));
86 WREG32(HDMI_ACR_48_1 + offset, acr.n_48khz); 94 WREG32(HDMI_ACR_48_1 + offset, acr->n_48khz);
87} 95}
88 96
89void dce4_afmt_write_latency_fields(struct drm_encoder *encoder, 97void dce4_afmt_write_latency_fields(struct drm_encoder *encoder,
@@ -378,15 +386,7 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode
378 386
379 /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */ 387 /* fglrx clears sth in AFMT_AUDIO_PACKET_CONTROL2 here */
380 388
381 if (bpc > 8) 389 radeon_audio_update_acr(encoder, mode->clock);
382 WREG32(HDMI_ACR_PACKET_CONTROL + offset,
383 HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
384 else
385 WREG32(HDMI_ACR_PACKET_CONTROL + offset,
386 HDMI_ACR_SOURCE | /* select SW CTS value */
387 HDMI_ACR_AUTO_SEND); /* allow hw to sent ACR packets when required */
388
389 evergreen_hdmi_update_ACR(encoder, mode->clock);
390 390
391 WREG32(AFMT_60958_0 + offset, 391 WREG32(AFMT_60958_0 + offset,
392 AFMT_60958_CS_CHANNEL_NUMBER_L(1)); 392 AFMT_60958_CS_CHANNEL_NUMBER_L(1));
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 53ee7ad9612c..f91273912eb8 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -56,21 +56,6 @@ enum r600_hdmi_iec_status_bits {
56 AUDIO_STATUS_LEVEL = 0x80 56 AUDIO_STATUS_LEVEL = 0x80
57}; 57};
58 58
59static const struct radeon_hdmi_acr r600_hdmi_predefined_acr[] = {
60 /* 32kHz 44.1kHz 48kHz */
61 /* Clock N CTS N CTS N CTS */
62 { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
63 { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
64 { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
65 { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
66 { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
67 { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
68 { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
69 { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
70 { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
71 { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
72};
73
74static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) 59static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev)
75{ 60{
76 struct r600_audio_pin status; 61 struct r600_audio_pin status;
@@ -189,97 +174,41 @@ struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev)
189 return &rdev->audio.pin[0]; 174 return &rdev->audio.pin[0];
190} 175}
191 176
192/* 177void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
193 * calculate CTS and N values if they are not found in the table 178 const struct radeon_hdmi_acr *acr)
194 */
195static void r600_hdmi_calc_cts(uint32_t clock, int *CTS, int *N, int freq)
196{
197 int n, cts;
198 unsigned long div, mul;
199
200 /* Safe, but overly large values */
201 n = 128 * freq;
202 cts = clock * 1000;
203
204 /* Smallest valid fraction */
205 div = gcd(n, cts);
206
207 n /= div;
208 cts /= div;
209
210 /*
211 * The optimal N is 128*freq/1000. Calculate the closest larger
212 * value that doesn't truncate any bits.
213 */
214 mul = ((128*freq/1000) + (n-1))/n;
215
216 n *= mul;
217 cts *= mul;
218
219 /* Check that we are in spec (not always possible) */
220 if (n < (128*freq/1500))
221 printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
222 if (n > (128*freq/300))
223 printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
224
225 *N = n;
226 *CTS = cts;
227
228 DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
229 *N, *CTS, freq);
230}
231
232struct radeon_hdmi_acr r600_hdmi_acr(uint32_t clock)
233{
234 struct radeon_hdmi_acr res;
235 u8 i;
236
237 /* Precalculated values for common clocks */
238 for (i = 0; i < ARRAY_SIZE(r600_hdmi_predefined_acr); i++) {
239 if (r600_hdmi_predefined_acr[i].clock == clock)
240 return r600_hdmi_predefined_acr[i];
241 }
242
243 /* And odd clocks get manually calculated */
244 r600_hdmi_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
245 r600_hdmi_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
246 r600_hdmi_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
247
248 return res;
249}
250
251/*
252 * update the N and CTS parameters for a given pixel clock rate
253 */
254void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)
255{ 179{
256 struct drm_device *dev = encoder->dev; 180 struct drm_device *dev = encoder->dev;
257 struct radeon_device *rdev = dev->dev_private; 181 struct radeon_device *rdev = dev->dev_private;
258 struct radeon_hdmi_acr acr = r600_hdmi_acr(clock); 182
259 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 183 /* DCE 3.0 uses register that's normally for CRC_CONTROL */
260 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 184 uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
261 uint32_t offset = dig->afmt->offset; 185 HDMI0_ACR_PACKET_CONTROL;
186 WREG32_P(acr_ctl + offset,
187 HDMI0_ACR_SOURCE | /* select SW CTS value */
188 HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */
189 ~(HDMI0_ACR_SOURCE |
190 HDMI0_ACR_AUTO_SEND));
262 191
263 WREG32_P(HDMI0_ACR_32_0 + offset, 192 WREG32_P(HDMI0_ACR_32_0 + offset,
264 HDMI0_ACR_CTS_32(acr.cts_32khz), 193 HDMI0_ACR_CTS_32(acr->cts_32khz),
265 ~HDMI0_ACR_CTS_32_MASK); 194 ~HDMI0_ACR_CTS_32_MASK);
266 WREG32_P(HDMI0_ACR_32_1 + offset, 195 WREG32_P(HDMI0_ACR_32_1 + offset,
267 HDMI0_ACR_N_32(acr.n_32khz), 196 HDMI0_ACR_N_32(acr->n_32khz),
268 ~HDMI0_ACR_N_32_MASK); 197 ~HDMI0_ACR_N_32_MASK);
269 198
270 WREG32_P(HDMI0_ACR_44_0 + offset, 199 WREG32_P(HDMI0_ACR_44_0 + offset,
271 HDMI0_ACR_CTS_44(acr.cts_44_1khz), 200 HDMI0_ACR_CTS_44(acr->cts_44_1khz),
272 ~HDMI0_ACR_CTS_44_MASK); 201 ~HDMI0_ACR_CTS_44_MASK);
273 WREG32_P(HDMI0_ACR_44_1 + offset, 202 WREG32_P(HDMI0_ACR_44_1 + offset,
274 HDMI0_ACR_N_44(acr.n_44_1khz), 203 HDMI0_ACR_N_44(acr->n_44_1khz),
275 ~HDMI0_ACR_N_44_MASK); 204 ~HDMI0_ACR_N_44_MASK);
276 205
277 WREG32_P(HDMI0_ACR_48_0 + offset, 206 WREG32_P(HDMI0_ACR_48_0 + offset,
278 HDMI0_ACR_CTS_48(acr.cts_48khz), 207 HDMI0_ACR_CTS_48(acr->cts_48khz),
279 ~HDMI0_ACR_CTS_48_MASK); 208 ~HDMI0_ACR_CTS_48_MASK);
280 WREG32_P(HDMI0_ACR_48_1 + offset, 209 WREG32_P(HDMI0_ACR_48_1 + offset,
281 HDMI0_ACR_N_48(acr.n_48khz), 210 HDMI0_ACR_N_48(acr->n_48khz),
282 ~HDMI0_ACR_N_48_MASK); 211 ~HDMI0_ACR_N_48_MASK);
283} 212}
284 213
285/* 214/*
@@ -412,7 +341,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
412 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE]; 341 u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
413 struct hdmi_avi_infoframe frame; 342 struct hdmi_avi_infoframe frame;
414 uint32_t offset; 343 uint32_t offset;
415 uint32_t acr_ctl;
416 ssize_t err; 344 ssize_t err;
417 345
418 if (!dig || !dig->afmt) 346 if (!dig || !dig->afmt)
@@ -439,15 +367,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
439 HDMI0_AUDIO_PACKETS_PER_LINE_MASK | 367 HDMI0_AUDIO_PACKETS_PER_LINE_MASK |
440 HDMI0_60958_CS_UPDATE)); 368 HDMI0_60958_CS_UPDATE));
441 369
442 /* DCE 3.0 uses register that's normally for CRC_CONTROL */
443 acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :
444 HDMI0_ACR_PACKET_CONTROL;
445 WREG32_P(acr_ctl + offset,
446 HDMI0_ACR_SOURCE | /* select SW CTS value - XXX verify that hw CTS works on all families */
447 HDMI0_ACR_AUTO_SEND, /* allow hw to sent ACR packets when required */
448 ~(HDMI0_ACR_SOURCE |
449 HDMI0_ACR_AUTO_SEND));
450
451 WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset, 370 WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,
452 HDMI0_NULL_SEND | /* send null packets when required */ 371 HDMI0_NULL_SEND | /* send null packets when required */
453 HDMI0_GC_SEND | /* send general control packets */ 372 HDMI0_GC_SEND | /* send general control packets */
@@ -493,7 +412,7 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
493 HDMI0_GENERIC0_LINE_MASK | 412 HDMI0_GENERIC0_LINE_MASK |
494 HDMI0_GENERIC1_LINE_MASK)); 413 HDMI0_GENERIC1_LINE_MASK));
495 414
496 r600_hdmi_update_ACR(encoder, mode->clock); 415 radeon_audio_update_acr(encoder, mode->clock);
497 416
498 WREG32_P(HDMI0_60958_0 + offset, 417 WREG32_P(HDMI0_60958_0 + offset,
499 HDMI0_60958_CS_CHANNEL_NUMBER_L(1), 418 HDMI0_60958_CS_CHANNEL_NUMBER_L(1),
diff --git a/drivers/gpu/drm/radeon/radeon_audio.c b/drivers/gpu/drm/radeon/radeon_audio.c
index cc58ee8c7d2f..dbb3c594e9ae 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.c
+++ b/drivers/gpu/drm/radeon/radeon_audio.c
@@ -22,6 +22,7 @@
22 * Authors: Slava Grigorev <slava.grigorev@amd.com> 22 * Authors: Slava Grigorev <slava.grigorev@amd.com>
23 */ 23 */
24 24
25#include <linux/gcd.h>
25#include <drm/drmP.h> 26#include <drm/drmP.h>
26#include <drm/drm_crtc.h> 27#include <drm/drm_crtc.h>
27#include "radeon.h" 28#include "radeon.h"
@@ -78,6 +79,12 @@ void r600_update_avi_infoframe(struct radeon_device *rdev, u32 offset,
78 unsigned char *buffer, size_t size); 79 unsigned char *buffer, size_t size);
79void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset, 80void evergreen_update_avi_infoframe(struct radeon_device *rdev, u32 offset,
80 unsigned char *buffer, size_t size); 81 unsigned char *buffer, size_t size);
82void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,
83 const struct radeon_hdmi_acr *acr);
84void dce3_2_hdmi_update_acr(struct drm_encoder *encoder, long offset,
85 const struct radeon_hdmi_acr *acr);
86void evergreen_hdmi_update_acr(struct drm_encoder *encoder, long offset,
87 const struct radeon_hdmi_acr *acr);
81 88
82static const u32 pin_offsets[7] = 89static const u32 pin_offsets[7] =
83{ 90{
@@ -132,6 +139,7 @@ static struct radeon_audio_basic_funcs dce6_funcs = {
132static struct radeon_audio_funcs r600_hdmi_funcs = { 139static struct radeon_audio_funcs r600_hdmi_funcs = {
133 .get_pin = r600_audio_get_pin, 140 .get_pin = r600_audio_get_pin,
134 .set_dto = r600_hdmi_audio_set_dto, 141 .set_dto = r600_hdmi_audio_set_dto,
142 .update_acr = r600_hdmi_update_acr,
135}; 143};
136 144
137static struct radeon_audio_funcs dce32_hdmi_funcs = { 145static struct radeon_audio_funcs dce32_hdmi_funcs = {
@@ -139,6 +147,7 @@ static struct radeon_audio_funcs dce32_hdmi_funcs = {
139 .write_sad_regs = dce3_2_afmt_write_sad_regs, 147 .write_sad_regs = dce3_2_afmt_write_sad_regs,
140 .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation, 148 .write_speaker_allocation = dce3_2_afmt_hdmi_write_speaker_allocation,
141 .set_dto = dce3_2_audio_set_dto, 149 .set_dto = dce3_2_audio_set_dto,
150 .update_acr = dce3_2_hdmi_update_acr,
142}; 151};
143 152
144static struct radeon_audio_funcs dce32_dp_funcs = { 153static struct radeon_audio_funcs dce32_dp_funcs = {
@@ -154,6 +163,7 @@ static struct radeon_audio_funcs dce4_hdmi_funcs = {
154 .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation, 163 .write_speaker_allocation = dce4_afmt_hdmi_write_speaker_allocation,
155 .write_latency_fields = dce4_afmt_write_latency_fields, 164 .write_latency_fields = dce4_afmt_write_latency_fields,
156 .set_dto = dce4_hdmi_audio_set_dto, 165 .set_dto = dce4_hdmi_audio_set_dto,
166 .update_acr = evergreen_hdmi_update_acr,
157}; 167};
158 168
159static struct radeon_audio_funcs dce4_dp_funcs = { 169static struct radeon_audio_funcs dce4_dp_funcs = {
@@ -171,6 +181,7 @@ static struct radeon_audio_funcs dce6_hdmi_funcs = {
171 .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation, 181 .write_speaker_allocation = dce6_afmt_hdmi_write_speaker_allocation,
172 .write_latency_fields = dce6_afmt_write_latency_fields, 182 .write_latency_fields = dce6_afmt_write_latency_fields,
173 .set_dto = dce6_hdmi_audio_set_dto, 183 .set_dto = dce6_hdmi_audio_set_dto,
184 .update_acr = evergreen_hdmi_update_acr,
174}; 185};
175 186
176static struct radeon_audio_funcs dce6_dp_funcs = { 187static struct radeon_audio_funcs dce6_dp_funcs = {
@@ -456,3 +467,92 @@ void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer,
456 rdev->audio.funcs->update_avi_infoframe(rdev, dig->afmt->offset, 467 rdev->audio.funcs->update_avi_infoframe(rdev, dig->afmt->offset,
457 buffer, size); 468 buffer, size);
458} 469}
470
471/*
472 * calculate CTS and N values if they are not found in the table
473 */
474static void radeon_audio_calc_cts(unsigned int clock, int *CTS, int *N, int freq)
475{
476 int n, cts;
477 unsigned long div, mul;
478
479 /* Safe, but overly large values */
480 n = 128 * freq;
481 cts = clock * 1000;
482
483 /* Smallest valid fraction */
484 div = gcd(n, cts);
485
486 n /= div;
487 cts /= div;
488
489 /*
490 * The optimal N is 128*freq/1000. Calculate the closest larger
491 * value that doesn't truncate any bits.
492 */
493 mul = ((128*freq/1000) + (n-1))/n;
494
495 n *= mul;
496 cts *= mul;
497
498 /* Check that we are in spec (not always possible) */
499 if (n < (128*freq/1500))
500 printk(KERN_WARNING "Calculated ACR N value is too small. You may experience audio problems.\n");
501 if (n > (128*freq/300))
502 printk(KERN_WARNING "Calculated ACR N value is too large. You may experience audio problems.\n");
503
504 *N = n;
505 *CTS = cts;
506
507 DRM_DEBUG("Calculated ACR timing N=%d CTS=%d for frequency %d\n",
508 *N, *CTS, freq);
509}
510
511static const struct radeon_hdmi_acr* radeon_audio_acr(unsigned int clock)
512{
513 static struct radeon_hdmi_acr res;
514 u8 i;
515
516 static const struct radeon_hdmi_acr hdmi_predefined_acr[] = {
517 /* 32kHz 44.1kHz 48kHz */
518 /* Clock N CTS N CTS N CTS */
519 { 25175, 4096, 25175, 28224, 125875, 6144, 25175 }, /* 25,20/1.001 MHz */
520 { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */
521 { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */
522 { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */
523 { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */
524 { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */
525 { 74176, 4096, 74176, 5733, 75335, 6144, 74176 }, /* 74.25/1.001 MHz */
526 { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */
527 { 148352, 4096, 148352, 5733, 150670, 6144, 148352 }, /* 148.50/1.001 MHz */
528 { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */
529 };
530
531 /* Precalculated values for common clocks */
532 for (i = 0; i < ARRAY_SIZE(hdmi_predefined_acr); i++)
533 if (hdmi_predefined_acr[i].clock == clock)
534 return &hdmi_predefined_acr[i];
535
536 /* And odd clocks get manually calculated */
537 radeon_audio_calc_cts(clock, &res.cts_32khz, &res.n_32khz, 32000);
538 radeon_audio_calc_cts(clock, &res.cts_44_1khz, &res.n_44_1khz, 44100);
539 radeon_audio_calc_cts(clock, &res.cts_48khz, &res.n_48khz, 48000);
540
541 return &res;
542}
543
544/*
545 * update the N and CTS parameters for a given pixel clock rate
546 */
547void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock)
548{
549 const struct radeon_hdmi_acr *acr = radeon_audio_acr(clock);
550 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
551 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
552
553 if (!dig || !dig->afmt)
554 return;
555
556 if (radeon_encoder->audio && radeon_encoder->audio->update_acr)
557 radeon_encoder->audio->update_acr(encoder, dig->afmt->offset, acr);
558}
diff --git a/drivers/gpu/drm/radeon/radeon_audio.h b/drivers/gpu/drm/radeon/radeon_audio.h
index dc85d53d1587..a4d055311ab5 100644
--- a/drivers/gpu/drm/radeon/radeon_audio.h
+++ b/drivers/gpu/drm/radeon/radeon_audio.h
@@ -55,6 +55,8 @@ struct radeon_audio_funcs
55 u8 *sadb, int sad_count); 55 u8 *sadb, int sad_count);
56 void (*set_dto)(struct radeon_device *rdev, 56 void (*set_dto)(struct radeon_device *rdev,
57 struct radeon_crtc *crtc, unsigned int clock); 57 struct radeon_crtc *crtc, unsigned int clock);
58 void (*update_acr)(struct drm_encoder *encoder, long offset,
59 const struct radeon_hdmi_acr *acr);
58}; 60};
59 61
60int radeon_audio_init(struct radeon_device *rdev); 62int radeon_audio_init(struct radeon_device *rdev);
@@ -76,5 +78,6 @@ void radeon_audio_fini(struct radeon_device *rdev);
76void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock); 78void radeon_audio_set_dto(struct drm_encoder *encoder, unsigned int clock);
77void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer, 79void radeon_update_avi_infoframe(struct drm_encoder *encoder, void *buffer,
78 size_t size); 80 size_t size);
81void radeon_audio_update_acr(struct drm_encoder *encoder, unsigned int clock);
79 82
80#endif 83#endif