mirror of
https://github.com/torvalds/linux.git
synced 2024-11-01 09:41:44 +00:00
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>
This commit is contained in:
parent
61cf059325
commit
58bd086313
@ -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,11 +178,36 @@ int r600_audio_init(struct radeon_device *rdev)
|
||||
r600_audio_update_hdmi,
|
||||
(unsigned long)rdev);
|
||||
|
||||
mod_timer(&rdev->audio_timer, jiffies + 1);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* atach the audio codec to the clock source of the encoder
|
||||
*/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user