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 ASIC_IS_DCE2(rdev
) && !ASIC_IS_NODCE(rdev
);
63 struct r600_audio_pin
r600_audio_status(struct radeon_device
*rdev
)
65 struct r600_audio_pin status
;
68 value
= RREG32(R600_AUDIO_RATE_BPS_CHANNEL
);
70 /* number of channels */
71 status
.channels
= (value
& 0x7) + 1;
74 switch ((value
& 0xF0) >> 4) {
76 status
.bits_per_sample
= 8;
79 status
.bits_per_sample
= 16;
82 status
.bits_per_sample
= 20;
85 status
.bits_per_sample
= 24;
88 status
.bits_per_sample
= 32;
91 dev_err(rdev
->dev
, "Unknown bits per sample 0x%x, using 16\n",
93 status
.bits_per_sample
= 16;
96 /* current sampling rate in HZ */
101 status
.rate
*= ((value
>> 11) & 0x7) + 1;
102 status
.rate
/= ((value
>> 8) & 0x7) + 1;
104 value
= RREG32(R600_AUDIO_STATUS_BITS
);
106 /* iec 60958 status bits */
107 status
.status_bits
= value
& 0xff;
109 /* iec 60958 category code */
110 status
.category_code
= (value
>> 8) & 0xff;
116 * update all hdmi interfaces with current audio parameters
118 void r600_audio_update_hdmi(struct work_struct
*work
)
120 struct radeon_device
*rdev
= container_of(work
, struct radeon_device
,
122 struct drm_device
*dev
= rdev
->ddev
;
123 struct r600_audio_pin audio_status
= r600_audio_status(rdev
);
124 struct drm_encoder
*encoder
;
125 bool changed
= false;
127 if (rdev
->audio
.pin
[0].channels
!= audio_status
.channels
||
128 rdev
->audio
.pin
[0].rate
!= audio_status
.rate
||
129 rdev
->audio
.pin
[0].bits_per_sample
!= audio_status
.bits_per_sample
||
130 rdev
->audio
.pin
[0].status_bits
!= audio_status
.status_bits
||
131 rdev
->audio
.pin
[0].category_code
!= audio_status
.category_code
) {
132 rdev
->audio
.pin
[0] = audio_status
;
136 list_for_each_entry(encoder
, &dev
->mode_config
.encoder_list
, head
) {
137 if (!radeon_dig_encoder(encoder
))
139 if (changed
|| r600_hdmi_buffer_status_changed(encoder
))
140 r600_hdmi_update_audio_settings(encoder
);
144 /* enable the audio stream */
145 void r600_audio_enable(struct radeon_device
*rdev
,
146 struct r600_audio_pin
*pin
,
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);
167 * initialize the audio vars
169 int r600_audio_init(struct radeon_device
*rdev
)
171 if (!radeon_audio
|| !r600_audio_chipset_supported(rdev
))
174 rdev
->audio
.enabled
= true;
176 rdev
->audio
.num_pins
= 1;
177 rdev
->audio
.pin
[0].channels
= -1;
178 rdev
->audio
.pin
[0].rate
= -1;
179 rdev
->audio
.pin
[0].bits_per_sample
= -1;
180 rdev
->audio
.pin
[0].status_bits
= 0;
181 rdev
->audio
.pin
[0].category_code
= 0;
182 rdev
->audio
.pin
[0].id
= 0;
183 /* disable audio. it will be set up later */
184 r600_audio_enable(rdev
, &rdev
->audio
.pin
[0], false);
190 * release the audio timer
191 * TODO: How to do this correctly on SMP systems?
193 void r600_audio_fini(struct radeon_device
*rdev
)
195 if (!rdev
->audio
.enabled
)
198 r600_audio_enable(rdev
, &rdev
->audio
.pin
[0], false);
200 rdev
->audio
.enabled
= false;
203 struct r600_audio_pin
*r600_audio_get_pin(struct radeon_device
*rdev
)
205 /* only one pin on 6xx-NI */
206 return &rdev
->audio
.pin
[0];