2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Christian König.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
24 * Authors: Christian König
28 #include "radeon_reg.h"
29 #include "radeon_asic.h"
33 * check if enc_priv stores radeon_encoder_atom_dig
35 static bool radeon_dig_encoder(struct drm_encoder
*encoder
)
37 struct radeon_encoder
*radeon_encoder
= to_radeon_encoder(encoder
);
38 switch (radeon_encoder
->encoder_id
) {
39 case ENCODER_OBJECT_ID_INTERNAL_LVDS
:
40 case ENCODER_OBJECT_ID_INTERNAL_TMDS1
:
41 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
42 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
43 case ENCODER_OBJECT_ID_INTERNAL_DVO1
:
44 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1
:
45 case ENCODER_OBJECT_ID_INTERNAL_DDI
:
46 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
47 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
48 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
49 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
56 * check if the chipset is supported
58 static int r600_audio_chipset_supported(struct radeon_device
*rdev
)
60 return (rdev
->family
>= CHIP_R600
&& !ASIC_IS_DCE6(rdev
))
61 || rdev
->family
== CHIP_RS600
62 || rdev
->family
== CHIP_RS690
63 || rdev
->family
== CHIP_RS740
;
66 struct r600_audio
r600_audio_status(struct radeon_device
*rdev
)
68 struct r600_audio status
;
71 value
= RREG32(R600_AUDIO_RATE_BPS_CHANNEL
);
73 /* number of channels */
74 status
.channels
= (value
& 0x7) + 1;
77 switch ((value
& 0xF0) >> 4) {
79 status
.bits_per_sample
= 8;
82 status
.bits_per_sample
= 16;
85 status
.bits_per_sample
= 20;
88 status
.bits_per_sample
= 24;
91 status
.bits_per_sample
= 32;
94 dev_err(rdev
->dev
, "Unknown bits per sample 0x%x, using 16\n",
96 status
.bits_per_sample
= 16;
99 /* current sampling rate in HZ */
104 status
.rate
*= ((value
>> 11) & 0x7) + 1;
105 status
.rate
/= ((value
>> 8) & 0x7) + 1;
107 value
= RREG32(R600_AUDIO_STATUS_BITS
);
109 /* iec 60958 status bits */
110 status
.status_bits
= value
& 0xff;
112 /* iec 60958 category code */
113 status
.category_code
= (value
>> 8) & 0xff;
119 * update all hdmi interfaces with current audio parameters
121 void r600_audio_update_hdmi(struct work_struct
*work
)
123 struct radeon_device
*rdev
= container_of(work
, struct radeon_device
,
125 struct drm_device
*dev
= rdev
->ddev
;
126 struct r600_audio audio_status
= r600_audio_status(rdev
);
127 struct drm_encoder
*encoder
;
128 bool changed
= false;
130 if (rdev
->audio_status
.channels
!= audio_status
.channels
||
131 rdev
->audio_status
.rate
!= audio_status
.rate
||
132 rdev
->audio_status
.bits_per_sample
!= audio_status
.bits_per_sample
||
133 rdev
->audio_status
.status_bits
!= audio_status
.status_bits
||
134 rdev
->audio_status
.category_code
!= audio_status
.category_code
) {
135 rdev
->audio_status
= audio_status
;
139 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
140 if (!radeon_dig_encoder(encoder
))
142 if (changed
|| r600_hdmi_buffer_status_changed(encoder
))
143 r600_hdmi_update_audio_settings(encoder
);
148 * turn on/off audio engine
150 static void r600_audio_engine_enable(struct radeon_device
*rdev
, bool enable
)
153 DRM_INFO("%s audio support\n", enable
? "Enabling" : "Disabling");
154 if (ASIC_IS_DCE4(rdev
)) {
156 value
|= 0x81000000; /* Required to enable audio */
157 value
|= 0x0e1000f0; /* fglrx sets that too */
159 WREG32(EVERGREEN_AUDIO_ENABLE
, value
);
161 WREG32_P(R600_AUDIO_ENABLE
,
162 enable
? 0x81000000 : 0x0, ~0x81000000);
164 rdev
->audio_enabled
= enable
;
168 * initialize the audio vars
170 int r600_audio_init(struct radeon_device
*rdev
)
172 if (!radeon_audio
|| !r600_audio_chipset_supported(rdev
))
175 r600_audio_engine_enable(rdev
, true);
177 rdev
->audio_status
.channels
= -1;
178 rdev
->audio_status
.rate
= -1;
179 rdev
->audio_status
.bits_per_sample
= -1;
180 rdev
->audio_status
.status_bits
= 0;
181 rdev
->audio_status
.category_code
= 0;
187 * atach the audio codec to the clock source of the encoder
189 void r600_audio_set_clock(struct drm_encoder
*encoder
, int clock
)
191 struct drm_device
*dev
= encoder
->dev
;
192 struct radeon_device
*rdev
= dev
->dev_private
;
193 struct radeon_encoder
*radeon_encoder
= to_radeon_encoder(encoder
);
194 struct radeon_encoder_atom_dig
*dig
= radeon_encoder
->enc_priv
;
195 struct radeon_crtc
*radeon_crtc
= to_radeon_crtc(encoder
->crtc
);
196 int base_rate
= 48000;
198 switch (radeon_encoder
->encoder_id
) {
199 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1
:
200 case ENCODER_OBJECT_ID_INTERNAL_LVTM1
:
201 WREG32_P(R600_AUDIO_TIMING
, 0, ~0x301);
203 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY
:
204 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1
:
205 case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2
:
206 case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA
:
207 WREG32_P(R600_AUDIO_TIMING
, 0x100, ~0x301);
210 dev_err(rdev
->dev
, "Unsupported encoder type 0x%02X\n",
211 radeon_encoder
->encoder_id
);
215 if (ASIC_IS_DCE4(rdev
)) {
216 /* TODO: other PLLs? */
217 WREG32(EVERGREEN_AUDIO_PLL1_MUL
, base_rate
* 10);
218 WREG32(EVERGREEN_AUDIO_PLL1_DIV
, clock
* 10);
219 WREG32(EVERGREEN_AUDIO_PLL1_UNK
, 0x00000071);
221 /* Select DTO source */
222 WREG32(0x5ac, radeon_crtc
->crtc_id
);
224 switch (dig
->dig_encoder
) {
226 WREG32(R600_AUDIO_PLL1_MUL
, base_rate
* 50);
227 WREG32(R600_AUDIO_PLL1_DIV
, clock
* 100);
228 WREG32(R600_AUDIO_CLK_SRCSEL
, 0);
232 WREG32(R600_AUDIO_PLL2_MUL
, base_rate
* 50);
233 WREG32(R600_AUDIO_PLL2_DIV
, clock
* 100);
234 WREG32(R600_AUDIO_CLK_SRCSEL
, 1);
238 "Unsupported DIG on encoder 0x%02X\n",
239 radeon_encoder
->encoder_id
);
246 * release the audio timer
247 * TODO: How to do this correctly on SMP systems?
249 void r600_audio_fini(struct radeon_device
*rdev
)
251 if (!rdev
->audio_enabled
)
254 r600_audio_engine_enable(rdev
, false);