]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c
crypto: akcipher - Drop sign/verify operations
[linux.git] / drivers / gpu / drm / amd / display / dc / dcn30 / dcn30_afmt.c
1 /*
2  * Copyright 2020 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
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
47 void afmt3_setup_hdmi_audio(
48         struct afmt *afmt)
49 {
50         struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
51
52         if (afmt->funcs->afmt_poweron)
53                 afmt->funcs->afmt_poweron(afmt);
54
55         /* AFMT_AUDIO_PACKET_CONTROL */
56         REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
57
58         /* AFMT_AUDIO_PACKET_CONTROL2 */
59         REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
60                         AFMT_AUDIO_LAYOUT_OVRD, 0,
61                         AFMT_60958_OSF_OVRD, 0);
62
63         /* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK &
64          * AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK
65          */
66         REG_UPDATE_2(AFMT_60958_0,
67                         AFMT_60958_CS_CHANNEL_NUMBER_L, 1,
68                         AFMT_60958_CS_CLOCK_ACCURACY, 0);
69
70         /* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */
71         REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2);
72
73         /* AFMT_60958_2 now keep this settings until
74          * Programming guide comes out
75          */
76         REG_UPDATE_6(AFMT_60958_2,
77                         AFMT_60958_CS_CHANNEL_NUMBER_2, 3,
78                         AFMT_60958_CS_CHANNEL_NUMBER_3, 4,
79                         AFMT_60958_CS_CHANNEL_NUMBER_4, 5,
80                         AFMT_60958_CS_CHANNEL_NUMBER_5, 6,
81                         AFMT_60958_CS_CHANNEL_NUMBER_6, 7,
82                         AFMT_60958_CS_CHANNEL_NUMBER_7, 8);
83 }
84
85 static union audio_cea_channels speakers_to_channels(
86         struct audio_speaker_flags speaker_flags)
87 {
88         union audio_cea_channels cea_channels = {0};
89
90         /* these are one to one */
91         cea_channels.channels.FL = speaker_flags.FL_FR;
92         cea_channels.channels.FR = speaker_flags.FL_FR;
93         cea_channels.channels.LFE = speaker_flags.LFE;
94         cea_channels.channels.FC = speaker_flags.FC;
95
96         /* if Rear Left and Right exist move RC speaker to channel 7
97          * otherwise to channel 5
98          */
99         if (speaker_flags.RL_RR) {
100                 cea_channels.channels.RL_RC = speaker_flags.RL_RR;
101                 cea_channels.channels.RR = speaker_flags.RL_RR;
102                 cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
103         } else {
104                 cea_channels.channels.RL_RC = speaker_flags.RC;
105         }
106
107         /* FRONT Left Right Center and REAR Left Right Center are exclusive */
108         if (speaker_flags.FLC_FRC) {
109                 cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
110                 cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
111         } else {
112                 cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
113                 cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
114         }
115
116         return cea_channels;
117 }
118
119 void afmt3_se_audio_setup(
120         struct afmt *afmt,
121         unsigned int az_inst,
122         struct audio_info *audio_info)
123 {
124         struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
125
126         uint32_t channels = 0;
127
128         ASSERT(audio_info);
129         /* This should not happen.it does so we don't get BSOD*/
130         if (audio_info == NULL)
131                 return;
132
133         channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
134
135         /* setup the audio stream source select (audio -> dig mapping) */
136         REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst);
137
138         /* Channel allocation */
139         REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
140
141         /* Disable forced mem power off */
142         if (afmt->funcs->afmt_poweron == NULL)
143                 REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
144 }
145
146 void afmt3_audio_mute_control(
147         struct afmt *afmt,
148         bool mute)
149 {
150         struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
151         if (mute && afmt->funcs->afmt_powerdown)
152                 afmt->funcs->afmt_powerdown(afmt);
153         if (!mute && afmt->funcs->afmt_poweron)
154                 afmt->funcs->afmt_poweron(afmt);
155         /* enable/disable transmission of audio packets */
156         REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
157 }
158
159 void afmt3_audio_info_immediate_update(
160         struct afmt *afmt)
161 {
162         struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
163
164         /* update double-buffered AUDIO_INFO registers immediately */
165         REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
166 }
167
168 void afmt3_setup_dp_audio(
169                 struct afmt *afmt)
170 {
171         struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
172
173         if (afmt->funcs->afmt_poweron)
174                 afmt->funcs->afmt_poweron(afmt);
175
176         /* AFMT_AUDIO_PACKET_CONTROL */
177         REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
178
179         /* AFMT_AUDIO_PACKET_CONTROL2 */
180         /* Program the ATP and AIP next */
181         REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
182                         AFMT_AUDIO_LAYOUT_OVRD, 0,
183                         AFMT_60958_OSF_OVRD, 0);
184
185         /* AFMT_INFOFRAME_CONTROL0 */
186         REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
187
188         /* AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */
189         REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0);
190 }
191
192 static struct afmt_funcs dcn30_afmt_funcs = {
193         .setup_hdmi_audio               = afmt3_setup_hdmi_audio,
194         .se_audio_setup                 = afmt3_se_audio_setup,
195         .audio_mute_control             = afmt3_audio_mute_control,
196         .audio_info_immediate_update    = afmt3_audio_info_immediate_update,
197         .setup_dp_audio                 = afmt3_setup_dp_audio,
198 };
199
200 void afmt3_construct(struct dcn30_afmt *afmt3,
201         struct dc_context *ctx,
202         uint32_t inst,
203         const struct dcn30_afmt_registers *afmt_regs,
204         const struct dcn30_afmt_shift *afmt_shift,
205         const struct dcn30_afmt_mask *afmt_mask)
206 {
207         afmt3->base.ctx = ctx;
208
209         afmt3->base.inst = inst;
210         afmt3->base.funcs = &dcn30_afmt_funcs;
211
212         afmt3->regs = afmt_regs;
213         afmt3->afmt_shift = afmt_shift;
214         afmt3->afmt_mask = afmt_mask;
215 }
This page took 0.045568 seconds and 4 git commands to generate.