LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dce - dce_audio.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 279 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2012-15 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             : #include "reg_helper.h"
      27             : #include "dce_audio.h"
      28             : #include "dce/dce_11_0_d.h"
      29             : #include "dce/dce_11_0_sh_mask.h"
      30             : 
      31             : #define DCE_AUD(audio)\
      32             :         container_of(audio, struct dce_audio, base)
      33             : 
      34             : #define CTX \
      35             :         aud->base.ctx
      36             : 
      37             : #define DC_LOGGER_INIT()
      38             : 
      39             : #define REG(reg)\
      40             :         (aud->regs->reg)
      41             : 
      42             : #undef FN
      43             : #define FN(reg_name, field_name) \
      44             :         aud->shifts->field_name, aud->masks->field_name
      45             : 
      46             : #define IX_REG(reg)\
      47             :         ix ## reg
      48             : 
      49             : #define AZ_REG_READ(reg_name) \
      50             :                 read_indirect_azalia_reg(audio, IX_REG(reg_name))
      51             : 
      52             : #define AZ_REG_WRITE(reg_name, value) \
      53             :                 write_indirect_azalia_reg(audio, IX_REG(reg_name), value)
      54             : 
      55           0 : static void write_indirect_azalia_reg(struct audio *audio,
      56             :         uint32_t reg_index,
      57             :         uint32_t reg_data)
      58             : {
      59           0 :         struct dce_audio *aud = DCE_AUD(audio);
      60             : 
      61             :         /* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
      62           0 :         REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
      63             :                         AZALIA_ENDPOINT_REG_INDEX, reg_index);
      64             : 
      65             :         /* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
      66           0 :         REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
      67             :                         AZALIA_ENDPOINT_REG_DATA, reg_data);
      68           0 : }
      69             : 
      70           0 : static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
      71             : {
      72           0 :         struct dce_audio *aud = DCE_AUD(audio);
      73             : 
      74           0 :         uint32_t value = 0;
      75             : 
      76             :         /* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
      77           0 :         REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
      78             :                         AZALIA_ENDPOINT_REG_INDEX, reg_index);
      79             : 
      80             :         /* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
      81           0 :         value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);
      82             : 
      83           0 :         return value;
      84             : }
      85             : 
      86             : static bool is_audio_format_supported(
      87             :         const struct audio_info *audio_info,
      88             :         enum audio_format_code audio_format_code,
      89             :         uint32_t *format_index)
      90             : {
      91             :         uint32_t index;
      92           0 :         uint32_t max_channe_index = 0;
      93           0 :         bool found = false;
      94             : 
      95           0 :         if (audio_info == NULL)
      96             :                 return found;
      97             : 
      98             :         /* pass through whole array */
      99           0 :         for (index = 0; index < audio_info->mode_count; index++) {
     100           0 :                 if (audio_info->modes[index].format_code == audio_format_code) {
     101           0 :                         if (found) {
     102             :                                 /* format has multiply entries, choose one with
     103             :                                  *  highst number of channels */
     104           0 :                                 if (audio_info->modes[index].channel_count >
     105           0 :                 audio_info->modes[max_channe_index].channel_count) {
     106           0 :                                         max_channe_index = index;
     107             :                                 }
     108             :                         } else {
     109             :                                 /* format found, save it's index */
     110             :                                 found = true;
     111             :                                 max_channe_index = index;
     112             :                         }
     113             :                 }
     114             :         }
     115             : 
     116             :         /* return index */
     117           0 :         if (found && format_index != NULL)
     118           0 :                 *format_index = max_channe_index;
     119             : 
     120             :         return found;
     121             : }
     122             : 
     123             : /*For HDMI, calculate if specified sample rates can fit into a given timing */
     124           0 : static void check_audio_bandwidth_hdmi(
     125             :         const struct audio_crtc_info *crtc_info,
     126             :         uint32_t channel_count,
     127             :         union audio_sample_rates *sample_rates)
     128             : {
     129             :         uint32_t samples;
     130             :         uint32_t  h_blank;
     131           0 :         bool limit_freq_to_48_khz = false;
     132           0 :         bool limit_freq_to_88_2_khz = false;
     133           0 :         bool limit_freq_to_96_khz = false;
     134           0 :         bool limit_freq_to_174_4_khz = false;
     135           0 :         if (!crtc_info)
     136             :                 return;
     137             : 
     138             :         /* For two channels supported return whatever sink support,unmodified*/
     139           0 :         if (channel_count > 2) {
     140             : 
     141             :                 /* Based on HDMI spec 1.3 Table 7.5 */
     142           0 :                 if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
     143           0 :                 (crtc_info->v_active <= 576) &&
     144           0 :                 !(crtc_info->interlaced) &&
     145           0 :                 !(crtc_info->pixel_repetition == 2 ||
     146             :                 crtc_info->pixel_repetition == 4)) {
     147             :                         limit_freq_to_48_khz = true;
     148             : 
     149           0 :                 } else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) &&
     150           0 :                                 (crtc_info->v_active <= 576) &&
     151           0 :                                 (crtc_info->interlaced) &&
     152           0 :                                 (crtc_info->pixel_repetition == 2)) {
     153             :                         limit_freq_to_88_2_khz = true;
     154             : 
     155           0 :                 } else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) &&
     156           0 :                                 (crtc_info->v_active <= 576) &&
     157           0 :                                 !(crtc_info->interlaced)) {
     158           0 :                         limit_freq_to_174_4_khz = true;
     159             :                 }
     160             :         }
     161             : 
     162             :         /* Also do some calculation for the available Audio Bandwidth for the
     163             :          * 8 ch (i.e. for the Layout 1 => ch > 2)
     164             :          */
     165           0 :         h_blank = crtc_info->h_total - crtc_info->h_active;
     166             : 
     167           0 :         if (crtc_info->pixel_repetition)
     168           0 :                 h_blank *= crtc_info->pixel_repetition;
     169             : 
     170             :         /*based on HDMI spec 1.3 Table 7.5 */
     171           0 :         h_blank -= 58;
     172             :         /*for Control Period */
     173           0 :         h_blank -= 16;
     174             : 
     175           0 :         samples = h_blank * 10;
     176             :         /* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
     177             :          * of Audio samples per line multiplied by 10 - Layout 1)
     178             :          */
     179           0 :         samples /= 32;
     180           0 :         samples *= crtc_info->v_active;
     181             :         /*Number of samples multiplied by 10, per second */
     182           0 :         samples *= crtc_info->refresh_rate;
     183             :         /*Number of Audio samples per second */
     184           0 :         samples /= 10;
     185             : 
     186             :         /* @todo do it after deep color is implemented
     187             :          * 8xx - deep color bandwidth scaling
     188             :          * Extra bandwidth is avaliable in deep color b/c link runs faster than
     189             :          * pixel rate. This has the effect of allowing more tmds characters to
     190             :          * be transmitted during blank
     191             :          */
     192             : 
     193           0 :         switch (crtc_info->color_depth) {
     194             :         case COLOR_DEPTH_888:
     195           0 :                 samples *= 4;
     196           0 :                 break;
     197             :         case COLOR_DEPTH_101010:
     198           0 :                 samples *= 5;
     199           0 :                 break;
     200             :         case COLOR_DEPTH_121212:
     201           0 :                 samples *= 6;
     202           0 :                 break;
     203             :         default:
     204           0 :                 samples *= 4;
     205           0 :                 break;
     206             :         }
     207             : 
     208           0 :         samples /= 4;
     209             : 
     210             :         /*check limitation*/
     211           0 :         if (samples < 88200)
     212             :                 limit_freq_to_48_khz = true;
     213           0 :         else if (samples < 96000)
     214             :                 limit_freq_to_88_2_khz = true;
     215           0 :         else if (samples < 176400)
     216             :                 limit_freq_to_96_khz = true;
     217           0 :         else if (samples < 192000)
     218           0 :                 limit_freq_to_174_4_khz = true;
     219             : 
     220           0 :         if (sample_rates != NULL) {
     221             :                 /* limit frequencies */
     222           0 :                 if (limit_freq_to_174_4_khz)
     223           0 :                         sample_rates->rate.RATE_192 = 0;
     224             : 
     225           0 :                 if (limit_freq_to_96_khz) {
     226           0 :                         sample_rates->rate.RATE_192 = 0;
     227           0 :                         sample_rates->rate.RATE_176_4 = 0;
     228             :                 }
     229           0 :                 if (limit_freq_to_88_2_khz) {
     230           0 :                         sample_rates->rate.RATE_192 = 0;
     231           0 :                         sample_rates->rate.RATE_176_4 = 0;
     232           0 :                         sample_rates->rate.RATE_96 = 0;
     233             :                 }
     234           0 :                 if (limit_freq_to_48_khz) {
     235           0 :                         sample_rates->rate.RATE_192 = 0;
     236           0 :                         sample_rates->rate.RATE_176_4 = 0;
     237           0 :                         sample_rates->rate.RATE_96 = 0;
     238           0 :                         sample_rates->rate.RATE_88_2 = 0;
     239             :                 }
     240             :         }
     241             : }
     242             : 
     243             : /*For DP SST, calculate if specified sample rates can fit into a given timing */
     244             : static void check_audio_bandwidth_dpsst(
     245             :         const struct audio_crtc_info *crtc_info,
     246             :         uint32_t channel_count,
     247             :         union audio_sample_rates *sample_rates)
     248             : {
     249             :         /* do nothing */
     250             : }
     251             : 
     252             : /*For DP MST, calculate if specified sample rates can fit into a given timing */
     253             : static void check_audio_bandwidth_dpmst(
     254             :         const struct audio_crtc_info *crtc_info,
     255             :         uint32_t channel_count,
     256             :         union audio_sample_rates *sample_rates)
     257             : {
     258             :         /* do nothing  */
     259             : }
     260             : 
     261             : static void check_audio_bandwidth(
     262             :         const struct audio_crtc_info *crtc_info,
     263             :         uint32_t channel_count,
     264             :         enum signal_type signal,
     265             :         union audio_sample_rates *sample_rates)
     266             : {
     267           0 :         switch (signal) {
     268             :         case SIGNAL_TYPE_HDMI_TYPE_A:
     269           0 :                 check_audio_bandwidth_hdmi(
     270             :                         crtc_info, channel_count, sample_rates);
     271             :                 break;
     272             :         case SIGNAL_TYPE_EDP:
     273             :         case SIGNAL_TYPE_DISPLAY_PORT:
     274             :                 check_audio_bandwidth_dpsst(
     275             :                         crtc_info, channel_count, sample_rates);
     276             :                 break;
     277             :         case SIGNAL_TYPE_DISPLAY_PORT_MST:
     278             :                 check_audio_bandwidth_dpmst(
     279             :                         crtc_info, channel_count, sample_rates);
     280             :                 break;
     281             :         default:
     282             :                 break;
     283             :         }
     284             : }
     285             : 
     286             : /* expose/not expose HBR capability to Audio driver */
     287           0 : static void set_high_bit_rate_capable(
     288             :         struct audio *audio,
     289             :         bool capable)
     290             : {
     291           0 :         uint32_t value = 0;
     292             : 
     293             :         /* set high bit rate audio capable*/
     294           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);
     295             : 
     296           0 :         set_reg_field_value(value, capable,
     297             :                 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
     298             :                 HBR_CAPABLE);
     299             : 
     300           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value);
     301           0 : }
     302             : 
     303             : /* set video latency in in ms/2+1 */
     304           0 : static void set_video_latency(
     305             :         struct audio *audio,
     306             :         int latency_in_ms)
     307             : {
     308           0 :         uint32_t value = 0;
     309             : 
     310           0 :         if ((latency_in_ms < 0) || (latency_in_ms > 255))
     311             :                 return;
     312             : 
     313           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
     314             : 
     315           0 :         set_reg_field_value(value, latency_in_ms,
     316             :                 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
     317             :                 VIDEO_LIPSYNC);
     318             : 
     319           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
     320             :                 value);
     321             : }
     322             : 
     323             : /* set audio latency in ms/2+1 */
     324           0 : static void set_audio_latency(
     325             :         struct audio *audio,
     326             :         int latency_in_ms)
     327             : {
     328           0 :         uint32_t value = 0;
     329             : 
     330           0 :         if (latency_in_ms < 0)
     331           0 :                 latency_in_ms = 0;
     332             : 
     333           0 :         if (latency_in_ms > 255)
     334           0 :                 latency_in_ms = 255;
     335             : 
     336           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);
     337             : 
     338           0 :         set_reg_field_value(value, latency_in_ms,
     339             :                 AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
     340             :                 AUDIO_LIPSYNC);
     341             : 
     342           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
     343             :                 value);
     344           0 : }
     345             : 
     346           0 : void dce_aud_az_enable(struct audio *audio)
     347             : {
     348           0 :         uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
     349             :         DC_LOGGER_INIT();
     350             : 
     351           0 :         set_reg_field_value(value, 1,
     352             :                             AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     353             :                             CLOCK_GATING_DISABLE);
     354           0 :         set_reg_field_value(value, 1,
     355             :                             AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     356             :                             AUDIO_ENABLED);
     357             : 
     358           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     359           0 :         set_reg_field_value(value, 0,
     360             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     361             :                         CLOCK_GATING_DISABLE);
     362           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     363             : 
     364             :         DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u  data: 0x%x\n",
     365             :                         audio->inst, value);
     366           0 : }
     367             : 
     368           0 : void dce_aud_az_disable(struct audio *audio)
     369             : {
     370             :         uint32_t value;
     371             :         DC_LOGGER_INIT();
     372             : 
     373           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
     374           0 :         set_reg_field_value(value, 1,
     375             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     376             :                         CLOCK_GATING_DISABLE);
     377           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     378             : 
     379           0 :         set_reg_field_value(value, 0,
     380             :                 AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     381             :                 AUDIO_ENABLED);
     382           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     383             : 
     384           0 :         set_reg_field_value(value, 0,
     385             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     386             :                         CLOCK_GATING_DISABLE);
     387           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     388           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
     389             :         DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u  data: 0x%x\n",
     390             :                         audio->inst, value);
     391           0 : }
     392             : 
     393           0 : void dce_aud_az_configure(
     394             :         struct audio *audio,
     395             :         enum signal_type signal,
     396             :         const struct audio_crtc_info *crtc_info,
     397             :         const struct audio_info *audio_info)
     398             : {
     399           0 :         struct dce_audio *aud = DCE_AUD(audio);
     400             : 
     401           0 :         uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
     402             :         uint32_t value;
     403           0 :         uint32_t field = 0;
     404             :         enum audio_format_code audio_format_code;
     405             :         uint32_t format_index;
     406             :         uint32_t index;
     407           0 :         bool is_ac3_supported = false;
     408             :         union audio_sample_rates sample_rate;
     409           0 :         uint32_t strlen = 0;
     410           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
     411           0 :         set_reg_field_value(value, 1,
     412             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     413             :                         CLOCK_GATING_DISABLE);
     414           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     415             : 
     416             :         /* Speaker Allocation */
     417             :         /*
     418             :         uint32_t value;
     419             :         uint32_t field = 0;*/
     420           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);
     421             : 
     422           0 :         set_reg_field_value(value,
     423             :                 speakers,
     424             :                 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     425             :                 SPEAKER_ALLOCATION);
     426             : 
     427             :         /* LFE_PLAYBACK_LEVEL = LFEPBL
     428             :          * LFEPBL = 0 : Unknown or refer to other information
     429             :          * LFEPBL = 1 : 0dB playback
     430             :          * LFEPBL = 2 : +10dB playback
     431             :          * LFE_BL = 3 : Reserved
     432             :          */
     433           0 :         set_reg_field_value(value,
     434             :                 0,
     435             :                 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     436             :                 LFE_PLAYBACK_LEVEL);
     437             :         /* todo: according to reg spec LFE_PLAYBACK_LEVEL is read only.
     438             :          *  why are we writing to it?  DCE8 does not write this */
     439             : 
     440             : 
     441           0 :         set_reg_field_value(value,
     442             :                 0,
     443             :                 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     444             :                 HDMI_CONNECTION);
     445             : 
     446           0 :         set_reg_field_value(value,
     447             :                 0,
     448             :                 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     449             :                 DP_CONNECTION);
     450             : 
     451           0 :         field = get_reg_field_value(value,
     452             :                         AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     453             :                         EXTRA_CONNECTION_INFO);
     454             : 
     455           0 :         field &= ~0x1;
     456             : 
     457           0 :         set_reg_field_value(value,
     458             :                 field,
     459             :                 AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     460             :                 EXTRA_CONNECTION_INFO);
     461             : 
     462             :         /* set audio for output signal */
     463           0 :         switch (signal) {
     464             :         case SIGNAL_TYPE_HDMI_TYPE_A:
     465           0 :                 set_reg_field_value(value,
     466             :                         1,
     467             :                         AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     468             :                         HDMI_CONNECTION);
     469             : 
     470           0 :                 break;
     471             : 
     472             :         case SIGNAL_TYPE_EDP:
     473             :         case SIGNAL_TYPE_DISPLAY_PORT:
     474             :         case SIGNAL_TYPE_DISPLAY_PORT_MST:
     475           0 :                 set_reg_field_value(value,
     476             :                         1,
     477             :                         AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
     478             :                         DP_CONNECTION);
     479           0 :                 break;
     480             :         default:
     481           0 :                 BREAK_TO_DEBUGGER();
     482           0 :                 break;
     483             :         }
     484             : 
     485           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value);
     486             : 
     487             :         /*  ACP Data - Supports AI  */
     488           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA);
     489             : 
     490           0 :         set_reg_field_value(
     491             :                 value,
     492             :                 audio_info->flags.info.SUPPORT_AI,
     493             :                 AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA,
     494             :                 SUPPORTS_AI);
     495             : 
     496           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_ACP_DATA, value);
     497             : 
     498             :         /*  Audio Descriptors   */
     499             :         /* pass through all formats */
     500           0 :         for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
     501             :                         format_index++) {
     502           0 :                 audio_format_code =
     503             :                         (AUDIO_FORMAT_CODE_FIRST + format_index);
     504             : 
     505             :                 /* those are unsupported, skip programming */
     506           0 :                 if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
     507           0 :                         audio_format_code == AUDIO_FORMAT_CODE_DST)
     508           0 :                         continue;
     509             : 
     510           0 :                 value = 0;
     511             : 
     512             :                 /* check if supported */
     513           0 :                 if (is_audio_format_supported(
     514             :                                 audio_info, audio_format_code, &index)) {
     515           0 :                         const struct audio_mode *audio_mode =
     516             :                                         &audio_info->modes[index];
     517           0 :                         union audio_sample_rates sample_rates =
     518             :                                         audio_mode->sample_rates;
     519           0 :                         uint8_t byte2 = audio_mode->max_bit_rate;
     520           0 :                         uint8_t channel_count = audio_mode->channel_count;
     521             : 
     522             :                         /* adjust specific properties */
     523           0 :                         switch (audio_format_code) {
     524             :                         case AUDIO_FORMAT_CODE_LINEARPCM: {
     525             : 
     526           0 :                                 check_audio_bandwidth(
     527             :                                         crtc_info,
     528             :                                         channel_count,
     529             :                                         signal,
     530             :                                         &sample_rates);
     531             : 
     532           0 :                                 byte2 = audio_mode->sample_size;
     533             : 
     534           0 :                                 set_reg_field_value(value,
     535             :                                                 sample_rates.all,
     536             :                                                 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
     537             :                                                 SUPPORTED_FREQUENCIES_STEREO);
     538             :                                 }
     539           0 :                                 break;
     540             :                         case AUDIO_FORMAT_CODE_AC3:
     541           0 :                                 is_ac3_supported = true;
     542           0 :                                 break;
     543             :                         case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
     544             :                         case AUDIO_FORMAT_CODE_DTS_HD:
     545             :                         case AUDIO_FORMAT_CODE_MAT_MLP:
     546             :                         case AUDIO_FORMAT_CODE_DST:
     547             :                         case AUDIO_FORMAT_CODE_WMAPRO:
     548             :                                 byte2 = audio_mode->vendor_specific;
     549             :                                 break;
     550             :                         default:
     551             :                                 break;
     552             :                         }
     553             : 
     554             :                         /* fill audio format data */
     555           0 :                         set_reg_field_value(value,
     556             :                                         channel_count - 1,
     557             :                                         AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
     558             :                                         MAX_CHANNELS);
     559             : 
     560           0 :                         set_reg_field_value(value,
     561             :                                         sample_rates.all,
     562             :                                         AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
     563             :                                         SUPPORTED_FREQUENCIES);
     564             : 
     565           0 :                         set_reg_field_value(value,
     566             :                                         byte2,
     567             :                                         AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
     568             :                                         DESCRIPTOR_BYTE_2);
     569             :                 } /* if */
     570             : 
     571           0 :                 AZ_REG_WRITE(
     572             :                                 AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,
     573             :                                 value);
     574             :         } /* for */
     575             : 
     576           0 :         if (is_ac3_supported)
     577             :                 /* todo: this reg global.  why program global register? */
     578           0 :                 REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
     579             :                                 0x05);
     580             : 
     581             :         /* check for 192khz/8-Ch support for HBR requirements */
     582           0 :         sample_rate.all = 0;
     583           0 :         sample_rate.rate.RATE_192 = 1;
     584             : 
     585           0 :         check_audio_bandwidth(
     586             :                 crtc_info,
     587             :                 8,
     588             :                 signal,
     589             :                 &sample_rate);
     590             : 
     591           0 :         set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);
     592             : 
     593             :         /* Audio and Video Lipsync */
     594           0 :         set_video_latency(audio, audio_info->video_latency);
     595           0 :         set_audio_latency(audio, audio_info->audio_latency);
     596             : 
     597           0 :         value = 0;
     598           0 :         set_reg_field_value(value, audio_info->manufacture_id,
     599             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
     600             :                 MANUFACTURER_ID);
     601             : 
     602           0 :         set_reg_field_value(value, audio_info->product_id,
     603             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
     604             :                 PRODUCT_ID);
     605             : 
     606           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
     607             :                 value);
     608             : 
     609           0 :         value = 0;
     610             : 
     611             :         /*get display name string length */
     612           0 :         while (audio_info->display_name[strlen++] != '\0') {
     613           0 :                 if (strlen >=
     614             :                 MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
     615             :                         break;
     616             :                 }
     617           0 :         set_reg_field_value(value, strlen,
     618             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
     619             :                 SINK_DESCRIPTION_LEN);
     620             : 
     621           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
     622             :                 value);
     623             :         DC_LOG_HW_AUDIO("\n\tAUDIO:az_configure: index: %u data, 0x%x, displayName %s: \n",
     624             :                 audio->inst, value, audio_info->display_name);
     625             : 
     626             :         /*
     627             :         *write the port ID:
     628             :         *PORT_ID0 = display index
     629             :         *PORT_ID1 = 16bit BDF
     630             :         *(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
     631             :         */
     632             : 
     633           0 :         value = 0;
     634             : 
     635           0 :         set_reg_field_value(value, audio_info->port_id[0],
     636             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
     637             :                 PORT_ID0);
     638             : 
     639           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value);
     640             : 
     641           0 :         value = 0;
     642           0 :         set_reg_field_value(value, audio_info->port_id[1],
     643             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
     644             :                 PORT_ID1);
     645             : 
     646           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value);
     647             : 
     648             :         /*write the 18 char monitor string */
     649             : 
     650           0 :         value = 0;
     651           0 :         set_reg_field_value(value, audio_info->display_name[0],
     652             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
     653             :                 DESCRIPTION0);
     654             : 
     655           0 :         set_reg_field_value(value, audio_info->display_name[1],
     656             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
     657             :                 DESCRIPTION1);
     658             : 
     659           0 :         set_reg_field_value(value, audio_info->display_name[2],
     660             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
     661             :                 DESCRIPTION2);
     662             : 
     663           0 :         set_reg_field_value(value, audio_info->display_name[3],
     664             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
     665             :                 DESCRIPTION3);
     666             : 
     667           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value);
     668             : 
     669           0 :         value = 0;
     670           0 :         set_reg_field_value(value, audio_info->display_name[4],
     671             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
     672             :                 DESCRIPTION4);
     673             : 
     674           0 :         set_reg_field_value(value, audio_info->display_name[5],
     675             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
     676             :                 DESCRIPTION5);
     677             : 
     678           0 :         set_reg_field_value(value, audio_info->display_name[6],
     679             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
     680             :                 DESCRIPTION6);
     681             : 
     682           0 :         set_reg_field_value(value, audio_info->display_name[7],
     683             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
     684             :                 DESCRIPTION7);
     685             : 
     686           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value);
     687             : 
     688           0 :         value = 0;
     689           0 :         set_reg_field_value(value, audio_info->display_name[8],
     690             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
     691             :                 DESCRIPTION8);
     692             : 
     693           0 :         set_reg_field_value(value, audio_info->display_name[9],
     694             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
     695             :                 DESCRIPTION9);
     696             : 
     697           0 :         set_reg_field_value(value, audio_info->display_name[10],
     698             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
     699             :                 DESCRIPTION10);
     700             : 
     701           0 :         set_reg_field_value(value, audio_info->display_name[11],
     702             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
     703             :                 DESCRIPTION11);
     704             : 
     705           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value);
     706             : 
     707           0 :         value = 0;
     708           0 :         set_reg_field_value(value, audio_info->display_name[12],
     709             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
     710             :                 DESCRIPTION12);
     711             : 
     712           0 :         set_reg_field_value(value, audio_info->display_name[13],
     713             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
     714             :                 DESCRIPTION13);
     715             : 
     716           0 :         set_reg_field_value(value, audio_info->display_name[14],
     717             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
     718             :                 DESCRIPTION14);
     719             : 
     720           0 :         set_reg_field_value(value, audio_info->display_name[15],
     721             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
     722             :                 DESCRIPTION15);
     723             : 
     724           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value);
     725             : 
     726           0 :         value = 0;
     727           0 :         set_reg_field_value(value, audio_info->display_name[16],
     728             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
     729             :                 DESCRIPTION16);
     730             : 
     731           0 :         set_reg_field_value(value, audio_info->display_name[17],
     732             :                 AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
     733             :                 DESCRIPTION17);
     734             : 
     735           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
     736           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
     737           0 :         set_reg_field_value(value, 0,
     738             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
     739             :                         CLOCK_GATING_DISABLE);
     740           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
     741           0 : }
     742             : 
     743             : /*
     744             : * todo: wall clk related functionality probably belong to clock_src.
     745             : */
     746             : 
     747             : /* search pixel clock value for Azalia HDMI Audio */
     748             : static void get_azalia_clock_info_hdmi(
     749             :         uint32_t crtc_pixel_clock_100hz,
     750             :         uint32_t actual_pixel_clock_100Hz,
     751             :         struct azalia_clock_info *azalia_clock_info)
     752             : {
     753             :         /* audio_dto_phase= 24 * 10,000;
     754             :          *   24MHz in [100Hz] units */
     755           0 :         azalia_clock_info->audio_dto_phase =
     756             :                         24 * 10000;
     757             : 
     758             :         /* audio_dto_module = PCLKFrequency * 10,000;
     759             :          *  [khz] -> [100Hz] */
     760           0 :         azalia_clock_info->audio_dto_module =
     761             :                         actual_pixel_clock_100Hz;
     762             : }
     763             : 
     764             : static void get_azalia_clock_info_dp(
     765             :         uint32_t requested_pixel_clock_100Hz,
     766             :         const struct audio_pll_info *pll_info,
     767             :         struct azalia_clock_info *azalia_clock_info)
     768             : {
     769             :         /* Reported dpDtoSourceClockInkhz value for
     770             :          * DCE8 already adjusted for SS, do not need any
     771             :          * adjustment here anymore
     772             :          */
     773             : 
     774             :         /*audio_dto_phase = 24 * 10,000;
     775             :          * 24MHz in [100Hz] units */
     776           0 :         azalia_clock_info->audio_dto_phase = 24 * 10000;
     777             : 
     778             :         /*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
     779             :          *  [khz] ->[100Hz] */
     780           0 :         azalia_clock_info->audio_dto_module =
     781           0 :                 pll_info->dp_dto_source_clock_in_khz * 10;
     782             : }
     783             : 
     784           0 : void dce_aud_wall_dto_setup(
     785             :         struct audio *audio,
     786             :         enum signal_type signal,
     787             :         const struct audio_crtc_info *crtc_info,
     788             :         const struct audio_pll_info *pll_info)
     789             : {
     790           0 :         struct dce_audio *aud = DCE_AUD(audio);
     791             : 
     792           0 :         struct azalia_clock_info clock_info = { 0 };
     793             : 
     794           0 :         if (dc_is_hdmi_tmds_signal(signal)) {
     795             :                 uint32_t src_sel;
     796             : 
     797             :                 /*DTO0 Programming goal:
     798             :                 -generate 24MHz, 128*Fs from 24MHz
     799             :                 -use DTO0 when an active HDMI port is connected
     800             :                 (optionally a DP is connected) */
     801             : 
     802             :                 /* calculate DTO settings */
     803           0 :                 get_azalia_clock_info_hdmi(
     804             :                         crtc_info->requested_pixel_clock_100Hz,
     805             :                         crtc_info->calculated_pixel_clock_100Hz,
     806             :                         &clock_info);
     807             : 
     808             :                 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
     809             :                                 "calculated_pixel_clock_100Hz =%d\n"\
     810             :                                 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
     811             :                                 crtc_info->requested_pixel_clock_100Hz,\
     812             :                                 crtc_info->calculated_pixel_clock_100Hz,\
     813             :                                 clock_info.audio_dto_module,\
     814             :                                 clock_info.audio_dto_phase);
     815             : 
     816             :                 /* On TN/SI, Program DTO source select and DTO select before
     817             :                 programming DTO modulo and DTO phase. These bits must be
     818             :                 programmed first, otherwise there will be no HDMI audio at boot
     819             :                 up. This is a HW sequence change (different from old ASICs).
     820             :                 Caution when changing this programming sequence.
     821             : 
     822             :                 HDMI enabled, using DTO0
     823             :                 program master CRTC for DTO0 */
     824           0 :                 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
     825           0 :                 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
     826             :                         DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
     827             :                         DCCG_AUDIO_DTO_SEL, 0);
     828             : 
     829             :                 /* module */
     830           0 :                 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
     831             :                         DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
     832             : 
     833             :                 /* phase */
     834           0 :                 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
     835             :                         DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
     836             :         } else {
     837             :                 /*DTO1 Programming goal:
     838             :                 -generate 24MHz, 512*Fs, 128*Fs from 24MHz
     839             :                 -default is to used DTO1, and switch to DTO0 when an audio
     840             :                 master HDMI port is connected
     841             :                 -use as default for DP
     842             : 
     843             :                 calculate DTO settings */
     844           0 :                 get_azalia_clock_info_dp(
     845             :                         crtc_info->requested_pixel_clock_100Hz,
     846             :                         pll_info,
     847             :                         &clock_info);
     848             : 
     849             :                 /* Program DTO select before programming DTO modulo and DTO
     850             :                 phase. default to use DTO1 */
     851             : 
     852           0 :                 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     853             :                                 DCCG_AUDIO_DTO_SEL, 1);
     854             : 
     855             :                         /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
     856             :                          * Select 512fs for DP TODO: web register definition
     857             :                          * does not match register header file
     858             :                          * DCE11 version it's commented out while DCE8 it's set to 1
     859             :                         */
     860             : 
     861             :                 /* module */
     862           0 :                 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
     863             :                                 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
     864             : 
     865             :                 /* phase */
     866           0 :                 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
     867             :                                 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
     868             : 
     869           0 :                 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     870             :                                 DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1);
     871             : 
     872             :         }
     873           0 : }
     874             : 
     875             : #if defined(CONFIG_DRM_AMD_DC_SI)
     876             : static void dce60_aud_wall_dto_setup(
     877             :         struct audio *audio,
     878             :         enum signal_type signal,
     879             :         const struct audio_crtc_info *crtc_info,
     880             :         const struct audio_pll_info *pll_info)
     881             : {
     882             :         struct dce_audio *aud = DCE_AUD(audio);
     883             : 
     884             :         struct azalia_clock_info clock_info = { 0 };
     885             : 
     886             :         if (dc_is_hdmi_signal(signal)) {
     887             :                 uint32_t src_sel;
     888             : 
     889             :                 /*DTO0 Programming goal:
     890             :                 -generate 24MHz, 128*Fs from 24MHz
     891             :                 -use DTO0 when an active HDMI port is connected
     892             :                 (optionally a DP is connected) */
     893             : 
     894             :                 /* calculate DTO settings */
     895             :                 get_azalia_clock_info_hdmi(
     896             :                         crtc_info->requested_pixel_clock_100Hz,
     897             :                         crtc_info->calculated_pixel_clock_100Hz,
     898             :                         &clock_info);
     899             : 
     900             :                 DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\
     901             :                                 "calculated_pixel_clock_100Hz =%d\n"\
     902             :                                 "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
     903             :                                 crtc_info->requested_pixel_clock_100Hz,\
     904             :                                 crtc_info->calculated_pixel_clock_100Hz,\
     905             :                                 clock_info.audio_dto_module,\
     906             :                                 clock_info.audio_dto_phase);
     907             : 
     908             :                 /* On TN/SI, Program DTO source select and DTO select before
     909             :                 programming DTO modulo and DTO phase. These bits must be
     910             :                 programmed first, otherwise there will be no HDMI audio at boot
     911             :                 up. This is a HW sequence change (different from old ASICs).
     912             :                 Caution when changing this programming sequence.
     913             : 
     914             :                 HDMI enabled, using DTO0
     915             :                 program master CRTC for DTO0 */
     916             :                 src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
     917             :                 REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
     918             :                         DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
     919             :                         DCCG_AUDIO_DTO_SEL, 0);
     920             : 
     921             :                 /* module */
     922             :                 REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
     923             :                         DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);
     924             : 
     925             :                 /* phase */
     926             :                 REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
     927             :                         DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
     928             :         } else {
     929             :                 /*DTO1 Programming goal:
     930             :                 -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs)
     931             :                 -default is to used DTO1, and switch to DTO0 when an audio
     932             :                 master HDMI port is connected
     933             :                 -use as default for DP
     934             : 
     935             :                 calculate DTO settings */
     936             :                 get_azalia_clock_info_dp(
     937             :                         crtc_info->requested_pixel_clock_100Hz,
     938             :                         pll_info,
     939             :                         &clock_info);
     940             : 
     941             :                 /* Program DTO select before programming DTO modulo and DTO
     942             :                 phase. default to use DTO1 */
     943             : 
     944             :                 REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
     945             :                                 DCCG_AUDIO_DTO_SEL, 1);
     946             : 
     947             :                         /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
     948             :                          * Cannot select 512fs for DP
     949             :                          *
     950             :                          * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask
     951             :                         */
     952             : 
     953             :                 /* module */
     954             :                 REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
     955             :                                 DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);
     956             : 
     957             :                 /* phase */
     958             :                 REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
     959             :                                 DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);
     960             : 
     961             :                 /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */
     962             : 
     963             :         }
     964             : }
     965             : #endif
     966             : 
     967           0 : static bool dce_aud_endpoint_valid(struct audio *audio)
     968             : {
     969             :         uint32_t value;
     970             :         uint32_t port_connectivity;
     971             : 
     972           0 :         value = AZ_REG_READ(
     973             :                         AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);
     974             : 
     975           0 :         port_connectivity = get_reg_field_value(value,
     976             :                         AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
     977             :                         PORT_CONNECTIVITY);
     978             : 
     979           0 :         return !(port_connectivity == 1);
     980             : }
     981             : 
     982             : /* initialize HW state */
     983           0 : void dce_aud_hw_init(
     984             :                 struct audio *audio)
     985             : {
     986             :         uint32_t value;
     987           0 :         struct dce_audio *aud = DCE_AUD(audio);
     988             : 
     989             :         /* we only need to program the following registers once, so we only do
     990             :         it for the inst 0*/
     991           0 :         if (audio->inst != 0)
     992             :                 return;
     993             : 
     994             :         /* Suport R5 - 32khz
     995             :          * Suport R6 - 44.1khz
     996             :          * Suport R7 - 48khz
     997             :          */
     998             :         /*disable clock gating before write to endpoint register*/
     999           0 :         value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
    1000           0 :         set_reg_field_value(value, 1,
    1001             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
    1002             :                         CLOCK_GATING_DISABLE);
    1003           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
    1004           0 :         REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
    1005             :                         AUDIO_RATE_CAPABILITIES, 0x70);
    1006             : 
    1007             :         /*Keep alive bit to verify HW block in BU. */
    1008           0 :         REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
    1009             :                         CLKSTOP, 1,
    1010             :                         EPSS, 1);
    1011           0 :         set_reg_field_value(value, 0,
    1012             :                         AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
    1013             :                         CLOCK_GATING_DISABLE);
    1014           0 :         AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
    1015             : }
    1016             : 
    1017             : static const struct audio_funcs funcs = {
    1018             :         .endpoint_valid = dce_aud_endpoint_valid,
    1019             :         .hw_init = dce_aud_hw_init,
    1020             :         .wall_dto_setup = dce_aud_wall_dto_setup,
    1021             :         .az_enable = dce_aud_az_enable,
    1022             :         .az_disable = dce_aud_az_disable,
    1023             :         .az_configure = dce_aud_az_configure,
    1024             :         .destroy = dce_aud_destroy,
    1025             : };
    1026             : 
    1027             : #if defined(CONFIG_DRM_AMD_DC_SI)
    1028             : static const struct audio_funcs dce60_funcs = {
    1029             :         .endpoint_valid = dce_aud_endpoint_valid,
    1030             :         .hw_init = dce_aud_hw_init,
    1031             :         .wall_dto_setup = dce60_aud_wall_dto_setup,
    1032             :         .az_enable = dce_aud_az_enable,
    1033             :         .az_disable = dce_aud_az_disable,
    1034             :         .az_configure = dce_aud_az_configure,
    1035             :         .destroy = dce_aud_destroy,
    1036             : };
    1037             : #endif
    1038             : 
    1039           0 : void dce_aud_destroy(struct audio **audio)
    1040             : {
    1041           0 :         struct dce_audio *aud = DCE_AUD(*audio);
    1042             : 
    1043           0 :         kfree(aud);
    1044           0 :         *audio = NULL;
    1045           0 : }
    1046             : 
    1047           0 : struct audio *dce_audio_create(
    1048             :                 struct dc_context *ctx,
    1049             :                 unsigned int inst,
    1050             :                 const struct dce_audio_registers *reg,
    1051             :                 const struct dce_audio_shift *shifts,
    1052             :                 const struct dce_audio_mask *masks
    1053             :                 )
    1054             : {
    1055           0 :         struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
    1056             : 
    1057           0 :         if (audio == NULL) {
    1058           0 :                 ASSERT_CRITICAL(audio);
    1059           0 :                 return NULL;
    1060             :         }
    1061             : 
    1062           0 :         audio->base.ctx = ctx;
    1063           0 :         audio->base.inst = inst;
    1064           0 :         audio->base.funcs = &funcs;
    1065             : 
    1066           0 :         audio->regs = reg;
    1067           0 :         audio->shifts = shifts;
    1068           0 :         audio->masks = masks;
    1069           0 :         return &audio->base;
    1070             : }
    1071             : 
    1072             : #if defined(CONFIG_DRM_AMD_DC_SI)
    1073             : struct audio *dce60_audio_create(
    1074             :                 struct dc_context *ctx,
    1075             :                 unsigned int inst,
    1076             :                 const struct dce_audio_registers *reg,
    1077             :                 const struct dce_audio_shift *shifts,
    1078             :                 const struct dce_audio_mask *masks
    1079             :                 )
    1080             : {
    1081             :         struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);
    1082             : 
    1083             :         if (audio == NULL) {
    1084             :                 ASSERT_CRITICAL(audio);
    1085             :                 return NULL;
    1086             :         }
    1087             : 
    1088             :         audio->base.ctx = ctx;
    1089             :         audio->base.inst = inst;
    1090             :         audio->base.funcs = &dce60_funcs;
    1091             : 
    1092             :         audio->regs = reg;
    1093             :         audio->shifts = shifts;
    1094             :         audio->masks = masks;
    1095             :         return &audio->base;
    1096             : }
    1097             : #endif

Generated by: LCOV version 1.14