| .. | .. |
|---|
| 23 | 23 | * |
|---|
| 24 | 24 | */ |
|---|
| 25 | 25 | |
|---|
| 26 | +#include <linux/slab.h> |
|---|
| 27 | + |
|---|
| 26 | 28 | #include "reg_helper.h" |
|---|
| 27 | 29 | #include "dce_audio.h" |
|---|
| 28 | 30 | #include "dce/dce_11_0_d.h" |
|---|
| .. | .. |
|---|
| 138 | 140 | bool limit_freq_to_88_2_khz = false; |
|---|
| 139 | 141 | bool limit_freq_to_96_khz = false; |
|---|
| 140 | 142 | bool limit_freq_to_174_4_khz = false; |
|---|
| 143 | + if (!crtc_info) |
|---|
| 144 | + return; |
|---|
| 141 | 145 | |
|---|
| 142 | 146 | /* For two channels supported return whatever sink support,unmodified*/ |
|---|
| 143 | 147 | if (channel_count > 2) { |
|---|
| 144 | 148 | |
|---|
| 145 | 149 | /* Based on HDMI spec 1.3 Table 7.5 */ |
|---|
| 146 | | - if ((crtc_info->requested_pixel_clock <= 27000) && |
|---|
| 150 | + if ((crtc_info->requested_pixel_clock_100Hz <= 270000) && |
|---|
| 147 | 151 | (crtc_info->v_active <= 576) && |
|---|
| 148 | 152 | !(crtc_info->interlaced) && |
|---|
| 149 | 153 | !(crtc_info->pixel_repetition == 2 || |
|---|
| 150 | 154 | crtc_info->pixel_repetition == 4)) { |
|---|
| 151 | 155 | limit_freq_to_48_khz = true; |
|---|
| 152 | 156 | |
|---|
| 153 | | - } else if ((crtc_info->requested_pixel_clock <= 27000) && |
|---|
| 157 | + } else if ((crtc_info->requested_pixel_clock_100Hz <= 270000) && |
|---|
| 154 | 158 | (crtc_info->v_active <= 576) && |
|---|
| 155 | 159 | (crtc_info->interlaced) && |
|---|
| 156 | 160 | (crtc_info->pixel_repetition == 2)) { |
|---|
| 157 | 161 | limit_freq_to_88_2_khz = true; |
|---|
| 158 | 162 | |
|---|
| 159 | | - } else if ((crtc_info->requested_pixel_clock <= 54000) && |
|---|
| 163 | + } else if ((crtc_info->requested_pixel_clock_100Hz <= 540000) && |
|---|
| 160 | 164 | (crtc_info->v_active <= 576) && |
|---|
| 161 | 165 | !(crtc_info->interlaced)) { |
|---|
| 162 | 166 | limit_freq_to_174_4_khz = true; |
|---|
| .. | .. |
|---|
| 737 | 741 | |
|---|
| 738 | 742 | /* search pixel clock value for Azalia HDMI Audio */ |
|---|
| 739 | 743 | static void get_azalia_clock_info_hdmi( |
|---|
| 740 | | - uint32_t crtc_pixel_clock_in_khz, |
|---|
| 741 | | - uint32_t actual_pixel_clock_in_khz, |
|---|
| 744 | + uint32_t crtc_pixel_clock_100hz, |
|---|
| 745 | + uint32_t actual_pixel_clock_100Hz, |
|---|
| 742 | 746 | struct azalia_clock_info *azalia_clock_info) |
|---|
| 743 | 747 | { |
|---|
| 744 | 748 | /* audio_dto_phase= 24 * 10,000; |
|---|
| .. | .. |
|---|
| 749 | 753 | /* audio_dto_module = PCLKFrequency * 10,000; |
|---|
| 750 | 754 | * [khz] -> [100Hz] */ |
|---|
| 751 | 755 | azalia_clock_info->audio_dto_module = |
|---|
| 752 | | - actual_pixel_clock_in_khz * 10; |
|---|
| 756 | + actual_pixel_clock_100Hz; |
|---|
| 753 | 757 | } |
|---|
| 754 | 758 | |
|---|
| 755 | 759 | static void get_azalia_clock_info_dp( |
|---|
| 756 | | - uint32_t requested_pixel_clock_in_khz, |
|---|
| 760 | + uint32_t requested_pixel_clock_100Hz, |
|---|
| 757 | 761 | const struct audio_pll_info *pll_info, |
|---|
| 758 | 762 | struct azalia_clock_info *azalia_clock_info) |
|---|
| 759 | 763 | { |
|---|
| .. | .. |
|---|
| 782 | 786 | |
|---|
| 783 | 787 | struct azalia_clock_info clock_info = { 0 }; |
|---|
| 784 | 788 | |
|---|
| 785 | | - if (dc_is_hdmi_signal(signal)) { |
|---|
| 789 | + if (dc_is_hdmi_tmds_signal(signal)) { |
|---|
| 786 | 790 | uint32_t src_sel; |
|---|
| 787 | 791 | |
|---|
| 788 | 792 | /*DTO0 Programming goal: |
|---|
| .. | .. |
|---|
| 792 | 796 | |
|---|
| 793 | 797 | /* calculate DTO settings */ |
|---|
| 794 | 798 | get_azalia_clock_info_hdmi( |
|---|
| 795 | | - crtc_info->requested_pixel_clock, |
|---|
| 796 | | - crtc_info->calculated_pixel_clock, |
|---|
| 799 | + crtc_info->requested_pixel_clock_100Hz, |
|---|
| 800 | + crtc_info->calculated_pixel_clock_100Hz, |
|---|
| 797 | 801 | &clock_info); |
|---|
| 798 | 802 | |
|---|
| 799 | | - DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock = %d"\ |
|---|
| 800 | | - "calculated_pixel_clock =%d\n"\ |
|---|
| 803 | + DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\ |
|---|
| 804 | + "calculated_pixel_clock_100Hz =%d\n"\ |
|---|
| 801 | 805 | "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\ |
|---|
| 802 | | - crtc_info->requested_pixel_clock,\ |
|---|
| 803 | | - crtc_info->calculated_pixel_clock,\ |
|---|
| 806 | + crtc_info->requested_pixel_clock_100Hz,\ |
|---|
| 807 | + crtc_info->calculated_pixel_clock_100Hz,\ |
|---|
| 804 | 808 | clock_info.audio_dto_module,\ |
|---|
| 805 | 809 | clock_info.audio_dto_phase); |
|---|
| 806 | 810 | |
|---|
| .. | .. |
|---|
| 833 | 837 | |
|---|
| 834 | 838 | calculate DTO settings */ |
|---|
| 835 | 839 | get_azalia_clock_info_dp( |
|---|
| 836 | | - crtc_info->requested_pixel_clock, |
|---|
| 840 | + crtc_info->requested_pixel_clock_100Hz, |
|---|
| 837 | 841 | pll_info, |
|---|
| 838 | 842 | &clock_info); |
|---|
| 839 | 843 | |
|---|
| .. | .. |
|---|
| 843 | 847 | REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, |
|---|
| 844 | 848 | DCCG_AUDIO_DTO_SEL, 1); |
|---|
| 845 | 849 | |
|---|
| 846 | | - REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, |
|---|
| 847 | | - DCCG_AUDIO_DTO_SEL, 1); |
|---|
| 848 | 850 | /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1) |
|---|
| 849 | 851 | * Select 512fs for DP TODO: web register definition |
|---|
| 850 | 852 | * does not match register header file |
|---|
| .. | .. |
|---|
| 864 | 866 | |
|---|
| 865 | 867 | } |
|---|
| 866 | 868 | } |
|---|
| 869 | + |
|---|
| 870 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 871 | +void dce60_aud_wall_dto_setup( |
|---|
| 872 | + struct audio *audio, |
|---|
| 873 | + enum signal_type signal, |
|---|
| 874 | + const struct audio_crtc_info *crtc_info, |
|---|
| 875 | + const struct audio_pll_info *pll_info) |
|---|
| 876 | +{ |
|---|
| 877 | + struct dce_audio *aud = DCE_AUD(audio); |
|---|
| 878 | + |
|---|
| 879 | + struct azalia_clock_info clock_info = { 0 }; |
|---|
| 880 | + |
|---|
| 881 | + if (dc_is_hdmi_signal(signal)) { |
|---|
| 882 | + uint32_t src_sel; |
|---|
| 883 | + |
|---|
| 884 | + /*DTO0 Programming goal: |
|---|
| 885 | + -generate 24MHz, 128*Fs from 24MHz |
|---|
| 886 | + -use DTO0 when an active HDMI port is connected |
|---|
| 887 | + (optionally a DP is connected) */ |
|---|
| 888 | + |
|---|
| 889 | + /* calculate DTO settings */ |
|---|
| 890 | + get_azalia_clock_info_hdmi( |
|---|
| 891 | + crtc_info->requested_pixel_clock_100Hz, |
|---|
| 892 | + crtc_info->calculated_pixel_clock_100Hz, |
|---|
| 893 | + &clock_info); |
|---|
| 894 | + |
|---|
| 895 | + DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock_100Hz = %d"\ |
|---|
| 896 | + "calculated_pixel_clock_100Hz =%d\n"\ |
|---|
| 897 | + "audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\ |
|---|
| 898 | + crtc_info->requested_pixel_clock_100Hz,\ |
|---|
| 899 | + crtc_info->calculated_pixel_clock_100Hz,\ |
|---|
| 900 | + clock_info.audio_dto_module,\ |
|---|
| 901 | + clock_info.audio_dto_phase); |
|---|
| 902 | + |
|---|
| 903 | + /* On TN/SI, Program DTO source select and DTO select before |
|---|
| 904 | + programming DTO modulo and DTO phase. These bits must be |
|---|
| 905 | + programmed first, otherwise there will be no HDMI audio at boot |
|---|
| 906 | + up. This is a HW sequence change (different from old ASICs). |
|---|
| 907 | + Caution when changing this programming sequence. |
|---|
| 908 | + |
|---|
| 909 | + HDMI enabled, using DTO0 |
|---|
| 910 | + program master CRTC for DTO0 */ |
|---|
| 911 | + src_sel = pll_info->dto_source - DTO_SOURCE_ID0; |
|---|
| 912 | + REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE, |
|---|
| 913 | + DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel, |
|---|
| 914 | + DCCG_AUDIO_DTO_SEL, 0); |
|---|
| 915 | + |
|---|
| 916 | + /* module */ |
|---|
| 917 | + REG_UPDATE(DCCG_AUDIO_DTO0_MODULE, |
|---|
| 918 | + DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module); |
|---|
| 919 | + |
|---|
| 920 | + /* phase */ |
|---|
| 921 | + REG_UPDATE(DCCG_AUDIO_DTO0_PHASE, |
|---|
| 922 | + DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase); |
|---|
| 923 | + } else { |
|---|
| 924 | + /*DTO1 Programming goal: |
|---|
| 925 | + -generate 24MHz, 128*Fs from 24MHz (DCE6 does not support 512*Fs) |
|---|
| 926 | + -default is to used DTO1, and switch to DTO0 when an audio |
|---|
| 927 | + master HDMI port is connected |
|---|
| 928 | + -use as default for DP |
|---|
| 929 | + |
|---|
| 930 | + calculate DTO settings */ |
|---|
| 931 | + get_azalia_clock_info_dp( |
|---|
| 932 | + crtc_info->requested_pixel_clock_100Hz, |
|---|
| 933 | + pll_info, |
|---|
| 934 | + &clock_info); |
|---|
| 935 | + |
|---|
| 936 | + /* Program DTO select before programming DTO modulo and DTO |
|---|
| 937 | + phase. default to use DTO1 */ |
|---|
| 938 | + |
|---|
| 939 | + REG_UPDATE(DCCG_AUDIO_DTO_SOURCE, |
|---|
| 940 | + DCCG_AUDIO_DTO_SEL, 1); |
|---|
| 941 | + |
|---|
| 942 | + /* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1) |
|---|
| 943 | + * Cannot select 512fs for DP |
|---|
| 944 | + * |
|---|
| 945 | + * DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask |
|---|
| 946 | + */ |
|---|
| 947 | + |
|---|
| 948 | + /* module */ |
|---|
| 949 | + REG_UPDATE(DCCG_AUDIO_DTO1_MODULE, |
|---|
| 950 | + DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module); |
|---|
| 951 | + |
|---|
| 952 | + /* phase */ |
|---|
| 953 | + REG_UPDATE(DCCG_AUDIO_DTO1_PHASE, |
|---|
| 954 | + DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase); |
|---|
| 955 | + |
|---|
| 956 | + /* DCE6 has no DCCG_AUDIO_DTO2_USE_512FBR_DTO mask in DCCG_AUDIO_DTO_SOURCE reg */ |
|---|
| 957 | + |
|---|
| 958 | + } |
|---|
| 959 | +} |
|---|
| 960 | +#endif |
|---|
| 867 | 961 | |
|---|
| 868 | 962 | static bool dce_aud_endpoint_valid(struct audio *audio) |
|---|
| 869 | 963 | { |
|---|
| .. | .. |
|---|
| 924 | 1018 | .az_configure = dce_aud_az_configure, |
|---|
| 925 | 1019 | .destroy = dce_aud_destroy, |
|---|
| 926 | 1020 | }; |
|---|
| 1021 | + |
|---|
| 1022 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 1023 | +static const struct audio_funcs dce60_funcs = { |
|---|
| 1024 | + .endpoint_valid = dce_aud_endpoint_valid, |
|---|
| 1025 | + .hw_init = dce_aud_hw_init, |
|---|
| 1026 | + .wall_dto_setup = dce60_aud_wall_dto_setup, |
|---|
| 1027 | + .az_enable = dce_aud_az_enable, |
|---|
| 1028 | + .az_disable = dce_aud_az_disable, |
|---|
| 1029 | + .az_configure = dce_aud_az_configure, |
|---|
| 1030 | + .destroy = dce_aud_destroy, |
|---|
| 1031 | +}; |
|---|
| 1032 | +#endif |
|---|
| 1033 | + |
|---|
| 927 | 1034 | void dce_aud_destroy(struct audio **audio) |
|---|
| 928 | 1035 | { |
|---|
| 929 | 1036 | struct dce_audio *aud = DCE_AUD(*audio); |
|---|
| .. | .. |
|---|
| 937 | 1044 | unsigned int inst, |
|---|
| 938 | 1045 | const struct dce_audio_registers *reg, |
|---|
| 939 | 1046 | const struct dce_audio_shift *shifts, |
|---|
| 940 | | - const struct dce_aduio_mask *masks |
|---|
| 1047 | + const struct dce_audio_mask *masks |
|---|
| 941 | 1048 | ) |
|---|
| 942 | 1049 | { |
|---|
| 943 | 1050 | struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 957 | 1064 | return &audio->base; |
|---|
| 958 | 1065 | } |
|---|
| 959 | 1066 | |
|---|
| 1067 | +#if defined(CONFIG_DRM_AMD_DC_SI) |
|---|
| 1068 | +struct audio *dce60_audio_create( |
|---|
| 1069 | + struct dc_context *ctx, |
|---|
| 1070 | + unsigned int inst, |
|---|
| 1071 | + const struct dce_audio_registers *reg, |
|---|
| 1072 | + const struct dce_audio_shift *shifts, |
|---|
| 1073 | + const struct dce_audio_mask *masks |
|---|
| 1074 | + ) |
|---|
| 1075 | +{ |
|---|
| 1076 | + struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL); |
|---|
| 1077 | + |
|---|
| 1078 | + if (audio == NULL) { |
|---|
| 1079 | + ASSERT_CRITICAL(audio); |
|---|
| 1080 | + return NULL; |
|---|
| 1081 | + } |
|---|
| 1082 | + |
|---|
| 1083 | + audio->base.ctx = ctx; |
|---|
| 1084 | + audio->base.inst = inst; |
|---|
| 1085 | + audio->base.funcs = &dce60_funcs; |
|---|
| 1086 | + |
|---|
| 1087 | + audio->regs = reg; |
|---|
| 1088 | + audio->shifts = shifts; |
|---|
| 1089 | + audio->masks = masks; |
|---|
| 1090 | + return &audio->base; |
|---|
| 1091 | +} |
|---|
| 1092 | +#endif |
|---|