.. | .. |
---|
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 |
---|