This is needed to enable audio support on devices using polling. In case user decides to disable audio (module parameter) we still will try to use timer in r600_audio_enable_polling. This would lead to BUG in kernel/timer.c.
Signed-off-by: Rafał Miłecki zajec5@gmail.com --- Dave: I think we should not hit this without enabled hdmi support on RS6x0, so I can wait for next merge window (2.6.36). --- drivers/gpu/drm/radeon/r600_audio.c | 6 ++++-- drivers/gpu/drm/radeon/radeon.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 2b26553..631e1ed 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -160,6 +160,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) { DRM_INFO("%s audio support", enable ? "Enabling" : "Disabling"); WREG32_P(R600_AUDIO_ENABLE, enable ? 0x81000000 : 0x0, ~0x81000000); + rdev->audio_enabled = enable; }
/* @@ -200,7 +201,8 @@ void r600_audio_enable_polling(struct drm_encoder *encoder) return;
radeon_encoder->audio_polling_active = 1; - mod_timer(&rdev->audio_timer, jiffies + 1); + if (rdev->audio_enabled) + mod_timer(&rdev->audio_timer, jiffies + 1); }
/* @@ -266,7 +268,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) */ void r600_audio_fini(struct radeon_device *rdev) { - if (!radeon_audio || !r600_audio_chipset_supported(rdev)) + if (!rdev->audio_enabled) return;
del_timer(&rdev->audio_timer); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 084221d..2013dd7 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1065,6 +1065,7 @@ struct radeon_device { struct mutex vram_mutex;
/* audio stuff */ + bool audio_enabled; struct timer_list audio_timer; int audio_channels; int audio_rate;
We will need method of selecting encoder that should receive HDMI block. For now we assign HDMI block to first enabled encoder. Hopefully there are not many RS6x0 chips with two digital encoders.
Signed-off-by: Rafał Miłecki zajec5@gmail.com --- Is there anyone with RS6x0 and HDMI audio received around? --- drivers/gpu/drm/radeon/r600_hdmi.c | 3 ++- drivers/gpu/drm/radeon/rs600.c | 9 +++++++++ drivers/gpu/drm/radeon/rs690.c | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 26b4bc9..ecfad68 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -466,7 +466,8 @@ static void r600_hdmi_assign_block(struct drm_encoder *encoder) if (ASIC_IS_DCE32(rdev)) radeon_encoder->hdmi_config_offset = dig->dig_encoder ? R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1; - } else if (rdev->family >= CHIP_R600) { + } else if (rdev->family >= CHIP_R600 || rdev->family == CHIP_RS600 || + rdev->family == CHIP_RS690) { radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev); } } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 7bb4c3e..7771fa8 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -812,6 +812,13 @@ static int rs600_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing IB (%d).\n", r); return r; } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; }
@@ -838,6 +845,7 @@ int rs600_resume(struct radeon_device *rdev)
int rs600_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); rs600_irq_disable(rdev); @@ -847,6 +855,7 @@ int rs600_suspend(struct radeon_device *rdev)
void rs600_fini(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev); diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index bcc3319..89f8d57 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -641,6 +641,13 @@ static int rs690_startup(struct radeon_device *rdev) dev_err(rdev->dev, "failled initializing IB (%d).\n", r); return r; } + + r = r600_audio_init(rdev); + if (r) { + dev_err(rdev->dev, "failed initializing audio\n"); + return r; + } + return 0; }
@@ -667,6 +674,7 @@ int rs690_resume(struct radeon_device *rdev)
int rs690_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_disable(rdev); r100_wb_disable(rdev); rs600_irq_disable(rdev); @@ -676,6 +684,7 @@ int rs690_suspend(struct radeon_device *rdev)
void rs690_fini(struct radeon_device *rdev) { + r600_audio_fini(rdev); r100_cp_fini(rdev); r100_wb_fini(rdev); r100_ib_fini(rdev);
dri-devel@lists.freedesktop.org