diff options
author | Christian König <deathsimple@vodafone.de> | 2010-04-05 22:14:55 +0200 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-23 14:11:17 +1000 |
commit | 58bd086313ea0eda037f65b9bda2b3decb959a31 (patch) | |
tree | 7d82481314d6e3c27a3639f99e115dd672a6ac6e /drivers | |
parent | 61cf059325a30995a78c5001db2ed2a8ab1d4c36 (diff) | |
download | op-kernel-dev-58bd086313ea0eda037f65b9bda2b3decb959a31.zip op-kernel-dev-58bd086313ea0eda037f65b9bda2b3decb959a31.tar.gz |
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')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_audio.c | 55 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600_hdmi.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_mode.h | 1 |
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 1d89805..ed8d398 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) /* * current number of channels */ -static int r600_audio_channels(struct radeon_device *rdev) +int r600_audio_channels(struct radeon_device *rdev) { return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; } @@ -52,7 +52,7 @@ static int r600_audio_channels(struct radeon_device *rdev) /* * current bits per sample */ -static int r600_audio_bits_per_sample(struct radeon_device *rdev) +int r600_audio_bits_per_sample(struct radeon_device *rdev) { uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4; switch (value) { @@ -71,7 +71,7 @@ static int r600_audio_bits_per_sample(struct radeon_device *rdev) /* * current sampling rate in HZ */ -static int r600_audio_rate(struct radeon_device *rdev) +int r600_audio_rate(struct radeon_device *rdev) { uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); uint32_t result; @@ -90,7 +90,7 @@ static int r600_audio_rate(struct radeon_device *rdev) /* * iec 60958 status bits */ -static uint8_t r600_audio_status_bits(struct radeon_device *rdev) +uint8_t r600_audio_status_bits(struct radeon_device *rdev) { return RREG32(R600_AUDIO_STATUS_BITS) & 0xff; } @@ -98,7 +98,7 @@ static uint8_t r600_audio_status_bits(struct radeon_device *rdev) /* * iec 60958 category code */ -static uint8_t r600_audio_category_code(struct radeon_device *rdev) +uint8_t r600_audio_category_code(struct radeon_device *rdev) { return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff; } @@ -118,7 +118,7 @@ static void r600_audio_update_hdmi(unsigned long param) uint8_t category_code = r600_audio_category_code(rdev); struct drm_encoder *encoder; - int changes = 0; + int changes = 0, still_going = 0; changes |= channels != rdev->audio_channels; changes |= rate != rdev->audio_rate; @@ -135,15 +135,17 @@ static void r600_audio_update_hdmi(unsigned long param) } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (changes || r600_hdmi_buffer_status_changed(encoder)) - r600_hdmi_update_audio_settings( - encoder, channels, - rate, bps, status_bits, - category_code); + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + if (radeon_encoder->audio_polling_active) { + still_going = 1; + if (changes || r600_hdmi_buffer_status_changed(encoder)) + r600_hdmi_update_audio_settings(encoder); + } } - mod_timer(&rdev->audio_timer, - jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); + if(still_going) + mod_timer(&rdev->audio_timer, + jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL)); } /* @@ -176,9 +178,34 @@ int r600_audio_init(struct radeon_device *rdev) r600_audio_update_hdmi, (unsigned long)rdev); + return 0; +} + +/* + * enable the polling timer, to check for status changes + */ +void r600_audio_enable_polling(struct drm_encoder *encoder) +{ + struct drm_device *dev = encoder->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + + DRM_DEBUG("r600_audio_enable_polling: %d", radeon_encoder->audio_polling_active); + if (radeon_encoder->audio_polling_active) + return; + + radeon_encoder->audio_polling_active = 1; mod_timer(&rdev->audio_timer, jiffies + 1); +} - return 0; +/* + * disable the polling timer, so we get no more status updates + */ +void r600_audio_disable_polling(struct drm_encoder *encoder) +{ + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + DRM_DEBUG("r600_audio_disable_polling: %d", radeon_encoder->audio_polling_active); + radeon_encoder->audio_polling_active = 0; } /* diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 2616b82..d014472 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 /* * update settings with current parameters from audio engine */ -void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, - int channels, - int rate, - int bps, - uint8_t status_bits, - uint8_t category_code) +void r600_hdmi_update_audio_settings(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; + int channels = r600_audio_channels(rdev); + int rate = r600_audio_rate(rdev); + int bps = r600_audio_bits_per_sample(rdev); + uint8_t status_bits = r600_audio_status_bits(rdev); + uint8_t category_code = r600_audio_category_code(rdev); + uint32_t iec; if (!offset) @@ -518,6 +519,8 @@ void r600_hdmi_enable(struct drm_encoder *encoder) } } + r600_audio_enable_polling(encoder); + DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n", radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); } @@ -539,6 +542,8 @@ void r600_hdmi_disable(struct drm_encoder *encoder) return; } + r600_audio_disable_polling(encoder); + DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n", radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index e912098..42217af 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); extern int r600_audio_init(struct radeon_device *rdev); extern int r600_audio_tmds_index(struct drm_encoder *encoder); extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); +extern int r600_audio_channels(struct radeon_device *rdev); +extern int r600_audio_bits_per_sample(struct radeon_device *rdev); +extern int r600_audio_rate(struct radeon_device *rdev); +extern uint8_t r600_audio_status_bits(struct radeon_device *rdev); +extern uint8_t r600_audio_category_code(struct radeon_device *rdev); +extern void r600_audio_enable_polling(struct drm_encoder *encoder); +extern void r600_audio_disable_polling(struct drm_encoder *encoder); extern void r600_audio_fini(struct radeon_device *rdev); extern void r600_hdmi_init(struct drm_encoder *encoder); extern void r600_hdmi_enable(struct drm_encoder *encoder); extern void r600_hdmi_disable(struct drm_encoder *encoder); extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); -extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, - int channels, - int rate, - int bps, - uint8_t status_bits, - uint8_t category_code); +extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); extern void r700_cp_stop(struct radeon_device *rdev); extern 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 4a086c0..dd451c5 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -345,6 +345,7 @@ struct radeon_encoder { enum radeon_rmx_type rmx_type; struct drm_display_mode native_mode; void *enc_priv; + int audio_polling_active; int hdmi_offset; int hdmi_config_offset; int hdmi_audio_workaround; |