1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include "dc_bios_types.h"
28#include "hw_shared.h"
29#include "dcn30_afmt.h"
30#include "reg_helper.h"
31
32#define DC_LOGGER \
33 afmt3->base.ctx->logger
34
35#define REG(reg)\
36 (afmt3->regs->reg)
37
38#undef FN
39#define FN(reg_name, field_name) \
40 afmt3->afmt_shift->field_name, afmt3->afmt_mask->field_name
41
42
43#define CTX \
44 afmt3->base.ctx
45
46
47static void afmt3_setup_hdmi_audio(
48 struct afmt *afmt)
49{
50 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
51
52
53 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
54
55
56 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
57 AFMT_AUDIO_LAYOUT_OVRD, 0,
58 AFMT_60958_OSF_OVRD, 0);
59
60
61
62
63 REG_UPDATE_2(AFMT_60958_0,
64 AFMT_60958_CS_CHANNEL_NUMBER_L, 1,
65 AFMT_60958_CS_CLOCK_ACCURACY, 0);
66
67
68 REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2);
69
70
71
72
73 REG_UPDATE_6(AFMT_60958_2,
74 AFMT_60958_CS_CHANNEL_NUMBER_2, 3,
75 AFMT_60958_CS_CHANNEL_NUMBER_3, 4,
76 AFMT_60958_CS_CHANNEL_NUMBER_4, 5,
77 AFMT_60958_CS_CHANNEL_NUMBER_5, 6,
78 AFMT_60958_CS_CHANNEL_NUMBER_6, 7,
79 AFMT_60958_CS_CHANNEL_NUMBER_7, 8);
80}
81
82static union audio_cea_channels speakers_to_channels(
83 struct audio_speaker_flags speaker_flags)
84{
85 union audio_cea_channels cea_channels = {0};
86
87
88 cea_channels.channels.FL = speaker_flags.FL_FR;
89 cea_channels.channels.FR = speaker_flags.FL_FR;
90 cea_channels.channels.LFE = speaker_flags.LFE;
91 cea_channels.channels.FC = speaker_flags.FC;
92
93
94
95
96 if (speaker_flags.RL_RR) {
97 cea_channels.channels.RL_RC = speaker_flags.RL_RR;
98 cea_channels.channels.RR = speaker_flags.RL_RR;
99 cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
100 } else {
101 cea_channels.channels.RL_RC = speaker_flags.RC;
102 }
103
104
105 if (speaker_flags.FLC_FRC) {
106 cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
107 cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
108 } else {
109 cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
110 cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
111 }
112
113 return cea_channels;
114}
115
116static void afmt3_se_audio_setup(
117 struct afmt *afmt,
118 unsigned int az_inst,
119 struct audio_info *audio_info)
120{
121 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
122
123 uint32_t speakers = 0;
124 uint32_t channels = 0;
125
126 ASSERT(audio_info);
127
128 if (audio_info == NULL)
129 return;
130
131 speakers = audio_info->flags.info.ALLSPEAKERS;
132 channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
133
134
135 REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst);
136
137
138 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
139
140
141 REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
142}
143
144static void afmt3_audio_mute_control(
145 struct afmt *afmt,
146 bool mute)
147{
148 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
149
150
151 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
152}
153
154static void afmt3_audio_info_immediate_update(
155 struct afmt *afmt)
156{
157 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
158
159
160 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
161}
162
163static void afmt3_setup_dp_audio(
164 struct afmt *afmt)
165{
166 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
167
168
169 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
170
171
172
173 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
174 AFMT_AUDIO_LAYOUT_OVRD, 0,
175 AFMT_60958_OSF_OVRD, 0);
176
177
178 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
179
180
181 REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0);
182}
183
184static struct afmt_funcs dcn30_afmt_funcs = {
185 .setup_hdmi_audio = afmt3_setup_hdmi_audio,
186 .se_audio_setup = afmt3_se_audio_setup,
187 .audio_mute_control = afmt3_audio_mute_control,
188 .audio_info_immediate_update = afmt3_audio_info_immediate_update,
189 .setup_dp_audio = afmt3_setup_dp_audio,
190};
191
192void afmt3_construct(struct dcn30_afmt *afmt3,
193 struct dc_context *ctx,
194 uint32_t inst,
195 const struct dcn30_afmt_registers *afmt_regs,
196 const struct dcn30_afmt_shift *afmt_shift,
197 const struct dcn30_afmt_mask *afmt_mask)
198{
199 afmt3->base.ctx = ctx;
200
201 afmt3->base.inst = inst;
202 afmt3->base.funcs = &dcn30_afmt_funcs;
203
204 afmt3->regs = afmt_regs;
205 afmt3->afmt_shift = afmt_shift;
206 afmt3->afmt_mask = afmt_mask;
207}
208