drm/amd/display: dce_audio: add DCE6 specific macros,functions
authorMauro Rossi <issor.oruam@gmail.com>
Fri, 10 Jul 2020 18:00:51 +0000 (20:00 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 27 Jul 2020 20:46:12 +0000 (16:46 -0400)
[Why]
DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE register

[How]
Add DCE6 specific macros definitions for AUD masks
DCE6 AUD macros will avoid buiding errors when using DCE6 headers
Add dce60_aud_wall_dto_setup() w/o 512*Fs programming
Use dce60_aud_wall_dto_setup() in dce60_funcs
Add DCE specific dce60_audio_create

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dce/dce_audio.c
drivers/gpu/drm/amd/display/dc/dce/dce_audio.h

index 4080465..2a2a0fd 100644 (file)
@@ -867,6 +867,98 @@ void dce_aud_wall_dto_setup(
        }
 }
 
+#if defined(CONFIG_DRM_AMD_DC_SI)
+void dce60_aud_wall_dto_setup(
+       struct audio *audio,
+       enum signal_type signal,
+       const struct audio_crtc_info *crtc_info,
+       const struct audio_pll_info *pll_info)
+{
+       struct dce_audio *aud = DCE_AUD(audio);
+
+       struct azalia_clock_info clock_info = { 0 };
+
+       if (dc_is_hdmi_signal(signal)) {
+               uint32_t src_sel;
+
+               /*DTO0 Programming goal:
+               -generate 24MHz, 128*Fs from 24MHz
+               -use DTO0 when an active HDMI port is connected
+               (optionally a DP is connected) */
+
+               /* calculate DTO settings */
+               get_azalia_clock_info_hdmi(
+                       crtc_info->requested_pixel_clock_100Hz,
+                       crtc_info->calculated_pixel_clock_100Hz,
+                       &clock_info);
+
+               DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
+                               "calculated_pixel_clock_100Hz =%d\n"\
+                               "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
+                               crtc_info->requested_pixel_clock_100Hz,\
+                               crtc_info->calculated_pixel_clock_100Hz,\
+                               clock_info.audio_dto_module,\
+                               clock_info.audio_dto_phase);
+
+               /* On TN/SI, Program DTO source select and DTO select before
+               programming DTO modulo and DTO phase. These bits must be
+               programmed first, otherwise there will be no HDMI audio at boot
+               up. This is a HW sequence change (different from old ASICs).
+               Caution when changing this programming sequence.
+
+               HDMI enabled, using DTO0
+               program master CRTC for DTO0 */
+               src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
+               REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
+                       DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
+                       DCCG_AUDIO_DTO_SEL, 0);
+
+               /* module */
+               REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
+                       DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
+
+               /* phase */
+               REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
+                       DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
+       } else {
+               /*DTO1 Programming goal:
+               -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs)
+               -default is to used DTO1, and switch to DTO0 when an audio
+               master HDMI port is connected
+               -use as default for DP
+
+               calculate DTO settings */
+               get_azalia_clock_info_dp(
+                       crtc_info->requested_pixel_clock_100Hz,
+                       pll_info,
+                       &clock_info);
+
+               /* Program DTO select before programming DTO modulo and DTO
+               phase. default to use DTO1 */
+
+               REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
+                               DCCG_AUDIO_DTO_SEL, 1);
+
+                       /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
+                        * Cannot select 512fs for DP
+                        *
+                        * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask
+                       */
+
+               /* module */
+               REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
+                               DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
+
+               /* phase */
+               REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
+                               DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
+
+               /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */
+
+       }
+}
+#endif
+
 static bool dce_aud_endpoint_valid(struct audio *audio)
 {
        uint32_t value;
@@ -926,6 +1018,19 @@ static const struct audio_funcs funcs = {
        .az_configure = dce_aud_az_configure,
        .destroy = dce_aud_destroy,
 };
+
+#if defined(CONFIG_DRM_AMD_DC_SI)
+static const struct audio_funcs dce60_funcs = {
+       .endpoint_valid = dce_aud_endpoint_valid,
+       .hw_init = dce_aud_hw_init,
+       .wall_dto_setup = dce60_aud_wall_dto_setup,
+       .az_enable = dce_aud_az_enable,
+       .az_disable = dce_aud_az_disable,
+       .az_configure = dce_aud_az_configure,
+       .destroy = dce_aud_destroy,
+};
+#endif
+
 void dce_aud_destroy(struct audio **audio)
 {
        struct dce_audio *aud = DCE_AUD(*audio);
@@ -959,3 +1064,29 @@ struct audio *dce_audio_create(
        return &audio->base;
 }
 
+#if defined(CONFIG_DRM_AMD_DC_SI)
+struct audio *dce60_audio_create(
+               struct dc_context *ctx,
+               unsigned int inst,
+               const struct dce_audio_registers *reg,
+               const struct dce_audio_shift *shifts,
+               const struct dce_audio_mask *masks
+               )
+{
+       struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
+
+       if (audio == NULL) {
+               ASSERT_CRITICAL(audio);
+               return NULL;
+       }
+
+       audio->base.ctx = ctx;
+       audio->base.inst = inst;
+       audio->base.funcs = &dce60_funcs;
+
+       audio->regs = reg;
+       audio->shifts = shifts;
+       audio->masks = masks;
+       return &audio->base;
+}
+#endif
index 1392fab..5622d5e 100644 (file)
                SF(AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
                SF(AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh)
 
+#if defined(CONFIG_DRM_AMD_DC_SI)
+#define AUD_DCE60_MASK_SH_LIST(mask_sh)\
+               SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO0_SOURCE_SEL, mask_sh),\
+               SF(DCCG_AUDIO_DTO_SOURCE, DCCG_AUDIO_DTO_SEL, mask_sh),\
+               SF(DCCG_AUDIO_DTO0_MODULE, DCCG_AUDIO_DTO0_MODULE, mask_sh),\
+               SF(DCCG_AUDIO_DTO0_PHASE, DCCG_AUDIO_DTO0_PHASE, mask_sh),\
+               SF(DCCG_AUDIO_DTO1_MODULE, DCCG_AUDIO_DTO1_MODULE, mask_sh),\
+               SF(DCCG_AUDIO_DTO1_PHASE, DCCG_AUDIO_DTO1_PHASE, mask_sh),\
+               SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES, AUDIO_RATE_CAPABILITIES, mask_sh),\
+               SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, CLKSTOP, mask_sh),\
+               SF(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES, EPSS, mask_sh), \
+               SF(AZALIA_F0_CODEC_ENDPOINT_INDEX, AZALIA_ENDPOINT_REG_INDEX, mask_sh),\
+               SF(AZALIA_F0_CODEC_ENDPOINT_DATA, AZALIA_ENDPOINT_REG_DATA, mask_sh)
+#endif
 
 struct dce_audio_registers {
        uint32_t AZALIA_F0_CODEC_ENDPOINT_INDEX;
@@ -135,6 +149,15 @@ struct audio *dce_audio_create(
                const struct dce_audio_shift *shifts,
                const struct dce_audio_mask *masks);
 
+#if defined(CONFIG_DRM_AMD_DC_SI)
+struct audio *dce60_audio_create(
+               struct dc_context *ctx,
+               unsigned int inst,
+               const struct dce_audio_registers *reg,
+               const struct dce_audio_shift *shifts,
+               const struct dce_audio_mask *masks);
+#endif
+
 void dce_aud_destroy(struct audio **audio);
 
 void dce_aud_hw_init(struct audio *audio);