aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2010-04-05 16:14:55 -0400
committerDave Airlie <airlied@redhat.com>2010-04-23 00:11:17 -0400
commit58bd086313ea0eda037f65b9bda2b3decb959a31 (patch)
tree7d82481314d6e3c27a3639f99e115dd672a6ac6e /drivers/gpu/drm
parent61cf059325a30995a78c5001db2ed2a8ab1d4c36 (diff)
drm/radeon/kms: rework audio polling timer
Rework HDMI audio polling timer, only enable it when at least one HDMI encoder needs it. Preparation for replacing it with irq support. Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/r600_audio.c55
-rw-r--r--drivers/gpu/drm/radeon/r600_hdmi.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon.h14
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h1
4 files changed, 61 insertions, 26 deletions
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c
index 1d898051c631..ed8d3989f172 100644
--- a/drivers/gpu/drm/radeon/r600_audio.c
+++ b/drivers/gpu/drm/radeon/r600_audio.c
@@ -44,7 +44,7 @@ static int r600_audio_chipset_supported(struct radeon_device *rdev)
44/* 44/*
45 * current number of channels 45 * current number of channels
46 */ 46 */
47static int r600_audio_channels(struct radeon_device *rdev) 47int r600_audio_channels(struct radeon_device *rdev)
48{ 48{
49 return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; 49 return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1;
50} 50}
@@ -52,7 +52,7 @@ static int r600_audio_channels(struct radeon_device *rdev)
52/* 52/*
53 * current bits per sample 53 * current bits per sample
54 */ 54 */
55static int r600_audio_bits_per_sample(struct radeon_device *rdev) 55int r600_audio_bits_per_sample(struct radeon_device *rdev)
56{ 56{
57 uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4; 57 uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
58 switch (value) { 58 switch (value) {
@@ -71,7 +71,7 @@ static int r600_audio_bits_per_sample(struct radeon_device *rdev)
71/* 71/*
72 * current sampling rate in HZ 72 * current sampling rate in HZ
73 */ 73 */
74static int r600_audio_rate(struct radeon_device *rdev) 74int r600_audio_rate(struct radeon_device *rdev)
75{ 75{
76 uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); 76 uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
77 uint32_t result; 77 uint32_t result;
@@ -90,7 +90,7 @@ static int r600_audio_rate(struct radeon_device *rdev)
90/* 90/*
91 * iec 60958 status bits 91 * iec 60958 status bits
92 */ 92 */
93static uint8_t r600_audio_status_bits(struct radeon_device *rdev) 93uint8_t r600_audio_status_bits(struct radeon_device *rdev)
94{ 94{
95 return RREG32(R600_AUDIO_STATUS_BITS) & 0xff; 95 return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
96} 96}
@@ -98,7 +98,7 @@ static uint8_t r600_audio_status_bits(struct radeon_device *rdev)
98/* 98/*
99 * iec 60958 category code 99 * iec 60958 category code
100 */ 100 */
101static uint8_t r600_audio_category_code(struct radeon_device *rdev) 101uint8_t r600_audio_category_code(struct radeon_device *rdev)
102{ 102{
103 return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff; 103 return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
104} 104}
@@ -118,7 +118,7 @@ static void r600_audio_update_hdmi(unsigned long param)
118 uint8_t category_code = r600_audio_category_code(rdev); 118 uint8_t category_code = r600_audio_category_code(rdev);
119 119
120 struct drm_encoder *encoder; 120 struct drm_encoder *encoder;
121 int changes = 0; 121 int changes = 0, still_going = 0;
122 122
123 changes |= channels != rdev->audio_channels; 123 changes |= channels != rdev->audio_channels;
124 changes |= rate != rdev->audio_rate; 124 changes |= rate != rdev->audio_rate;
@@ -135,15 +135,17 @@ static void r600_audio_update_hdmi(unsigned long param)
135 } 135 }
136 136
137 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 137 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
138 if (changes || r600_hdmi_buffer_status_changed(encoder)) 138 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
139 r600_hdmi_update_audio_settings( 139 if (radeon_encoder->audio_polling_active) {
140 encoder, channels, 140 still_going = 1;
141 rate, bps, status_bits, 141 if (changes || r600_hdmi_buffer_status_changed(encoder))
142 category_code); 142 r600_hdmi_update_audio_settings(encoder);
143 }
143 } 144 }
144 145
145 mod_timer(&rdev->audio_timer, 146 if(still_going)
146 jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); 147 mod_timer(&rdev->audio_timer,
148 jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));
147} 149}
148 150
149/* 151/*
@@ -176,9 +178,34 @@ int r600_audio_init(struct radeon_device *rdev)
176 r600_audio_update_hdmi, 178 r600_audio_update_hdmi,
177 (unsigned long)rdev); 179 (unsigned long)rdev);
178 180
181 return 0;
182}
183
184/*
185 * enable the polling timer, to check for status changes
186 */
187void r600_audio_enable_polling(struct drm_encoder *encoder)
188{
189 struct drm_device *dev = encoder->dev;
190 struct radeon_device *rdev = dev->dev_private;
191 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
192
193 DRM_DEBUG("r600_audio_enable_polling: %d", radeon_encoder->audio_polling_active);
194 if (radeon_encoder->audio_polling_active)
195 return;
196
197 radeon_encoder->audio_polling_active = 1;
179 mod_timer(&rdev->audio_timer, jiffies + 1); 198 mod_timer(&rdev->audio_timer, jiffies + 1);
199}
180 200
181 return 0; 201/*
202 * disable the polling timer, so we get no more status updates
203 */
204void r600_audio_disable_polling(struct drm_encoder *encoder)
205{
206 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
207 DRM_DEBUG("r600_audio_disable_polling: %d", radeon_encoder->audio_polling_active);
208 radeon_encoder->audio_polling_active = 0;
182} 209}
183 210
184/* 211/*
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c
index 2616b822ba68..d014472d0d3f 100644
--- a/drivers/gpu/drm/radeon/r600_hdmi.c
+++ b/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -353,17 +353,18 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod
353/* 353/*
354 * update settings with current parameters from audio engine 354 * update settings with current parameters from audio engine
355 */ 355 */
356void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, 356void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)
357 int channels,
358 int rate,
359 int bps,
360 uint8_t status_bits,
361 uint8_t category_code)
362{ 357{
363 struct drm_device *dev = encoder->dev; 358 struct drm_device *dev = encoder->dev;
364 struct radeon_device *rdev = dev->dev_private; 359 struct radeon_device *rdev = dev->dev_private;
365 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; 360 uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;
366 361
362 int channels = r600_audio_channels(rdev);
363 int rate = r600_audio_rate(rdev);
364 int bps = r600_audio_bits_per_sample(rdev);
365 uint8_t status_bits = r600_audio_status_bits(rdev);
366 uint8_t category_code = r600_audio_category_code(rdev);
367
367 uint32_t iec; 368 uint32_t iec;
368 369
369 if (!offset) 370 if (!offset)
@@ -518,6 +519,8 @@ void r600_hdmi_enable(struct drm_encoder *encoder)
518 } 519 }
519 } 520 }
520 521
522 r600_audio_enable_polling(encoder);
523
521 DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", 524 DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
522 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); 525 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
523} 526}
@@ -539,6 +542,8 @@ void r600_hdmi_disable(struct drm_encoder *encoder)
539 return; 542 return;
540 } 543 }
541 544
545 r600_audio_disable_polling(encoder);
546
542 DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", 547 DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
543 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); 548 radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
544 549
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index e9120985a652..42217af58145 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1327,18 +1327,20 @@ extern void r600_rlc_stop(struct radeon_device *rdev);
1327extern int r600_audio_init(struct radeon_device *rdev); 1327extern int r600_audio_init(struct radeon_device *rdev);
1328extern int r600_audio_tmds_index(struct drm_encoder *encoder); 1328extern int r600_audio_tmds_index(struct drm_encoder *encoder);
1329extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); 1329extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
1330extern int r600_audio_channels(struct radeon_device *rdev);
1331extern int r600_audio_bits_per_sample(struct radeon_device *rdev);
1332extern int r600_audio_rate(struct radeon_device *rdev);
1333extern uint8_t r600_audio_status_bits(struct radeon_device *rdev);
1334extern uint8_t r600_audio_category_code(struct radeon_device *rdev);
1335extern void r600_audio_enable_polling(struct drm_encoder *encoder);
1336extern void r600_audio_disable_polling(struct drm_encoder *encoder);
1330extern void r600_audio_fini(struct radeon_device *rdev); 1337extern void r600_audio_fini(struct radeon_device *rdev);
1331extern void r600_hdmi_init(struct drm_encoder *encoder); 1338extern void r600_hdmi_init(struct drm_encoder *encoder);
1332extern void r600_hdmi_enable(struct drm_encoder *encoder); 1339extern void r600_hdmi_enable(struct drm_encoder *encoder);
1333extern void r600_hdmi_disable(struct drm_encoder *encoder); 1340extern void r600_hdmi_disable(struct drm_encoder *encoder);
1334extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); 1341extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
1335extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); 1342extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
1336extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, 1343extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder);
1337 int channels,
1338 int rate,
1339 int bps,
1340 uint8_t status_bits,
1341 uint8_t category_code);
1342 1344
1343extern void r700_cp_stop(struct radeon_device *rdev); 1345extern void r700_cp_stop(struct radeon_device *rdev);
1344extern void r700_cp_fini(struct radeon_device *rdev); 1346extern void r700_cp_fini(struct radeon_device *rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 4a086c09e117..dd451c55c533 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -345,6 +345,7 @@ struct radeon_encoder {
345 enum radeon_rmx_type rmx_type; 345 enum radeon_rmx_type rmx_type;
346 struct drm_display_mode native_mode; 346 struct drm_display_mode native_mode;
347 void *enc_priv; 347 void *enc_priv;
348 int audio_polling_active;
348 int hdmi_offset; 349 int hdmi_offset;
349 int hdmi_config_offset; 350 int hdmi_config_offset;
350 int hdmi_audio_workaround; 351 int hdmi_audio_workaround;