Bug Summary

File:dev/pci/drm/amd/display/dc/dce/dce_audio.c
Warning:line 388, column 2
Value stored to 'value' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dce_audio.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/drm/amd/display/dc/dce/dce_audio.c
1/*
2 * Copyright 2012-15 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#include "reg_helper.h"
27#include "dce_audio.h"
28#include "dce/dce_11_0_d.h"
29#include "dce/dce_11_0_sh_mask.h"
30
31#define DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
\
32 container_of(audio, struct dce_audio, base)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
33
34#define CTXaud->base.ctx \
35 aud->base.ctx
36
37#define DC_LOGGER_INIT()
38
39#define REG(reg)(aud->regs->reg)\
40 (aud->regs->reg)
41
42#undef FN
43#define FN(reg_name, field_name)aud->shifts->field_name, aud->masks->field_name \
44 aud->shifts->field_name, aud->masks->field_name
45
46#define IX_REG(reg)ixreg\
47 ix ## reg
48
49#define AZ_REG_READ(reg_name)read_indirect_azalia_reg(audio, ixreg_name) \
50 read_indirect_azalia_reg(audio, IX_REG(reg_name)ixreg_name)
51
52#define AZ_REG_WRITE(reg_name, value)write_indirect_azalia_reg(audio, ixreg_name, value) \
53 write_indirect_azalia_reg(audio, IX_REG(reg_name)ixreg_name, value)
54
55static void write_indirect_azalia_reg(struct audio *audio,
56 uint32_t reg_index,
57 uint32_t reg_data)
58{
59 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
60
61 /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
62 REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_INDEX
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_INDEX, aud->
masks->AZALIA_ENDPOINT_REG_INDEX, reg_index)
63 AZALIA_ENDPOINT_REG_INDEX, reg_index)generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_INDEX
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_INDEX, aud->
masks->AZALIA_ENDPOINT_REG_INDEX, reg_index)
;
64
65 /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
66 REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_DATA
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_DATA, aud->
masks->AZALIA_ENDPOINT_REG_DATA, reg_data)
67 AZALIA_ENDPOINT_REG_DATA, reg_data)generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_DATA
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_DATA, aud->
masks->AZALIA_ENDPOINT_REG_DATA, reg_data)
;
68}
69
70static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
71{
72 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
73
74 uint32_t value = 0;
75
76 /* AZALIA_F0_CODEC_ENDPOINT_INDEX endpoint index */
77 REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_INDEX
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_INDEX, aud->
masks->AZALIA_ENDPOINT_REG_INDEX, reg_index)
78 AZALIA_ENDPOINT_REG_INDEX, reg_index)generic_reg_set_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_INDEX
), 0, 1, aud->shifts->AZALIA_ENDPOINT_REG_INDEX, aud->
masks->AZALIA_ENDPOINT_REG_INDEX, reg_index)
;
79
80 /* AZALIA_F0_CODEC_ENDPOINT_DATA endpoint data */
81 value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA)dm_read_reg_func(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_ENDPOINT_DATA
), __func__)
;
82
83 return value;
84}
85
86static bool_Bool is_audio_format_supported(
87 const struct audio_info *audio_info,
88 enum audio_format_code audio_format_code,
89 uint32_t *format_index)
90{
91 uint32_t index;
92 uint32_t max_channe_index = 0;
93 bool_Bool found = false0;
94
95 if (audio_info == NULL((void *)0))
96 return found;
97
98 /* pass through whole array */
99 for (index = 0; index < audio_info->mode_count; index++) {
100 if (audio_info->modes[index].format_code == audio_format_code) {
101 if (found) {
102 /* format has multiply entries, choose one with
103 * highst number of channels */
104 if (audio_info->modes[index].channel_count >
105 audio_info->modes[max_channe_index].channel_count) {
106 max_channe_index = index;
107 }
108 } else {
109 /* format found, save it's index */
110 found = true1;
111 max_channe_index = index;
112 }
113 }
114 }
115
116 /* return index */
117 if (found && format_index != NULL((void *)0))
118 *format_index = max_channe_index;
119
120 return found;
121}
122
123/*For HDMI, calculate if specified sample rates can fit into a given timing */
124static void check_audio_bandwidth_hdmi(
125 const struct audio_crtc_info *crtc_info,
126 uint32_t channel_count,
127 union audio_sample_rates *sample_rates)
128{
129 uint32_t samples;
130 uint32_t h_blank;
131 bool_Bool limit_freq_to_48_khz = false0;
132 bool_Bool limit_freq_to_88_2_khz = false0;
133 bool_Bool limit_freq_to_96_khz = false0;
134 bool_Bool limit_freq_to_174_4_khz = false0;
135 if (!crtc_info)
136 return;
137
138 /* For two channels supported return whatever sink support,unmodified*/
139 if (channel_count > 2) {
140
141 /* Based on HDMI spec 1.3 Table 7.5 */
142 if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
143 (crtc_info->v_active <= 576) &&
144 !(crtc_info->interlaced) &&
145 !(crtc_info->pixel_repetition == 2 ||
146 crtc_info->pixel_repetition == 4)) {
147 limit_freq_to_48_khz = true1;
148
149 } else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
150 (crtc_info->v_active <= 576) &&
151 (crtc_info->interlaced) &&
152 (crtc_info->pixel_repetition == 2)) {
153 limit_freq_to_88_2_khz = true1;
154
155 } else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) &&
156 (crtc_info->v_active <= 576) &&
157 !(crtc_info->interlaced)) {
158 limit_freq_to_174_4_khz = true1;
159 }
160 }
161
162 /* Also do some calculation for the available Audio Bandwidth for the
163 * 8 ch (i.e. for the Layout 1 => ch > 2)
164 */
165 h_blank = crtc_info->h_total - crtc_info->h_active;
166
167 if (crtc_info->pixel_repetition)
168 h_blank *= crtc_info->pixel_repetition;
169
170 /*based on HDMI spec 1.3 Table 7.5 */
171 h_blank -= 58;
172 /*for Control Period */
173 h_blank -= 16;
174
175 samples = h_blank * 10;
176 /* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
177 * of Audio samples per line multiplied by 10 - Layout 1)
178 */
179 samples /= 32;
180 samples *= crtc_info->v_active;
181 /*Number of samples multiplied by 10, per second */
182 samples *= crtc_info->refresh_rate;
183 /*Number of Audio samples per second */
184 samples /= 10;
185
186 /* @todo do it after deep color is implemented
187 * 8xx - deep color bandwidth scaling
188 * Extra bandwidth is avaliable in deep color b/c link runs faster than
189 * pixel rate. This has the effect of allowing more tmds characters to
190 * be transmitted during blank
191 */
192
193 switch (crtc_info->color_depth) {
194 case COLOR_DEPTH_888:
195 samples *= 4;
196 break;
197 case COLOR_DEPTH_101010:
198 samples *= 5;
199 break;
200 case COLOR_DEPTH_121212:
201 samples *= 6;
202 break;
203 default:
204 samples *= 4;
205 break;
206 }
207
208 samples /= 4;
209
210 /*check limitation*/
211 if (samples < 88200)
212 limit_freq_to_48_khz = true1;
213 else if (samples < 96000)
214 limit_freq_to_88_2_khz = true1;
215 else if (samples < 176400)
216 limit_freq_to_96_khz = true1;
217 else if (samples < 192000)
218 limit_freq_to_174_4_khz = true1;
219
220 if (sample_rates != NULL((void *)0)) {
221 /* limit frequencies */
222 if (limit_freq_to_174_4_khz)
223 sample_rates->rate.RATE_192 = 0;
224
225 if (limit_freq_to_96_khz) {
226 sample_rates->rate.RATE_192 = 0;
227 sample_rates->rate.RATE_176_4 = 0;
228 }
229 if (limit_freq_to_88_2_khz) {
230 sample_rates->rate.RATE_192 = 0;
231 sample_rates->rate.RATE_176_4 = 0;
232 sample_rates->rate.RATE_96 = 0;
233 }
234 if (limit_freq_to_48_khz) {
235 sample_rates->rate.RATE_192 = 0;
236 sample_rates->rate.RATE_176_4 = 0;
237 sample_rates->rate.RATE_96 = 0;
238 sample_rates->rate.RATE_88_2 = 0;
239 }
240 }
241}
242
243/*For DP SST, calculate if specified sample rates can fit into a given timing */
244static void check_audio_bandwidth_dpsst(
245 const struct audio_crtc_info *crtc_info,
246 uint32_t channel_count,
247 union audio_sample_rates *sample_rates)
248{
249 /* do nothing */
250}
251
252/*For DP MST, calculate if specified sample rates can fit into a given timing */
253static void check_audio_bandwidth_dpmst(
254 const struct audio_crtc_info *crtc_info,
255 uint32_t channel_count,
256 union audio_sample_rates *sample_rates)
257{
258 /* do nothing */
259}
260
261static void check_audio_bandwidth(
262 const struct audio_crtc_info *crtc_info,
263 uint32_t channel_count,
264 enum amd_signal_type signal,
265 union audio_sample_rates *sample_rates)
266{
267 switch (signal) {
268 case SIGNAL_TYPE_HDMI_TYPE_A:
269 check_audio_bandwidth_hdmi(
270 crtc_info, channel_count, sample_rates);
271 break;
272 case SIGNAL_TYPE_EDP:
273 case SIGNAL_TYPE_DISPLAY_PORT:
274 check_audio_bandwidth_dpsst(
275 crtc_info, channel_count, sample_rates);
276 break;
277 case SIGNAL_TYPE_DISPLAY_PORT_MST:
278 check_audio_bandwidth_dpmst(
279 crtc_info, channel_count, sample_rates);
280 break;
281 default:
282 break;
283 }
284}
285
286/* expose/not expose HBR capability to Audio driver */
287static void set_high_bit_rate_capable(
288 struct audio *audio,
289 bool_Bool capable)
290{
291 uint32_t value = 0;
292
293 /* set high bit rate audio capable*/
294 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR)read_indirect_azalia_reg(audio, 0x38);
295
296 set_reg_field_value(value, capable,(value) = set_reg_field_value_ex( (value), (capable), 0x1, 0x0
)
297 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,(value) = set_reg_field_value_ex( (value), (capable), 0x1, 0x0
)
298 HBR_CAPABLE)(value) = set_reg_field_value_ex( (value), (capable), 0x1, 0x0
)
;
299
300 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value)write_indirect_azalia_reg(audio, 0x38, value);
301}
302
303/* set video latency in ms/2+1 */
304static void set_video_latency(
305 struct audio *audio,
306 int latency_in_ms)
307{
308 uint32_t value = 0;
309
310 if ((latency_in_ms < 0) || (latency_in_ms > 255))
311 return;
312
313 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC)read_indirect_azalia_reg(audio, 0x37);
314
315 set_reg_field_value(value, latency_in_ms,(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff
, 0x0)
316 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff
, 0x0)
317 VIDEO_LIPSYNC)(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff
, 0x0)
;
318
319 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,write_indirect_azalia_reg(audio, 0x37, value)
320 value)write_indirect_azalia_reg(audio, 0x37, value);
321}
322
323/* set audio latency in ms/2+1 */
324static void set_audio_latency(
325 struct audio *audio,
326 int latency_in_ms)
327{
328 uint32_t value = 0;
329
330 if (latency_in_ms < 0)
331 latency_in_ms = 0;
332
333 if (latency_in_ms > 255)
334 latency_in_ms = 255;
335
336 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC)read_indirect_azalia_reg(audio, 0x37);
337
338 set_reg_field_value(value, latency_in_ms,(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff00
, 0x8)
339 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff00
, 0x8)
340 AUDIO_LIPSYNC)(value) = set_reg_field_value_ex( (value), (latency_in_ms), 0xff00
, 0x8)
;
341
342 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,write_indirect_azalia_reg(audio, 0x37, value)
343 value)write_indirect_azalia_reg(audio, 0x37, value);
344}
345
346void dce_aud_az_enable(struct audio *audio)
347{
348 uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
349 DC_LOGGER_INIT();
350
351 set_reg_field_value(value, 1,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
352 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
353 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0);
354 set_reg_field_value(value, 1,(value) = set_reg_field_value_ex( (value), (1), 0x80000000, 0x1f
)
355 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (1), 0x80000000, 0x1f
)
356 AUDIO_ENABLED)(value) = set_reg_field_value_ex( (value), (1), 0x80000000, 0x1f
)
;
357
358 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
359 set_reg_field_value(value, 0,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
360 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
361 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0);
362 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
363
364 DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u data: 0x%x\n",do { } while(0)
365 audio->inst, value)do { } while(0);
366}
367
368void dce_aud_az_disable(struct audio *audio)
369{
370 uint32_t value;
371 DC_LOGGER_INIT();
372
373 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
374 set_reg_field_value(value, 1,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
375 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
376 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0);
377 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
378
379 set_reg_field_value(value, 0,(value) = set_reg_field_value_ex( (value), (0), 0x80000000, 0x1f
)
380 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (0), 0x80000000, 0x1f
)
381 AUDIO_ENABLED)(value) = set_reg_field_value_ex( (value), (0), 0x80000000, 0x1f
)
;
382 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
383
384 set_reg_field_value(value, 0,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
385 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
386 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0);
387 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
388 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
Value stored to 'value' is never read
389 DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u data: 0x%x\n",do { } while(0)
390 audio->inst, value)do { } while(0);
391}
392
393void dce_aud_az_configure(
394 struct audio *audio,
395 enum amd_signal_type signal,
396 const struct audio_crtc_info *crtc_info,
397 const struct audio_info *audio_info)
398{
399 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
400
401 uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
402 uint32_t value;
403 uint32_t field = 0;
404 enum audio_format_code audio_format_code;
405 uint32_t format_index;
406 uint32_t index;
407 bool_Bool is_ac3_supported = false0;
408 union audio_sample_rates sample_rate;
409 uint32_t strlen = 0;
410 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
411 set_reg_field_value(value, 1,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
412 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
413 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0);
414 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
415
416 /* Speaker Allocation */
417 /*
418 uint32_t value;
419 uint32_t field = 0;*/
420 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER)read_indirect_azalia_reg(audio, 0x25);
421
422 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (speakers), 0x7f, 0x0
)
423 speakers,(value) = set_reg_field_value_ex( (value), (speakers), 0x7f, 0x0
)
424 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (speakers), 0x7f, 0x0
)
425 SPEAKER_ALLOCATION)(value) = set_reg_field_value_ex( (value), (speakers), 0x7f, 0x0
)
;
426
427 /* LFE_PLAYBACK_LEVEL = LFEPBL
428 * LFEPBL = 0 : Unknown or refer to other information
429 * LFEPBL = 1 : 0dB playback
430 * LFEPBL = 2 : +10dB playback
431 * LFE_BL = 3 : Reserved
432 */
433 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (0), 0x3000000, 0x18
)
434 0,(value) = set_reg_field_value_ex( (value), (0), 0x3000000, 0x18
)
435 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (0), 0x3000000, 0x18
)
436 LFE_PLAYBACK_LEVEL)(value) = set_reg_field_value_ex( (value), (0), 0x3000000, 0x18
)
;
437 /* todo: according to reg spec LFE_PLAYBACK_LEVEL is read only.
438 * why are we writing to it? DCE8 does not write this */
439
440
441 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (0), 0x10000, 0x10
)
442 0,(value) = set_reg_field_value_ex( (value), (0), 0x10000, 0x10
)
443 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (0), 0x10000, 0x10
)
444 HDMI_CONNECTION)(value) = set_reg_field_value_ex( (value), (0), 0x10000, 0x10
)
;
445
446 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (0), 0x20000, 0x11
)
447 0,(value) = set_reg_field_value_ex( (value), (0), 0x20000, 0x11
)
448 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (0), 0x20000, 0x11
)
449 DP_CONNECTION)(value) = set_reg_field_value_ex( (value), (0), 0x20000, 0x11
)
;
450
451 field = get_reg_field_value(value,get_reg_field_value_ex( (value), 0xfc0000, 0x12)
452 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,get_reg_field_value_ex( (value), 0xfc0000, 0x12)
453 EXTRA_CONNECTION_INFO)get_reg_field_value_ex( (value), 0xfc0000, 0x12);
454
455 field &= ~0x1;
456
457 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (field), 0xfc0000,
0x12)
458 field,(value) = set_reg_field_value_ex( (value), (field), 0xfc0000,
0x12)
459 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (field), 0xfc0000,
0x12)
460 EXTRA_CONNECTION_INFO)(value) = set_reg_field_value_ex( (value), (field), 0xfc0000,
0x12)
;
461
462 /* set audio for output signal */
463 switch (signal) {
464 case SIGNAL_TYPE_HDMI_TYPE_A:
465 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (1), 0x10000, 0x10
)
466 1,(value) = set_reg_field_value_ex( (value), (1), 0x10000, 0x10
)
467 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (1), 0x10000, 0x10
)
468 HDMI_CONNECTION)(value) = set_reg_field_value_ex( (value), (1), 0x10000, 0x10
)
;
469
470 break;
471
472 case SIGNAL_TYPE_EDP:
473 case SIGNAL_TYPE_DISPLAY_PORT:
474 case SIGNAL_TYPE_DISPLAY_PORT_MST:
475 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (1), 0x20000, 0x11
)
476 1,(value) = set_reg_field_value_ex( (value), (1), 0x20000, 0x11
)
477 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,(value) = set_reg_field_value_ex( (value), (1), 0x20000, 0x11
)
478 DP_CONNECTION)(value) = set_reg_field_value_ex( (value), (1), 0x20000, 0x11
)
;
479 break;
480 default:
481 BREAK_TO_DEBUGGER()do { ___drm_dbg(((void *)0), DRM_UT_DRIVER, "%s():%d\n", __func__
, 481); do {} while (0); } while (0)
;
482 break;
483 }
484
485 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value)write_indirect_azalia_reg(audio, 0x25, value);
486
487 /* ACP Data - Supports AI */
488 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA)read_indirect_azalia_reg(audio, 0x27);
489
490 set_reg_field_value((value) = set_reg_field_value_ex( (value), (audio_info->flags
.info.SUPPORT_AI), 0x40, 0x6)
491 value,(value) = set_reg_field_value_ex( (value), (audio_info->flags
.info.SUPPORT_AI), 0x40, 0x6)
492 audio_info->flags.info.SUPPORT_AI,(value) = set_reg_field_value_ex( (value), (audio_info->flags
.info.SUPPORT_AI), 0x40, 0x6)
493 AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA,(value) = set_reg_field_value_ex( (value), (audio_info->flags
.info.SUPPORT_AI), 0x40, 0x6)
494 SUPPORTS_AI)(value) = set_reg_field_value_ex( (value), (audio_info->flags
.info.SUPPORT_AI), 0x40, 0x6)
;
495
496 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA, value)write_indirect_azalia_reg(audio, 0x27, value);
497
498 /* Audio Descriptors */
499 /* pass through all formats */
500 for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
501 format_index++) {
502 audio_format_code =
503 (AUDIO_FORMAT_CODE_FIRST + format_index);
504
505 /* those are unsupported, skip programming */
506 if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
507 audio_format_code == AUDIO_FORMAT_CODE_DST)
508 continue;
509
510 value = 0;
511
512 /* check if supported */
513 if (is_audio_format_supported(
514 audio_info, audio_format_code, &index)) {
515 const struct audio_mode *audio_mode =
516 &audio_info->modes[index];
517 union audio_sample_rates sample_rates =
518 audio_mode->sample_rates;
519 uint8_t byte2 = audio_mode->max_bit_rate;
520 uint8_t channel_count = audio_mode->channel_count;
521
522 /* adjust specific properties */
523 switch (audio_format_code) {
524 case AUDIO_FORMAT_CODE_LINEARPCM: {
525
526 check_audio_bandwidth(
527 crtc_info,
528 channel_count,
529 signal,
530 &sample_rates);
531
532 byte2 = audio_mode->sample_size;
533
534 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff000000, 0x18)
535 sample_rates.all,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff000000, 0x18)
536 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff000000, 0x18)
537 SUPPORTED_FREQUENCIES_STEREO)(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff000000, 0x18)
;
538 }
539 break;
540 case AUDIO_FORMAT_CODE_AC3:
541 is_ac3_supported = true1;
542 break;
543 case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
544 case AUDIO_FORMAT_CODE_DTS_HD:
545 case AUDIO_FORMAT_CODE_MAT_MLP:
546 case AUDIO_FORMAT_CODE_DST:
547 case AUDIO_FORMAT_CODE_WMAPRO:
548 byte2 = audio_mode->vendor_specific;
549 break;
550 default:
551 break;
552 }
553
554 /* fill audio format data */
555 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (channel_count - 1
), 0x7, 0x0)
556 channel_count - 1,(value) = set_reg_field_value_ex( (value), (channel_count - 1
), 0x7, 0x0)
557 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,(value) = set_reg_field_value_ex( (value), (channel_count - 1
), 0x7, 0x0)
558 MAX_CHANNELS)(value) = set_reg_field_value_ex( (value), (channel_count - 1
), 0x7, 0x0)
;
559
560 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff00, 0x8)
561 sample_rates.all,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff00, 0x8)
562 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff00, 0x8)
563 SUPPORTED_FREQUENCIES)(value) = set_reg_field_value_ex( (value), (sample_rates.all)
, 0xff00, 0x8)
;
564
565 set_reg_field_value(value,(value) = set_reg_field_value_ex( (value), (byte2), 0xff0000,
0x10)
566 byte2,(value) = set_reg_field_value_ex( (value), (byte2), 0xff0000,
0x10)
567 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,(value) = set_reg_field_value_ex( (value), (byte2), 0xff0000,
0x10)
568 DESCRIPTOR_BYTE_2)(value) = set_reg_field_value_ex( (value), (byte2), 0xff0000,
0x10)
;
569 } /* if */
570
571 AZ_REG_WRITE(write_indirect_azalia_reg(audio, 0x28 + format_index, value)
572 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,write_indirect_azalia_reg(audio, 0x28 + format_index, value)
573 value)write_indirect_azalia_reg(audio, 0x28 + format_index, value);
574 } /* for */
575
576 if (is_ac3_supported)
577 /* todo: this reg global. why program global register? */
578 REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,dm_write_reg_func(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS
), 0x05, __func__)
579 0x05)dm_write_reg_func(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS
), 0x05, __func__)
;
580
581 /* check for 192khz/8-Ch support for HBR requirements */
582 sample_rate.all = 0;
583 sample_rate.rate.RATE_192 = 1;
584
585 check_audio_bandwidth(
586 crtc_info,
587 8,
588 signal,
589 &sample_rate);
590
591 set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);
592
593 /* Audio and Video Lipsync */
594 set_video_latency(audio, audio_info->video_latency);
595 set_audio_latency(audio, audio_info->audio_latency);
596
597 value = 0;
598 set_reg_field_value(value, audio_info->manufacture_id,(value) = set_reg_field_value_ex( (value), (audio_info->manufacture_id
), 0xffff, 0x0)
599 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,(value) = set_reg_field_value_ex( (value), (audio_info->manufacture_id
), 0xffff, 0x0)
600 MANUFACTURER_ID)(value) = set_reg_field_value_ex( (value), (audio_info->manufacture_id
), 0xffff, 0x0)
;
601
602 set_reg_field_value(value, audio_info->product_id,(value) = set_reg_field_value_ex( (value), (audio_info->product_id
), 0xffff0000, 0x10)
603 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,(value) = set_reg_field_value_ex( (value), (audio_info->product_id
), 0xffff0000, 0x10)
604 PRODUCT_ID)(value) = set_reg_field_value_ex( (value), (audio_info->product_id
), 0xffff0000, 0x10)
;
605
606 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,write_indirect_azalia_reg(audio, 0x3a, value)
607 value)write_indirect_azalia_reg(audio, 0x3a, value);
608
609 value = 0;
610
611 /*get display name string length */
612 while (audio_info->display_name[strlen++] != '\0') {
613 if (strlen >=
614 MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS18)
615 break;
616 }
617 set_reg_field_value(value, strlen,(value) = set_reg_field_value_ex( (value), (strlen), 0xff, 0x0
)
618 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,(value) = set_reg_field_value_ex( (value), (strlen), 0xff, 0x0
)
619 SINK_DESCRIPTION_LEN)(value) = set_reg_field_value_ex( (value), (strlen), 0xff, 0x0
)
;
620
621 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,write_indirect_azalia_reg(audio, 0x3b, value)
622 value)write_indirect_azalia_reg(audio, 0x3b, value);
623 DC_LOG_HW_AUDIO("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n",do { } while(0)
624 audio->inst, value, audio_info->display_name)do { } while(0);
625
626 /*
627 *write the port ID:
628 *PORT_ID0 = display index
629 *PORT_ID1 = 16bit BDF
630 *(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
631 */
632
633 value = 0;
634
635 set_reg_field_value(value, audio_info->port_id[0],(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[0]), 0xffffffff, 0x0)
636 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[0]), 0xffffffff, 0x0)
637 PORT_ID0)(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[0]), 0xffffffff, 0x0)
;
638
639 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value)write_indirect_azalia_reg(audio, 0x3c, value);
640
641 value = 0;
642 set_reg_field_value(value, audio_info->port_id[1],(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[1]), 0xffffffff, 0x0)
643 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[1]), 0xffffffff, 0x0)
644 PORT_ID1)(value) = set_reg_field_value_ex( (value), (audio_info->port_id
[1]), 0xffffffff, 0x0)
;
645
646 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value)write_indirect_azalia_reg(audio, 0x3d, value);
647
648 /*write the 18 char monitor string */
649
650 value = 0;
651 set_reg_field_value(value, audio_info->display_name[0],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[0]), 0xff, 0x0)
652 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[0]), 0xff, 0x0)
653 DESCRIPTION0)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[0]), 0xff, 0x0)
;
654
655 set_reg_field_value(value, audio_info->display_name[1],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[1]), 0xff00, 0x8)
656 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[1]), 0xff00, 0x8)
657 DESCRIPTION1)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[1]), 0xff00, 0x8)
;
658
659 set_reg_field_value(value, audio_info->display_name[2],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[2]), 0xff0000, 0x10)
660 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[2]), 0xff0000, 0x10)
661 DESCRIPTION2)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[2]), 0xff0000, 0x10)
;
662
663 set_reg_field_value(value, audio_info->display_name[3],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[3]), 0xff000000, 0x18)
664 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[3]), 0xff000000, 0x18)
665 DESCRIPTION3)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[3]), 0xff000000, 0x18)
;
666
667 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value)write_indirect_azalia_reg(audio, 0x3e, value);
668
669 value = 0;
670 set_reg_field_value(value, audio_info->display_name[4],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[4]), 0xff, 0x0)
671 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[4]), 0xff, 0x0)
672 DESCRIPTION4)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[4]), 0xff, 0x0)
;
673
674 set_reg_field_value(value, audio_info->display_name[5],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[5]), 0xff00, 0x8)
675 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[5]), 0xff00, 0x8)
676 DESCRIPTION5)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[5]), 0xff00, 0x8)
;
677
678 set_reg_field_value(value, audio_info->display_name[6],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[6]), 0xff0000, 0x10)
679 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[6]), 0xff0000, 0x10)
680 DESCRIPTION6)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[6]), 0xff0000, 0x10)
;
681
682 set_reg_field_value(value, audio_info->display_name[7],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[7]), 0xff000000, 0x18)
683 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[7]), 0xff000000, 0x18)
684 DESCRIPTION7)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[7]), 0xff000000, 0x18)
;
685
686 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value)write_indirect_azalia_reg(audio, 0x3f, value);
687
688 value = 0;
689 set_reg_field_value(value, audio_info->display_name[8],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[8]), 0xff, 0x0)
690 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[8]), 0xff, 0x0)
691 DESCRIPTION8)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[8]), 0xff, 0x0)
;
692
693 set_reg_field_value(value, audio_info->display_name[9],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[9]), 0xff00, 0x8)
694 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[9]), 0xff00, 0x8)
695 DESCRIPTION9)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[9]), 0xff00, 0x8)
;
696
697 set_reg_field_value(value, audio_info->display_name[10],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[10]), 0xff0000, 0x10)
698 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[10]), 0xff0000, 0x10)
699 DESCRIPTION10)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[10]), 0xff0000, 0x10)
;
700
701 set_reg_field_value(value, audio_info->display_name[11],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[11]), 0xff000000, 0x18)
702 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[11]), 0xff000000, 0x18)
703 DESCRIPTION11)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[11]), 0xff000000, 0x18)
;
704
705 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value)write_indirect_azalia_reg(audio, 0x40, value);
706
707 value = 0;
708 set_reg_field_value(value, audio_info->display_name[12],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[12]), 0xff, 0x0)
709 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[12]), 0xff, 0x0)
710 DESCRIPTION12)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[12]), 0xff, 0x0)
;
711
712 set_reg_field_value(value, audio_info->display_name[13],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[13]), 0xff00, 0x8)
713 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[13]), 0xff00, 0x8)
714 DESCRIPTION13)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[13]), 0xff00, 0x8)
;
715
716 set_reg_field_value(value, audio_info->display_name[14],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[14]), 0xff0000, 0x10)
717 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[14]), 0xff0000, 0x10)
718 DESCRIPTION14)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[14]), 0xff0000, 0x10)
;
719
720 set_reg_field_value(value, audio_info->display_name[15],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[15]), 0xff000000, 0x18)
721 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[15]), 0xff000000, 0x18)
722 DESCRIPTION15)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[15]), 0xff000000, 0x18)
;
723
724 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value)write_indirect_azalia_reg(audio, 0x41, value);
725
726 value = 0;
727 set_reg_field_value(value, audio_info->display_name[16],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[16]), 0xff, 0x0)
728 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[16]), 0xff, 0x0)
729 DESCRIPTION16)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[16]), 0xff, 0x0)
;
730
731 set_reg_field_value(value, audio_info->display_name[17],(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[17]), 0xff00, 0x8)
732 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[17]), 0xff00, 0x8)
733 DESCRIPTION17)(value) = set_reg_field_value_ex( (value), (audio_info->display_name
[17]), 0xff00, 0x8)
;
734
735 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value)write_indirect_azalia_reg(audio, 0x42, value);
736 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
737 set_reg_field_value(value, 0,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
738 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
739 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0);
740 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
741}
742
743/*
744* todo: wall clk related functionality probably belong to clock_src.
745*/
746
747/* search pixel clock value for Azalia HDMI Audio */
748static void get_azalia_clock_info_hdmi(
749 uint32_t crtc_pixel_clock_100hz,
750 uint32_t actual_pixel_clock_100Hz,
751 struct azalia_clock_info *azalia_clock_info)
752{
753 /* audio_dto_phase= 24 * 10,000;
754 * 24MHz in [100Hz] units */
755 azalia_clock_info->audio_dto_phase =
756 24 * 10000;
757
758 /* audio_dto_module = PCLKFrequency * 10,000;
759 * [khz] -> [100Hz] */
760 azalia_clock_info->audio_dto_module =
761 actual_pixel_clock_100Hz;
762}
763
764static void get_azalia_clock_info_dp(
765 uint32_t requested_pixel_clock_100Hz,
766 const struct audio_pll_info *pll_info,
767 struct azalia_clock_info *azalia_clock_info)
768{
769 /* Reported dpDtoSourceClockInkhz value for
770 * DCE8 already adjusted for SS, do not need any
771 * adjustment here anymore
772 */
773
774 /*audio_dto_phase = 24 * 10,000;
775 * 24MHz in [100Hz] units */
776 azalia_clock_info->audio_dto_phase = 24 * 10000;
777
778 /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
779 * [khz] ->[100Hz] */
780 azalia_clock_info->audio_dto_module =
781 pll_info->dp_dto_source_clock_in_khz * 10;
782}
783
784void dce_aud_wall_dto_setup(
785 struct audio *audio,
786 enum amd_signal_type signal,
787 const struct audio_crtc_info *crtc_info,
788 const struct audio_pll_info *pll_info)
789{
790 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
791
792 struct azalia_clock_info clock_info = { 0 };
793
794 if (dc_is_hdmi_tmds_signal(signal)) {
795 uint32_t src_sel;
796
797 /*DTO0 Programming goal:
798 -generate 24MHz, 128*Fs from 24MHz
799 -use DTO0 when an active HDMI port is connected
800 (optionally a DP is connected) */
801
802 /* calculate DTO settings */
803 get_azalia_clock_info_hdmi(
804 crtc_info->requested_pixel_clock_100Hz,
805 crtc_info->calculated_pixel_clock_100Hz,
806 &clock_info);
807
808 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\do { } while(0)
809 "calculated_pixel_clock_100Hz =%d\n"\do { } while(0)
810 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\do { } while(0)
811 crtc_info->requested_pixel_clock_100Hz,\do { } while(0)
812 crtc_info->calculated_pixel_clock_100Hz,\do { } while(0)
813 clock_info.audio_dto_module,\do { } while(0)
814 clock_info.audio_dto_phase)do { } while(0);
815
816 /* On TN/SI, Program DTO source select and DTO select before
817 programming DTO modulo and DTO phase. These bits must be
818 programmed first, otherwise there will be no HDMI audio at boot
819 up. This is a HW sequence change (different from old ASICs).
820 Caution when changing this programming sequence.
821
822 HDMI enabled, using DTO0
823 program master CRTC for DTO0 */
824 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
825 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
826 DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
827 DCCG_AUDIO_DTO_SEL, 0)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
;
828
829 /* module */
830 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO0_MODULE, aud->masks
->DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)
831 DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO0_MODULE, aud->masks
->DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)
;
832
833 /* phase */
834 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO0_PHASE, aud->masks
->DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)
835 DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO0_PHASE, aud->masks
->DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)
;
836 } else {
837 /*DTO1 Programming goal:
838 -generate 24MHz, 512*Fs, 128*Fs from 24MHz
839 -default is to used DTO1, and switch to DTO0 when an audio
840 master HDMI port is connected
841 -use as default for DP
842
843 calculate DTO settings */
844 get_azalia_clock_info_dp(
845 crtc_info->requested_pixel_clock_100Hz,
846 pll_info,
847 &clock_info);
848
849 /* Program DTO select before programming DTO modulo and DTO
850 phase. default to use DTO1 */
851
852 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO_SEL, aud->masks->
DCCG_AUDIO_DTO_SEL, 1)
853 DCCG_AUDIO_DTO_SEL, 1)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO_SEL, aud->masks->
DCCG_AUDIO_DTO_SEL, 1)
;
854
855 /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
856 * Select 512fs for DP TODO: web register definition
857 * does not match register header file
858 * DCE11 version it's commented out while DCE8 it's set to 1
859 */
860
861 /* module */
862 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO1_MODULE, aud->masks
->DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)
863 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO1_MODULE, aud->masks
->DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)
;
864
865 /* phase */
866 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO1_PHASE, aud->masks
->DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)
867 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO1_PHASE, aud->masks
->DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)
;
868
869 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO2_USE_512FBR_DTO, aud->
masks->DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
870 DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO2_USE_512FBR_DTO, aud->
masks->DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
;
871
872 }
873}
874
875#if defined(CONFIG_DRM_AMD_DC_SI)
876static void dce60_aud_wall_dto_setup(
877 struct audio *audio,
878 enum amd_signal_type signal,
879 const struct audio_crtc_info *crtc_info,
880 const struct audio_pll_info *pll_info)
881{
882 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
883
884 struct azalia_clock_info clock_info = { 0 };
885
886 if (dc_is_hdmi_signal(signal)) {
887 uint32_t src_sel;
888
889 /*DTO0 Programming goal:
890 -generate 24MHz, 128*Fs from 24MHz
891 -use DTO0 when an active HDMI port is connected
892 (optionally a DP is connected) */
893
894 /* calculate DTO settings */
895 get_azalia_clock_info_hdmi(
896 crtc_info->requested_pixel_clock_100Hz,
897 crtc_info->calculated_pixel_clock_100Hz,
898 &clock_info);
899
900 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\do { } while(0)
901 "calculated_pixel_clock_100Hz =%d\n"\do { } while(0)
902 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\do { } while(0)
903 crtc_info->requested_pixel_clock_100Hz,\do { } while(0)
904 crtc_info->calculated_pixel_clock_100Hz,\do { } while(0)
905 clock_info.audio_dto_module,\do { } while(0)
906 clock_info.audio_dto_phase)do { } while(0);
907
908 /* On TN/SI, Program DTO source select and DTO select before
909 programming DTO modulo and DTO phase. These bits must be
910 programmed first, otherwise there will be no HDMI audio at boot
911 up. This is a HW sequence change (different from old ASICs).
912 Caution when changing this programming sequence.
913
914 HDMI enabled, using DTO0
915 program master CRTC for DTO0 */
916 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
917 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
918 DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
919 DCCG_AUDIO_DTO_SEL, 0)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 2, aud->shifts->DCCG_AUDIO_DTO0_SOURCE_SEL, aud->
masks->DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, aud->shifts
->DCCG_AUDIO_DTO_SEL, aud->masks->DCCG_AUDIO_DTO_SEL
, 0)
;
920
921 /* module */
922 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO0_MODULE, aud->masks
->DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)
923 DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO0_MODULE, aud->masks
->DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module)
;
924
925 /* phase */
926 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO0_PHASE, aud->masks
->DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)
927 DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO0_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO0_PHASE, aud->masks
->DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase)
;
928 } else {
929 /*DTO1 Programming goal:
930 -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs)
931 -default is to used DTO1, and switch to DTO0 when an audio
932 master HDMI port is connected
933 -use as default for DP
934
935 calculate DTO settings */
936 get_azalia_clock_info_dp(
937 crtc_info->requested_pixel_clock_100Hz,
938 pll_info,
939 &clock_info);
940
941 /* Program DTO select before programming DTO modulo and DTO
942 phase. default to use DTO1 */
943
944 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO_SEL, aud->masks->
DCCG_AUDIO_DTO_SEL, 1)
945 DCCG_AUDIO_DTO_SEL, 1)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO_SOURCE
), 1, aud->shifts->DCCG_AUDIO_DTO_SEL, aud->masks->
DCCG_AUDIO_DTO_SEL, 1)
;
946
947 /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
948 * Cannot select 512fs for DP
949 *
950 * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask
951 */
952
953 /* module */
954 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO1_MODULE, aud->masks
->DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)
955 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_MODULE
), 1, aud->shifts->DCCG_AUDIO_DTO1_MODULE, aud->masks
->DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module)
;
956
957 /* phase */
958 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO1_PHASE, aud->masks
->DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)
959 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)generic_reg_update_ex(aud->base.ctx, (aud->regs->DCCG_AUDIO_DTO1_PHASE
), 1, aud->shifts->DCCG_AUDIO_DTO1_PHASE, aud->masks
->DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase)
;
960
961 /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */
962
963 }
964}
965#endif
966
967static bool_Bool dce_aud_endpoint_valid(struct audio *audio)
968{
969 uint32_t value;
970 uint32_t port_connectivity;
971
972 value = AZ_REG_READ(read_indirect_azalia_reg(audio, 0x56)
973 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT)read_indirect_azalia_reg(audio, 0x56);
974
975 port_connectivity = get_reg_field_value(value,get_reg_field_value_ex( (value), 0xc0000000, 0x1e)
976 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,get_reg_field_value_ex( (value), 0xc0000000, 0x1e)
977 PORT_CONNECTIVITY)get_reg_field_value_ex( (value), 0xc0000000, 0x1e);
978
979 return !(port_connectivity == 1);
980}
981
982/* initialize HW state */
983void dce_aud_hw_init(
984 struct audio *audio)
985{
986 uint32_t value;
987 struct dce_audio *aud = DCE_AUD(audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
988
989 /* we only need to program the following registers once, so we only do
990 it for the inst 0*/
991 if (audio->inst != 0)
992 return;
993
994 /* Suport R5 - 32khz
995 * Suport R6 - 44.1khz
996 * Suport R7 - 48khz
997 */
998 /*disable clock gating before write to endpoint register*/
999 value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL)read_indirect_azalia_reg(audio, 0x54);
1000 set_reg_field_value(value, 1,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
1001 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0)
1002 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (1), 0x1, 0x0);
1003 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
1004 REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,generic_reg_update_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES
), 1, aud->shifts->AUDIO_RATE_CAPABILITIES, aud->masks
->AUDIO_RATE_CAPABILITIES, 0x70)
1005 AUDIO_RATE_CAPABILITIES, 0x70)generic_reg_update_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES
), 1, aud->shifts->AUDIO_RATE_CAPABILITIES, aud->masks
->AUDIO_RATE_CAPABILITIES, 0x70)
;
1006
1007 /*Keep alive bit to verify HW block in BU. */
1008 REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,generic_reg_update_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES
), 2, aud->shifts->CLKSTOP, aud->masks->CLKSTOP, 1
, aud->shifts->EPSS, aud->masks->EPSS, 1)
1009 CLKSTOP, 1,generic_reg_update_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES
), 2, aud->shifts->CLKSTOP, aud->masks->CLKSTOP, 1
, aud->shifts->EPSS, aud->masks->EPSS, 1)
1010 EPSS, 1)generic_reg_update_ex(aud->base.ctx, (aud->regs->AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES
), 2, aud->shifts->CLKSTOP, aud->masks->CLKSTOP, 1
, aud->shifts->EPSS, aud->masks->EPSS, 1)
;
1011 set_reg_field_value(value, 0,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
1012 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0)
1013 CLOCK_GATING_DISABLE)(value) = set_reg_field_value_ex( (value), (0), 0x1, 0x0);
1014 AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value)write_indirect_azalia_reg(audio, 0x54, value);
1015}
1016
1017static const struct audio_funcs funcs = {
1018 .endpoint_valid = dce_aud_endpoint_valid,
1019 .hw_init = dce_aud_hw_init,
1020 .wall_dto_setup = dce_aud_wall_dto_setup,
1021 .az_enable = dce_aud_az_enable,
1022 .az_disable = dce_aud_az_disable,
1023 .az_configure = dce_aud_az_configure,
1024 .destroy = dce_aud_destroy,
1025};
1026
1027#if defined(CONFIG_DRM_AMD_DC_SI)
1028static const struct audio_funcs dce60_funcs = {
1029 .endpoint_valid = dce_aud_endpoint_valid,
1030 .hw_init = dce_aud_hw_init,
1031 .wall_dto_setup = dce60_aud_wall_dto_setup,
1032 .az_enable = dce_aud_az_enable,
1033 .az_disable = dce_aud_az_disable,
1034 .az_configure = dce_aud_az_configure,
1035 .destroy = dce_aud_destroy,
1036};
1037#endif
1038
1039void dce_aud_destroy(struct audio **audio)
1040{
1041 struct dce_audio *aud = DCE_AUD(*audio)({ const __typeof( ((struct dce_audio *)0)->base ) *__mptr
= (*audio); (struct dce_audio *)( (char *)__mptr - __builtin_offsetof
(struct dce_audio, base) );})
;
1042
1043 kfree(aud);
1044 *audio = NULL((void *)0);
1045}
1046
1047struct audio *dce_audio_create(
1048 struct dc_context *ctx,
1049 unsigned int inst,
1050 const struct dce_audio_registers *reg,
1051 const struct dce_audio_shift *shifts,
1052 const struct dce_audio_mask *masks
1053 )
1054{
1055 struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL(0x0001 | 0x0004));
1056
1057 if (audio == NULL((void *)0)) {
1058 ASSERT_CRITICAL(audio)do { if (({ int __ret = !!(!(audio)); if (__ret) printf("WARNING %s failed at %s:%d\n"
, "!(audio)", "/usr/src/sys/dev/pci/drm/amd/display/dc/dce/dce_audio.c"
, 1058); __builtin_expect(!!(__ret), 0); })) do {} while (0);
} while (0)
;
1059 return NULL((void *)0);
1060 }
1061
1062 audio->base.ctx = ctx;
1063 audio->base.inst = inst;
1064 audio->base.funcs = &funcs;
1065
1066 audio->regs = reg;
1067 audio->shifts = shifts;
1068 audio->masks = masks;
1069 return &audio->base;
1070}
1071
1072#if defined(CONFIG_DRM_AMD_DC_SI)
1073struct audio *dce60_audio_create(
1074 struct dc_context *ctx,
1075 unsigned int inst,
1076 const struct dce_audio_registers *reg,
1077 const struct dce_audio_shift *shifts,
1078 const struct dce_audio_mask *masks
1079 )
1080{
1081 struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL(0x0001 | 0x0004));
1082
1083 if (audio == NULL((void *)0)) {
1084 ASSERT_CRITICAL(audio)do { if (({ int __ret = !!(!(audio)); if (__ret) printf("WARNING %s failed at %s:%d\n"
, "!(audio)", "/usr/src/sys/dev/pci/drm/amd/display/dc/dce/dce_audio.c"
, 1084); __builtin_expect(!!(__ret), 0); })) do {} while (0);
} while (0)
;
1085 return NULL((void *)0);
1086 }
1087
1088 audio->base.ctx = ctx;
1089 audio->base.inst = inst;
1090 audio->base.funcs = &dce60_funcs;
1091
1092 audio->regs = reg;
1093 audio->shifts = shifts;
1094 audio->masks = masks;
1095 return &audio->base;
1096}
1097#endif