Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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