0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include "dc_bios_types.h"
0028 #include "hw_shared.h"
0029 #include "dcn30_afmt.h"
0030 #include "reg_helper.h"
0031
0032 #define DC_LOGGER \
0033 afmt3->base.ctx->logger
0034
0035 #define REG(reg)\
0036 (afmt3->regs->reg)
0037
0038 #undef FN
0039 #define FN(reg_name, field_name) \
0040 afmt3->afmt_shift->field_name, afmt3->afmt_mask->field_name
0041
0042
0043 #define CTX \
0044 afmt3->base.ctx
0045
0046
0047 void afmt3_setup_hdmi_audio(
0048 struct afmt *afmt)
0049 {
0050 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
0051
0052 if (afmt->funcs->afmt_poweron)
0053 afmt->funcs->afmt_poweron(afmt);
0054
0055
0056 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
0057
0058
0059 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
0060 AFMT_AUDIO_LAYOUT_OVRD, 0,
0061 AFMT_60958_OSF_OVRD, 0);
0062
0063
0064
0065
0066 REG_UPDATE_2(AFMT_60958_0,
0067 AFMT_60958_CS_CHANNEL_NUMBER_L, 1,
0068 AFMT_60958_CS_CLOCK_ACCURACY, 0);
0069
0070
0071 REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2);
0072
0073
0074
0075
0076 REG_UPDATE_6(AFMT_60958_2,
0077 AFMT_60958_CS_CHANNEL_NUMBER_2, 3,
0078 AFMT_60958_CS_CHANNEL_NUMBER_3, 4,
0079 AFMT_60958_CS_CHANNEL_NUMBER_4, 5,
0080 AFMT_60958_CS_CHANNEL_NUMBER_5, 6,
0081 AFMT_60958_CS_CHANNEL_NUMBER_6, 7,
0082 AFMT_60958_CS_CHANNEL_NUMBER_7, 8);
0083 }
0084
0085 static union audio_cea_channels speakers_to_channels(
0086 struct audio_speaker_flags speaker_flags)
0087 {
0088 union audio_cea_channels cea_channels = {0};
0089
0090
0091 cea_channels.channels.FL = speaker_flags.FL_FR;
0092 cea_channels.channels.FR = speaker_flags.FL_FR;
0093 cea_channels.channels.LFE = speaker_flags.LFE;
0094 cea_channels.channels.FC = speaker_flags.FC;
0095
0096
0097
0098
0099 if (speaker_flags.RL_RR) {
0100 cea_channels.channels.RL_RC = speaker_flags.RL_RR;
0101 cea_channels.channels.RR = speaker_flags.RL_RR;
0102 cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
0103 } else {
0104 cea_channels.channels.RL_RC = speaker_flags.RC;
0105 }
0106
0107
0108 if (speaker_flags.FLC_FRC) {
0109 cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
0110 cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
0111 } else {
0112 cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
0113 cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
0114 }
0115
0116 return cea_channels;
0117 }
0118
0119 void afmt3_se_audio_setup(
0120 struct afmt *afmt,
0121 unsigned int az_inst,
0122 struct audio_info *audio_info)
0123 {
0124 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
0125
0126 uint32_t speakers = 0;
0127 uint32_t channels = 0;
0128
0129 ASSERT(audio_info);
0130
0131 if (audio_info == NULL)
0132 return;
0133
0134 speakers = audio_info->flags.info.ALLSPEAKERS;
0135 channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
0136
0137
0138 REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst);
0139
0140
0141 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);
0142
0143
0144 if (afmt->funcs->afmt_poweron == NULL)
0145 REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);
0146 }
0147
0148 void afmt3_audio_mute_control(
0149 struct afmt *afmt,
0150 bool mute)
0151 {
0152 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
0153 if (mute && afmt->funcs->afmt_powerdown)
0154 afmt->funcs->afmt_powerdown(afmt);
0155 if (!mute && afmt->funcs->afmt_poweron)
0156 afmt->funcs->afmt_poweron(afmt);
0157
0158 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);
0159 }
0160
0161 void afmt3_audio_info_immediate_update(
0162 struct afmt *afmt)
0163 {
0164 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
0165
0166
0167 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
0168 }
0169
0170 void afmt3_setup_dp_audio(
0171 struct afmt *afmt)
0172 {
0173 struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt);
0174
0175 if (afmt->funcs->afmt_poweron)
0176 afmt->funcs->afmt_poweron(afmt);
0177
0178
0179 REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);
0180
0181
0182
0183 REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,
0184 AFMT_AUDIO_LAYOUT_OVRD, 0,
0185 AFMT_60958_OSF_OVRD, 0);
0186
0187
0188 REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);
0189
0190
0191 REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0);
0192 }
0193
0194 static struct afmt_funcs dcn30_afmt_funcs = {
0195 .setup_hdmi_audio = afmt3_setup_hdmi_audio,
0196 .se_audio_setup = afmt3_se_audio_setup,
0197 .audio_mute_control = afmt3_audio_mute_control,
0198 .audio_info_immediate_update = afmt3_audio_info_immediate_update,
0199 .setup_dp_audio = afmt3_setup_dp_audio,
0200 };
0201
0202 void afmt3_construct(struct dcn30_afmt *afmt3,
0203 struct dc_context *ctx,
0204 uint32_t inst,
0205 const struct dcn30_afmt_registers *afmt_regs,
0206 const struct dcn30_afmt_shift *afmt_shift,
0207 const struct dcn30_afmt_mask *afmt_mask)
0208 {
0209 afmt3->base.ctx = ctx;
0210
0211 afmt3->base.inst = inst;
0212 afmt3->base.funcs = &dcn30_afmt_funcs;
0213
0214 afmt3->regs = afmt_regs;
0215 afmt3->afmt_shift = afmt_shift;
0216 afmt3->afmt_mask = afmt_mask;
0217 }