diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-07-31 16:51:33 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-08-30 16:30:45 -0400 |
commit | b530602fd4625f763344e455902981b22f85f609 (patch) | |
tree | fb1c932b2bf74b76fbbdc198d527a698088500c2 /drivers/gpu/drm/radeon/r600_audio.c | |
parent | a4d39e68949f5b4f7b426be63782b421018f741a (diff) |
drm/radeon: add audio support for DCE6/8 GPUs (v12)
Similar to DCE4/5, but supports multiple audio pins
which can be assigned per afmt block.
v2: rework the driver to handle more than one audio
pin.
v3: try different dto reg
v4: properly program dto
v5 (ck): change dto programming order
v6: program speaker allocation block
v7: rebase
v8: rebase on Rafał's changes
v9: integrated Rafał's comments, update to latest
drm_edid_to_speaker_allocation API
v10: add missing line break in error message
v11: add back audio enabled messages
v12: fix copy paste typo in r600_audio_enable
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Rafał Miłecki <zajec5@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600_audio.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600_audio.c | 60 |
1 files changed, 36 insertions, 24 deletions
diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index c92eb86a8e55..47fc2b886979 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c | |||
@@ -57,12 +57,12 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) | |||
57 | */ | 57 | */ |
58 | static int r600_audio_chipset_supported(struct radeon_device *rdev) | 58 | static int r600_audio_chipset_supported(struct radeon_device *rdev) |
59 | { | 59 | { |
60 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_DCE6(rdev); | 60 | return ASIC_IS_DCE2(rdev) && !ASIC_IS_NODCE(rdev); |
61 | } | 61 | } |
62 | 62 | ||
63 | struct r600_audio r600_audio_status(struct radeon_device *rdev) | 63 | struct r600_audio_pin r600_audio_status(struct radeon_device *rdev) |
64 | { | 64 | { |
65 | struct r600_audio status; | 65 | struct r600_audio_pin status; |
66 | uint32_t value; | 66 | uint32_t value; |
67 | 67 | ||
68 | value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); | 68 | value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL); |
@@ -120,16 +120,16 @@ void r600_audio_update_hdmi(struct work_struct *work) | |||
120 | struct radeon_device *rdev = container_of(work, struct radeon_device, | 120 | struct radeon_device *rdev = container_of(work, struct radeon_device, |
121 | audio_work); | 121 | audio_work); |
122 | struct drm_device *dev = rdev->ddev; | 122 | struct drm_device *dev = rdev->ddev; |
123 | struct r600_audio audio_status = r600_audio_status(rdev); | 123 | struct r600_audio_pin audio_status = r600_audio_status(rdev); |
124 | struct drm_encoder *encoder; | 124 | struct drm_encoder *encoder; |
125 | bool changed = false; | 125 | bool changed = false; |
126 | 126 | ||
127 | if (rdev->audio_status.channels != audio_status.channels || | 127 | if (rdev->audio.pin[0].channels != audio_status.channels || |
128 | rdev->audio_status.rate != audio_status.rate || | 128 | rdev->audio.pin[0].rate != audio_status.rate || |
129 | rdev->audio_status.bits_per_sample != audio_status.bits_per_sample || | 129 | rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample || |
130 | rdev->audio_status.status_bits != audio_status.status_bits || | 130 | rdev->audio.pin[0].status_bits != audio_status.status_bits || |
131 | rdev->audio_status.category_code != audio_status.category_code) { | 131 | rdev->audio.pin[0].category_code != audio_status.category_code) { |
132 | rdev->audio_status = audio_status; | 132 | rdev->audio.pin[0] = audio_status; |
133 | changed = true; | 133 | changed = true; |
134 | } | 134 | } |
135 | 135 | ||
@@ -141,13 +141,13 @@ void r600_audio_update_hdmi(struct work_struct *work) | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | /* | 144 | /* enable the audio stream */ |
145 | * turn on/off audio engine | 145 | static void r600_audio_enable(struct radeon_device *rdev, |
146 | */ | 146 | struct r600_audio_pin *pin, |
147 | static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) | 147 | bool enable) |
148 | { | 148 | { |
149 | u32 value = 0; | 149 | u32 value = 0; |
150 | DRM_INFO("%s audio support\n", enable ? "Enabling" : "Disabling"); | 150 | |
151 | if (ASIC_IS_DCE4(rdev)) { | 151 | if (ASIC_IS_DCE4(rdev)) { |
152 | if (enable) { | 152 | if (enable) { |
153 | value |= 0x81000000; /* Required to enable audio */ | 153 | value |= 0x81000000; /* Required to enable audio */ |
@@ -158,7 +158,7 @@ static void r600_audio_engine_enable(struct radeon_device *rdev, bool enable) | |||
158 | WREG32_P(R600_AUDIO_ENABLE, | 158 | WREG32_P(R600_AUDIO_ENABLE, |
159 | enable ? 0x81000000 : 0x0, ~0x81000000); | 159 | enable ? 0x81000000 : 0x0, ~0x81000000); |
160 | } | 160 | } |
161 | rdev->audio_enabled = enable; | 161 | DRM_INFO("%s audio %d support\n", enable ? "Enabling" : "Disabling", pin->id); |
162 | } | 162 | } |
163 | 163 | ||
164 | /* | 164 | /* |
@@ -169,13 +169,17 @@ int r600_audio_init(struct radeon_device *rdev) | |||
169 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) | 169 | if (!radeon_audio || !r600_audio_chipset_supported(rdev)) |
170 | return 0; | 170 | return 0; |
171 | 171 | ||
172 | r600_audio_engine_enable(rdev, true); | 172 | rdev->audio.enabled = true; |
173 | |||
174 | rdev->audio.num_pins = 1; | ||
175 | rdev->audio.pin[0].channels = -1; | ||
176 | rdev->audio.pin[0].rate = -1; | ||
177 | rdev->audio.pin[0].bits_per_sample = -1; | ||
178 | rdev->audio.pin[0].status_bits = 0; | ||
179 | rdev->audio.pin[0].category_code = 0; | ||
180 | rdev->audio.pin[0].id = 0; | ||
173 | 181 | ||
174 | rdev->audio_status.channels = -1; | 182 | r600_audio_enable(rdev, &rdev->audio.pin[0], true); |
175 | rdev->audio_status.rate = -1; | ||
176 | rdev->audio_status.bits_per_sample = -1; | ||
177 | rdev->audio_status.status_bits = 0; | ||
178 | rdev->audio_status.category_code = 0; | ||
179 | 183 | ||
180 | return 0; | 184 | return 0; |
181 | } | 185 | } |
@@ -186,8 +190,16 @@ int r600_audio_init(struct radeon_device *rdev) | |||
186 | */ | 190 | */ |
187 | void r600_audio_fini(struct radeon_device *rdev) | 191 | void r600_audio_fini(struct radeon_device *rdev) |
188 | { | 192 | { |
189 | if (!rdev->audio_enabled) | 193 | if (!rdev->audio.enabled) |
190 | return; | 194 | return; |
191 | 195 | ||
192 | r600_audio_engine_enable(rdev, false); | 196 | r600_audio_enable(rdev, &rdev->audio.pin[0], false); |
197 | |||
198 | rdev->audio.enabled = false; | ||
199 | } | ||
200 | |||
201 | struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev) | ||
202 | { | ||
203 | /* only one pin on 6xx-NI */ | ||
204 | return &rdev->audio.pin[0]; | ||
193 | } | 205 | } |