aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600_audio.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_audio.c')
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c215
1 files changed, 83 insertions, 132 deletions
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index ba66f3093d46..7c4fa77f018f 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -29,7 +29,28 @@
29#include "radeon_asic.h" 29#include "radeon_asic.h"
30#include "atom.h" 30#include "atom.h"
31 31
32#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */ 32/*
33 * check if enc_priv stores radeon_encoder_atom_dig
34 */
35static bool radeon_dig_encoder(struct drm_encoder *encoder)
36{
37 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
38 switch (radeon_encoder->encoder_id) {
39 case ENCODER_OBJECT_ID_INTERNAL_LVDS:
40 case ENCODER_OBJECT_ID_INTERNAL_TMDS1:
41 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
42 case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
43 case ENCODER_OBJECT_ID_INTERNAL_DVO1:
44 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
45 case ENCODER_OBJECT_ID_INTERNAL_DDI:
46 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
47 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
48 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
49 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
50 return true;
51 }
52 return false;
53}
33 54
34/* 55/*
35 * check if the chipset is supported 56 * check if the chipset is supported
@@ -42,118 +63,85 @@ static int r600_audio_chipset_supported(struct radeon_device *rdev)
42 || rdev->family == CHIP_RS740; 63 || rdev->family == CHIP_RS740;
43} 64}
44 65
45/* 66struct r600_audio r600_audio_status(struct radeon_device *rdev)
46 * current number of channels
47 */
48int r600_audio_channels(struct radeon_device *rdev)
49{ 67{
50 return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; 68 struct r600_audio status;
51} 69 uint32_t value;
52 70
53/* 71 value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
54 * current bits per sample
55 */
56int r600_audio_bits_per_sample(struct radeon_device *rdev)
57{
58 uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
59 switch (value) {
60 case 0x0: return 8;
61 case 0x1: return 16;
62 case 0x2: return 20;
63 case 0x3: return 24;
64 case 0x4: return 32;
65 }
66 72
67 dev_err(rdev->dev, "Unknown bits per sample 0x%x using 16 instead\n", 73 /* number of channels */
68 (int)value); 74 status.channels = (value & 0x7) + 1;
69 75
70 return 16; 76 /* bits per sample */
71} 77 switch ((value & 0xF0) >> 4) {
72 78 case 0x0:
73/* 79 status.bits_per_sample = 8;
74 * current sampling rate in HZ 80 break;
75 */ 81 case 0x1:
76int r600_audio_rate(struct radeon_device *rdev) 82 status.bits_per_sample = 16;
77{ 83 break;
78 uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); 84 case 0x2:
79 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 }
80 98
99 /* current sampling rate in HZ */
81 if (value & 0x4000) 100 if (value & 0x4000)
82 result = 44100; 101 status.rate = 44100;
83 else 102 else
84 result = 48000; 103 status.rate = 48000;
104 status.rate *= ((value >> 11) & 0x7) + 1;
105 status.rate /= ((value >> 8) & 0x7) + 1;
85 106
86 result *= ((value >> 11) & 0x7) + 1; 107 value = RREG32(R600_AUDIO_STATUS_BITS);
87 result /= ((value >> 8) & 0x7) + 1;
88 108
89 return result; 109 /* iec 60958 status bits */
90} 110 status.status_bits = value & 0xff;
91 111
92/* 112 /* iec 60958 category code */
93 * iec 60958 status bits 113 status.category_code = (value >> 8) & 0xff;
94 */
95uint8_t r600_audio_status_bits(struct radeon_device *rdev)
96{
97 return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
98}
99 114
100/* 115 return status;
101 * iec 60958 category code
102 */
103uint8_t r600_audio_category_code(struct radeon_device *rdev)
104{
105 return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
106}
107
108/*
109 * schedule next audio update event
110 */
111void r600_audio_schedule_polling(struct radeon_device *rdev)
112{
113 mod_timer(&rdev->audio_timer,
114 jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));
115} 116}
116 117
117/* 118/*
118 * update all hdmi interfaces with current audio parameters 119 * update all hdmi interfaces with current audio parameters
119 */ 120 */
120static void r600_audio_update_hdmi(unsigned long param) 121void r600_audio_update_hdmi(struct work_struct *work)
121{ 122{
122 struct radeon_device *rdev = (struct radeon_device *)param; 123 struct radeon_device *rdev = container_of(work, struct radeon_device,
124 audio_work);
123 struct drm_device *dev = rdev->ddev; 125 struct drm_device *dev = rdev->ddev;
124 126 struct r600_audio audio_status = r600_audio_status(rdev);
125 int channels = r600_audio_channels(rdev);
126 int rate = r600_audio_rate(rdev);
127 int bps = r600_audio_bits_per_sample(rdev);
128 uint8_t status_bits = r600_audio_status_bits(rdev);
129 uint8_t category_code = r600_audio_category_code(rdev);
130
131 struct drm_encoder *encoder; 127 struct drm_encoder *encoder;
132 int changes = 0, still_going = 0; 128 bool changed = false;
133 129
134 changes |= channels != rdev->audio_channels; 130 if (rdev->audio_status.channels != audio_status.channels ||
135 changes |= rate != rdev->audio_rate; 131 rdev->audio_status.rate != audio_status.rate ||
136 changes |= bps != rdev->audio_bits_per_sample; 132 rdev->audio_status.bits_per_sample != audio_status.bits_per_sample ||
137 changes |= status_bits != rdev->audio_status_bits; 133 rdev->audio_status.status_bits != audio_status.status_bits ||
138 changes |= category_code != rdev->audio_category_code; 134 rdev->audio_status.category_code != audio_status.category_code) {
139 135 rdev->audio_status = audio_status;
140 if (changes) { 136 changed = true;
141 rdev->audio_channels = channels;
142 rdev->audio_rate = rate;
143 rdev->audio_bits_per_sample = bps;
144 rdev->audio_status_bits = status_bits;
145 rdev->audio_category_code = category_code;
146 } 137 }
147 138
148 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 139 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
149 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 140 if (!radeon_dig_encoder(encoder))
150 still_going |= radeon_encoder->audio_polling_active; 141 continue;
151 if (changes || r600_hdmi_buffer_status_changed(encoder)) 142 if (changed || r600_hdmi_buffer_status_changed(encoder))
152 r600_hdmi_update_audio_settings(encoder); 143 r600_hdmi_update_audio_settings(encoder);
153 } 144 }
154
155 if (still_going)
156 r600_audio_schedule_polling(rdev);
157} 145}
158 146
159/* 147/*
@@ -177,7 +165,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable)
177} 165}
178 166
179/* 167/*
180 * initialize the audio vars and register the update timer 168 * initialize the audio vars
181 */ 169 */
182int r600_audio_init(struct radeon_device *rdev) 170int r600_audio_init(struct radeon_device *rdev)
183{ 171{
@@ -186,51 +174,16 @@ int r600_audio_init(struct radeon_device *rdev)
186 174
187 r600_audio_engine_enable(rdev, true); 175 r600_audio_engine_enable(rdev, true);
188 176
189 rdev->audio_channels = -1; 177 rdev->audio_status.channels = -1;
190 rdev->audio_rate = -1; 178 rdev->audio_status.rate = -1;
191 rdev->audio_bits_per_sample = -1; 179 rdev->audio_status.bits_per_sample = -1;
192 rdev->audio_status_bits = 0; 180 rdev->audio_status.status_bits = 0;
193 rdev->audio_category_code = 0; 181 rdev->audio_status.category_code = 0;
194
195 setup_timer(
196 &rdev->audio_timer,
197 r600_audio_update_hdmi,
198 (unsigned long)rdev);
199 182
200 return 0; 183 return 0;
201} 184}
202 185
203/* 186/*
204 * enable the polling timer, to check for status changes
205 */
206void r600_audio_enable_polling(struct drm_encoder *encoder)
207{
208 struct drm_device *dev = encoder->dev;
209 struct radeon_device *rdev = dev->dev_private;
210 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
211
212 DRM_DEBUG("r600_audio_enable_polling: %d\n",
213 radeon_encoder->audio_polling_active);
214 if (radeon_encoder->audio_polling_active)
215 return;
216
217 radeon_encoder->audio_polling_active = 1;
218 if (rdev->audio_enabled)
219 mod_timer(&rdev->audio_timer, jiffies + 1);
220}
221
222/*
223 * disable the polling timer, so we get no more status updates
224 */
225void r600_audio_disable_polling(struct drm_encoder *encoder)
226{
227 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
228 DRM_DEBUG("r600_audio_disable_polling: %d\n",
229 radeon_encoder->audio_polling_active);
230 radeon_encoder->audio_polling_active = 0;
231}
232
233/*
234 * atach the audio codec to the clock source of the encoder 187 * atach the audio codec to the clock source of the encoder
235 */ 188 */
236void r600_audio_set_clock(struct drm_encoder *encoder, int clock) 189void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
@@ -297,7 +250,5 @@ void r600_audio_fini(struct radeon_device *rdev)
297 if (!rdev->audio_enabled) 250 if (!rdev->audio_enabled)
298 return; 251 return;
299 252
300 del_timer(&rdev->audio_timer);
301
302 r600_audio_engine_enable(rdev, false); 253 r600_audio_engine_enable(rdev, false);
303} 254}