aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2012-05-14 15:25:57 -0400
committerDave Airlie <airlied@redhat.com>2012-05-22 05:14:16 -0400
commit3299de9558687ec02b3b9fae1af639844c46ea4b (patch)
tree9780c04edd28e5e979ea1a2bb01e70a1d3ea8530
parentc284815debba2f14ee2fd07b1b4cc972ab116110 (diff)
drm/radeon/hdmi: compile audio status in 1 function
This optmizes calls, registers reads and assignments. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c135
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c31
-rw-r--r--drivers/gpu/drm/radeon/radeon.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h7
4 files changed, 73 insertions, 104 deletions
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index b5a602e71c12..7c4fa77f018f 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -63,67 +63,56 @@ static int r600_audio_chipset_supported(struct radeon_device *rdev)
63 || rdev->family == CHIP_RS740; 63 || rdev->family == CHIP_RS740;
64} 64}
65 65
66/* 66struct r600_audio r600_audio_status(struct radeon_device *rdev)
67 * current number of channels
68 */
69int r600_audio_channels(struct radeon_device *rdev)
70{ 67{
71 return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; 68 struct r600_audio status;
72} 69 uint32_t value;
73 70
74/* 71 value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
75 * current bits per sample
76 */
77int r600_audio_bits_per_sample(struct radeon_device *rdev)
78{
79 uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
80 switch (value) {
81 case 0x0: return 8;
82 case 0x1: return 16;
83 case 0x2: return 20;
84 case 0x3: return 24;
85 case 0x4: return 32;
86 }
87 72
88 dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", 73 /* number of channels */
89 (int)value); 74 status.channels = (value & 0x7) + 1;
90 75
91 return 16; 76 /* bits per sample */
92} 77 switch ((value & 0xF0) >> 4) {
93 78 case 0x0:
94/* 79 status.bits_per_sample = 8;
95 * current sampling rate in HZ 80 break;
96 */ 81 case 0x1:
97int r600_audio_rate(struct radeon_device *rdev) 82 status.bits_per_sample = 16;
98{ 83 break;
99 uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); 84 case 0x2:
100 uint32_t result; 85 status.bits_per_sample = 20;
86 break;
87 case 0x3:
88 status.bits_per_sample = 24;
89 break;
90 case 0x4:
91 status.bits_per_sample = 32;
92 break;
93 default:
94 dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n",
95 (int)value);
96 status.bits_per_sample = 16;
97 }
101 98
99 /* current sampling rate in HZ */
102 if (value & 0x4000) 100 if (value & 0x4000)
103 result = 44100; 101 status.rate = 44100;
104 else 102 else
105 result = 48000; 103 status.rate = 48000;
104 status.rate *= ((value >> 11) & 0x7) + 1;
105 status.rate /= ((value >> 8) & 0x7) + 1;
106 106
107 result *= ((value >> 11) & 0x7) + 1; 107 value = RREG32(R600_AUDIO_STATUS_BITS);
108 result /= ((value >> 8) & 0x7) + 1;
109 108
110 return result; 109 /* iec 60958 status bits */
111} 110 status.status_bits = value & 0xff;
112 111
113/* 112 /* iec 60958 category code */
114 * iec 60958 status bits 113 status.category_code = (value >> 8) & 0xff;
115 */
116uint8_t r600_audio_status_bits(struct radeon_device *rdev)
117{
118 return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
119}
120 114
121/* 115 return status;
122 * iec 60958 category code
123 */
124uint8_t r600_audio_category_code(struct radeon_device *rdev)
125{
126 return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
127} 116}
128 117
129/* 118/*
@@ -134,33 +123,23 @@ void r600_audio_update_hdmi(struct work_struct *work)
134 struct radeon_device *rdev = container_of(work, struct radeon_device, 123 struct radeon_device *rdev = container_of(work, struct radeon_device,
135 audio_work); 124 audio_work);
136 struct drm_device *dev = rdev->ddev; 125 struct drm_device *dev = rdev->ddev;
137 126 struct r600_audio audio_status = r600_audio_status(rdev);
138 int channels = r600_audio_channels(rdev);
139 int rate = r600_audio_rate(rdev);
140 int bps = r600_audio_bits_per_sample(rdev);
141 uint8_t status_bits = r600_audio_status_bits(rdev);
142 uint8_t category_code = r600_audio_category_code(rdev);
143 struct drm_encoder *encoder; 127 struct drm_encoder *encoder;
144 int changes = 0; 128 bool changed = false;
145 129
146 changes |= channels != rdev->audio.channels; 130 if (rdev->audio_status.channels != audio_status.channels ||
147 changes |= rate != rdev->audio.rate; 131 rdev->audio_status.rate != audio_status.rate ||
148 changes |= bps != rdev->audio.bits_per_sample; 132 rdev->audio_status.bits_per_sample != audio_status.bits_per_sample ||
149 changes |= status_bits != rdev->audio.status_bits; 133 rdev->audio_status.status_bits != audio_status.status_bits ||
150 changes |= category_code != rdev->audio.category_code; 134 rdev->audio_status.category_code != audio_status.category_code) {
151 135 rdev->audio_status = audio_status;
152 if (changes) { 136 changed = true;
153 rdev->audio.channels = channels;
154 rdev->audio.rate = rate;
155 rdev->audio.bits_per_sample = bps;
156 rdev->audio.status_bits = status_bits;
157 rdev->audio.category_code = category_code;
158 } 137 }
159 138
160 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 139 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
161 if (!radeon_dig_encoder(encoder)) 140 if (!radeon_dig_encoder(encoder))
162 continue; 141 continue;
163 if (changes || r600_hdmi_buffer_status_changed(encoder)) 142 if (changed || r600_hdmi_buffer_status_changed(encoder))
164 r600_hdmi_update_audio_settings(encoder); 143 r600_hdmi_update_audio_settings(encoder);
165 } 144 }
166} 145}
@@ -182,7 +161,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
182 WREG32_P(R600_AUDIO_ENABLE, 161 WREG32_P(R600_AUDIO_ENABLE,
183 enable ? 0x81000000 : 0x0, ~0x81000000); 162 enable ? 0x81000000 : 0x0, ~0x81000000);
184 } 163 }
185 rdev->audio.enabled = enable; 164 rdev->audio_enabled = enable;
186} 165}
187 166
188/* 167/*
@@ -195,11 +174,11 @@ int r600_audio_init(struct radeon_device *rdev)
195 174
196 r600_audio_engine_enable(rdev, true); 175 r600_audio_engine_enable(rdev, true);
197 176
198 rdev->audio.channels = -1; 177 rdev->audio_status.channels = -1;
199 rdev->audio.rate = -1; 178 rdev->audio_status.rate = -1;
200 rdev->audio.bits_per_sample = -1; 179 rdev->audio_status.bits_per_sample = -1;
201 rdev->audio.status_bits = 0; 180 rdev->audio_status.status_bits = 0;
202 rdev->audio.category_code = 0; 181 rdev->audio_status.category_code = 0;
203 182
204 return 0; 183 return 0;
205} 184}
@@ -268,7 +247,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
268 */ 247 */
269void r600_audio_fini(struct radeon_device *rdev) 248void r600_audio_fini(struct radeon_device *rdev)
270{ 249{
271 if (!rdev->audio.enabled) 250 if (!rdev->audio_enabled)
272 return; 251 return;
273 252
274 r600_audio_engine_enable(rdev, false); 253 r600_audio_engine_enable(rdev, false);
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 31d19509e1d5..226379e00ac1 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -398,14 +398,8 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
398 struct radeon_device *rdev = dev->dev_private; 398 struct radeon_device *rdev = dev->dev_private;
399 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 399 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
400 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 400 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
401 struct r600_audio audio = r600_audio_status(rdev);
401 uint32_t offset; 402 uint32_t offset;
402
403 int channels = r600_audio_channels(rdev);
404 int rate = r600_audio_rate(rdev);
405 int bps = r600_audio_bits_per_sample(rdev);
406 uint8_t status_bits = r600_audio_status_bits(rdev);
407 uint8_t category_code = r600_audio_category_code(rdev);
408
409 uint32_t iec; 403 uint32_t iec;
410 404
411 if (!dig->afmt || !dig->afmt->enabled) 405 if (!dig->afmt || !dig->afmt->enabled)
@@ -414,23 +408,23 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
414 408
415 DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n", 409 DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",
416 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped", 410 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",
417 channels, rate, bps); 411 audio.channels, audio.rate, audio.bits_per_sample);
418 DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n", 412 DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",
419 (int)status_bits, (int)category_code); 413 (int)audio.status_bits, (int)audio.category_code);
420 414
421 iec = 0; 415 iec = 0;
422 if (status_bits & AUDIO_STATUS_PROFESSIONAL) 416 if (audio.status_bits & AUDIO_STATUS_PROFESSIONAL)
423 iec |= 1 << 0; 417 iec |= 1 << 0;
424 if (status_bits & AUDIO_STATUS_NONAUDIO) 418 if (audio.status_bits & AUDIO_STATUS_NONAUDIO)
425 iec |= 1 << 1; 419 iec |= 1 << 1;
426 if (status_bits & AUDIO_STATUS_COPYRIGHT) 420 if (audio.status_bits & AUDIO_STATUS_COPYRIGHT)
427 iec |= 1 << 2; 421 iec |= 1 << 2;
428 if (status_bits & AUDIO_STATUS_EMPHASIS) 422 if (audio.status_bits & AUDIO_STATUS_EMPHASIS)
429 iec |= 1 << 3; 423 iec |= 1 << 3;
430 424
431 iec |= HDMI0_60958_CS_CATEGORY_CODE(category_code); 425 iec |= HDMI0_60958_CS_CATEGORY_CODE(audio.category_code);
432 426
433 switch (rate) { 427 switch (audio.rate) {
434 case 32000: 428 case 32000:
435 iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x3); 429 iec |= HDMI0_60958_CS_SAMPLING_FREQUENCY(0x3);
436 break; 430 break;
@@ -457,7 +451,7 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
457 WREG32(HDMI0_60958_0 + offset, iec); 451 WREG32(HDMI0_60958_0 + offset, iec);
458 452
459 iec = 0; 453 iec = 0;
460 switch (bps) { 454 switch (audio.bits_per_sample) {
461 case 16: 455 case 16:
462 iec |= HDMI0_60958_CS_WORD_LENGTH(0x2); 456 iec |= HDMI0_60958_CS_WORD_LENGTH(0x2);
463 break; 457 break;
@@ -468,11 +462,12 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
468 iec |= HDMI0_60958_CS_WORD_LENGTH(0xb); 462 iec |= HDMI0_60958_CS_WORD_LENGTH(0xb);
469 break; 463 break;
470 } 464 }
471 if (status_bits & AUDIO_STATUS_V) 465 if (audio.status_bits & AUDIO_STATUS_V)
472 iec |= 0x5 << 16; 466 iec |= 0x5 << 16;
473 WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f); 467 WREG32_P(HDMI0_60958_1 + offset, iec, ~0x5000f);
474 468
475 r600_hdmi_audioinfoframe(encoder, channels - 1, 0, 0, 0, 0, 0, 0, 0); 469 r600_hdmi_audioinfoframe(encoder, audio.channels - 1, 0, 0, 0, 0, 0, 0,
470 0);
476 471
477 r600_hdmi_audio_workaround(encoder); 472 r600_hdmi_audio_workaround(encoder);
478} 473}
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9783178a8ff0..1dc3a4aba020 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1094,7 +1094,6 @@ int radeon_pm_get_type_index(struct radeon_device *rdev,
1094 int instance); 1094 int instance);
1095 1095
1096struct r600_audio { 1096struct r600_audio {
1097 bool enabled;
1098 int channels; 1097 int channels;
1099 int rate; 1098 int rate;
1100 int bits_per_sample; 1099 int bits_per_sample;
@@ -1535,7 +1534,8 @@ struct radeon_device {
1535 int num_crtc; /* number of crtcs */ 1534 int num_crtc; /* number of crtcs */
1536 struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */ 1535 struct mutex dc_hw_i2c_mutex; /* display controller hw i2c mutex */
1537 struct mutex vram_mutex; 1536 struct mutex vram_mutex;
1538 struct r600_audio audio; /* audio stuff */ 1537 bool audio_enabled;
1538 struct r600_audio audio_status; /* audio stuff */
1539 struct notifier_block acpi_nb; 1539 struct notifier_block acpi_nb;
1540 /* only one userspace can use Hyperz features or CMASK at a time */ 1540 /* only one userspace can use Hyperz features or CMASK at a time */
1541 struct drm_file *hyperz_filp; 1541 struct drm_file *hyperz_filp;
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index ef9ccb4def4d..e76a941ef14e 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -356,13 +356,8 @@ void r600_disable_interrupts(struct radeon_device *rdev);
356void r600_rlc_stop(struct radeon_device *rdev); 356void r600_rlc_stop(struct radeon_device *rdev);
357/* r600 audio */ 357/* r600 audio */
358int r600_audio_init(struct radeon_device *rdev); 358int r600_audio_init(struct radeon_device *rdev);
359int r600_audio_tmds_index(struct drm_encoder *encoder);
360void r600_audio_set_clock(struct drm_encoder *encoder, int clock); 359void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
361int r600_audio_channels(struct radeon_device *rdev); 360struct r600_audio r600_audio_status(struct radeon_device *rdev);
362int r600_audio_bits_per_sample(struct radeon_device *rdev);
363int r600_audio_rate(struct radeon_device *rdev);
364uint8_t r600_audio_status_bits(struct radeon_device *rdev);
365uint8_t r600_audio_category_code(struct radeon_device *rdev);
366void r600_audio_fini(struct radeon_device *rdev); 361void r600_audio_fini(struct radeon_device *rdev);
367int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); 362int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
368void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); 363void r600_hdmi_update_audio_settings(struct drm_encoder *encoder);