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 "dcn31_apg.h"
0030 #include "reg_helper.h"
0031
0032 #define DC_LOGGER \
0033 apg31->base.ctx->logger
0034
0035 #define REG(reg)\
0036 (apg31->regs->reg)
0037
0038 #undef FN
0039 #define FN(reg_name, field_name) \
0040 apg31->apg_shift->field_name, apg31->apg_mask->field_name
0041
0042
0043 #define CTX \
0044 apg31->base.ctx
0045
0046
0047 static void apg31_enable(
0048 struct apg *apg)
0049 {
0050 struct dcn31_apg *apg31 = DCN31_APG_FROM_APG(apg);
0051
0052
0053 REG_UPDATE(APG_CONTROL, APG_RESET, 1);
0054 REG_WAIT(APG_CONTROL,
0055 APG_RESET_DONE, 1,
0056 1, 10);
0057 REG_UPDATE(APG_CONTROL, APG_RESET, 0);
0058 REG_WAIT(APG_CONTROL,
0059 APG_RESET_DONE, 0,
0060 1, 10);
0061
0062
0063 REG_UPDATE(APG_CONTROL2, APG_ENABLE, 1);
0064 }
0065
0066 static void apg31_disable(
0067 struct apg *apg)
0068 {
0069 struct dcn31_apg *apg31 = DCN31_APG_FROM_APG(apg);
0070
0071
0072 REG_UPDATE(APG_CONTROL2, APG_ENABLE, 0);
0073 }
0074
0075 static union audio_cea_channels speakers_to_channels(
0076 struct audio_speaker_flags speaker_flags)
0077 {
0078 union audio_cea_channels cea_channels = {0};
0079
0080
0081 cea_channels.channels.FL = speaker_flags.FL_FR;
0082 cea_channels.channels.FR = speaker_flags.FL_FR;
0083 cea_channels.channels.LFE = speaker_flags.LFE;
0084 cea_channels.channels.FC = speaker_flags.FC;
0085
0086
0087
0088
0089 if (speaker_flags.RL_RR) {
0090 cea_channels.channels.RL_RC = speaker_flags.RL_RR;
0091 cea_channels.channels.RR = speaker_flags.RL_RR;
0092 cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;
0093 } else {
0094 cea_channels.channels.RL_RC = speaker_flags.RC;
0095 }
0096
0097
0098 if (speaker_flags.FLC_FRC) {
0099 cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;
0100 cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;
0101 } else {
0102 cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;
0103 cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;
0104 }
0105
0106 return cea_channels;
0107 }
0108
0109 static void apg31_se_audio_setup(
0110 struct apg *apg,
0111 unsigned int az_inst,
0112 struct audio_info *audio_info)
0113 {
0114 struct dcn31_apg *apg31 = DCN31_APG_FROM_APG(apg);
0115
0116 uint32_t speakers = 0;
0117 uint32_t channels = 0;
0118
0119 ASSERT(audio_info);
0120
0121 if (audio_info == NULL)
0122 return;
0123
0124 speakers = audio_info->flags.info.ALLSPEAKERS;
0125 channels = speakers_to_channels(audio_info->flags.speaker_flags).all;
0126
0127
0128 REG_UPDATE(APG_CONTROL2, APG_DP_AUDIO_STREAM_ID, 0);
0129
0130
0131
0132 REG_UPDATE(APG_DBG_GEN_CONTROL, APG_DBG_AUDIO_CHANNEL_ENABLE, 0xFF);
0133
0134
0135
0136 REG_UPDATE(APG_MEM_PWR, APG_MEM_PWR_FORCE, 0);
0137
0138 apg31_enable(apg);
0139 }
0140
0141 static void apg31_audio_mute_control(
0142 struct apg *apg,
0143 bool mute)
0144 {
0145 if (mute)
0146 apg31_disable(apg);
0147 else
0148 apg31_enable(apg);
0149 }
0150
0151 static struct apg_funcs dcn31_apg_funcs = {
0152 .se_audio_setup = apg31_se_audio_setup,
0153 .audio_mute_control = apg31_audio_mute_control,
0154 .enable_apg = apg31_enable,
0155 .disable_apg = apg31_disable,
0156 };
0157
0158 void apg31_construct(struct dcn31_apg *apg31,
0159 struct dc_context *ctx,
0160 uint32_t inst,
0161 const struct dcn31_apg_registers *apg_regs,
0162 const struct dcn31_apg_shift *apg_shift,
0163 const struct dcn31_apg_mask *apg_mask)
0164 {
0165 apg31->base.ctx = ctx;
0166
0167 apg31->base.inst = inst;
0168 apg31->base.funcs = &dcn31_apg_funcs;
0169
0170 apg31->regs = apg_regs;
0171 apg31->apg_shift = apg_shift;
0172 apg31->apg_mask = apg_mask;
0173 }