1 /* 2 * Copyright 2017 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 #ifndef DM_PP_SMU_IF__H 27 #define DM_PP_SMU_IF__H 28 29 /* 30 * interface to PPLIB/SMU to setup clocks and pstate requirements on SoC 31 */ 32 33 typedef bool BOOLEAN; 34 35 enum pp_smu_ver { 36 /* 37 * PP_SMU_INTERFACE_X should be interpreted as the interface defined 38 * starting from X, where X is some family of ASICs. This is as 39 * opposed to interfaces used only for X. There will be some degree 40 * of interface sharing between families of ASIcs. 41 */ 42 PP_SMU_UNSUPPORTED, 43 PP_SMU_VER_RV, 44 #ifndef CONFIG_TRIM_DRM_AMD_DC_DCN2_0 45 PP_SMU_VER_NV, 46 #endif 47 48 PP_SMU_VER_MAX 49 }; 50 51 struct pp_smu { 52 enum pp_smu_ver ver; 53 const void *pp; 54 55 /* 56 * interim extra handle for backwards compatibility 57 * as some existing functionality not yet implemented 58 * by ppsmu 59 */ 60 const void *dm; 61 }; 62 63 enum pp_smu_status { 64 PP_SMU_RESULT_UNDEFINED = 0, 65 PP_SMU_RESULT_OK = 1, 66 PP_SMU_RESULT_FAIL, 67 PP_SMU_RESULT_UNSUPPORTED 68 }; 69 70 #define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN 0x0 71 #define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX 0xFFFF 72 73 enum wm_type { 74 WM_TYPE_PSTATE_CHG = 0, 75 WM_TYPE_RETRAINING = 1, 76 }; 77 78 /* This structure is a copy of WatermarkRowGeneric_t defined by smuxx_driver_if.h*/ 79 struct pp_smu_wm_set_range { 80 uint16_t min_fill_clk_mhz; 81 uint16_t max_fill_clk_mhz; 82 uint16_t min_drain_clk_mhz; 83 uint16_t max_drain_clk_mhz; 84 85 uint8_t wm_inst; 86 uint8_t wm_type; 87 }; 88 89 #define MAX_WATERMARK_SETS 4 90 91 struct pp_smu_wm_range_sets { 92 unsigned int num_reader_wm_sets; 93 struct pp_smu_wm_set_range reader_wm_sets[MAX_WATERMARK_SETS]; 94 95 unsigned int num_writer_wm_sets; 96 struct pp_smu_wm_set_range writer_wm_sets[MAX_WATERMARK_SETS]; 97 }; 98 99 struct pp_smu_funcs_rv { 100 struct pp_smu pp_smu; 101 102 /* PPSMC_MSG_SetDisplayCount 103 * 0 triggers S0i2 optimization 104 */ 105 106 void (*set_display_count)(struct pp_smu *pp, int count); 107 108 /* reader and writer WM's are sent together as part of one table*/ 109 /* 110 * PPSMC_MSG_SetDriverDramAddrHigh 111 * PPSMC_MSG_SetDriverDramAddrLow 112 * PPSMC_MSG_TransferTableDram2Smu 113 * 114 * */ 115 void (*set_wm_ranges)(struct pp_smu *pp, 116 struct pp_smu_wm_range_sets *ranges); 117 118 /* PPSMC_MSG_SetHardMinDcfclkByFreq 119 * fixed clock at requested freq, either from FCH bypass or DFS 120 */ 121 void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int mhz); 122 123 /* PPSMC_MSG_SetMinDeepSleepDcfclk 124 * when DF is in cstate, dcf clock is further divided down 125 * to just above given frequency 126 */ 127 void (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int mhz); 128 129 /* PPSMC_MSG_SetHardMinFclkByFreq 130 * FCLK will vary with DPM, but never below requested hard min 131 */ 132 void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int mhz); 133 134 /* PPSMC_MSG_SetHardMinSocclkByFreq 135 * Needed for DWB support 136 */ 137 void (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int mhz); 138 139 /* PME w/a */ 140 void (*set_pme_wa_enable)(struct pp_smu *pp); 141 }; 142 143 #ifndef CONFIG_TRIM_DRM_AMD_DC_DCN2_0 144 /* Used by pp_smu_funcs_nv.set_voltage_by_freq 145 * 146 */ 147 enum pp_smu_nv_clock_id { 148 PP_SMU_NV_DISPCLK, 149 PP_SMU_NV_PHYCLK, 150 PP_SMU_NV_PIXELCLK 151 }; 152 153 /* 154 * Used by pp_smu_funcs_nv.get_maximum_sustainable_clocks 155 */ 156 struct pp_smu_nv_clock_table { 157 // voltage managed SMU, freq set by driver 158 unsigned int displayClockInKhz; 159 unsigned int dppClockInKhz; 160 unsigned int phyClockInKhz; 161 unsigned int pixelClockInKhz; 162 unsigned int dscClockInKhz; 163 164 // freq/voltage managed by SMU 165 unsigned int fabricClockInKhz; 166 unsigned int socClockInKhz; 167 unsigned int dcfClockInKhz; 168 unsigned int uClockInKhz; 169 }; 170 171 struct pp_smu_funcs_nv { 172 struct pp_smu pp_smu; 173 174 /* PPSMC_MSG_SetDisplayCount 175 * 0 triggers S0i2 optimization 176 */ 177 enum pp_smu_status (*set_display_count)(struct pp_smu *pp, int count); 178 179 /* PPSMC_MSG_SetHardMinDcfclkByFreq 180 * fixed clock at requested freq, either from FCH bypass or DFS 181 */ 182 enum pp_smu_status (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int Mhz); 183 184 /* PPSMC_MSG_SetMinDeepSleepDcfclk 185 * when DF is in cstate, dcf clock is further divided down 186 * to just above given frequency 187 */ 188 enum pp_smu_status (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int Mhz); 189 190 /* PPSMC_MSG_SetHardMinUclkByFreq 191 * UCLK will vary with DPM, but never below requested hard min 192 */ 193 enum pp_smu_status (*set_hard_min_uclk_by_freq)(struct pp_smu *pp, int Mhz); 194 195 /* PPSMC_MSG_SetHardMinSocclkByFreq 196 * Needed for DWB support 197 */ 198 enum pp_smu_status (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int Mhz); 199 200 /* PME w/a */ 201 enum pp_smu_status (*set_pme_wa_enable)(struct pp_smu *pp); 202 203 /* PPSMC_MSG_SetHardMinByFreq 204 * Needed to set ASIC voltages for clocks programmed by DAL 205 */ 206 enum pp_smu_status (*set_voltage_by_freq)(struct pp_smu *pp, 207 enum pp_smu_nv_clock_id clock_id, int Mhz); 208 209 /* reader and writer WM's are sent together as part of one table*/ 210 /* 211 * PPSMC_MSG_SetDriverDramAddrHigh 212 * PPSMC_MSG_SetDriverDramAddrLow 213 * PPSMC_MSG_TransferTableDram2Smu 214 * 215 * on DCN20: 216 * reader fill clk = uclk 217 * reader drain clk = dcfclk 218 * writer fill clk = socclk 219 * writer drain clk = uclk 220 * */ 221 enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp, 222 struct pp_smu_wm_range_sets *ranges); 223 224 /* Not a single SMU message. This call should return maximum sustainable limit for all 225 * clocks that DC depends on. These will be used as basis for mode enumeration. 226 */ 227 enum pp_smu_status (*get_maximum_sustainable_clocks)(struct pp_smu *pp, 228 struct pp_smu_nv_clock_table *max_clocks); 229 230 /* This call should return the discrete uclk DPM states available 231 */ 232 enum pp_smu_status (*get_uclk_dpm_states)(struct pp_smu *pp, 233 unsigned int *clock_values_in_khz, unsigned int *num_states); 234 235 /* Not a single SMU message. This call informs PPLIB that display will not be able 236 * to perform pstate handshaking in its current state. Typically this handshake 237 * is used to perform uCLK switching, so disabling pstate disables uCLK switching. 238 * 239 * Note that when setting handshake to unsupported, the call is pre-emptive. That means 240 * DC will make the call BEFORE setting up the display state which would cause pstate 241 * request to go un-acked. Only when the call completes should such a state be applied to 242 * DC hardware 243 */ 244 enum pp_smu_status (*set_pstate_handshake_support)(struct pp_smu *pp, 245 BOOLEAN pstate_handshake_supported); 246 }; 247 #endif 248 249 struct pp_smu_funcs { 250 struct pp_smu ctx; 251 union { 252 struct pp_smu_funcs_rv rv_funcs; 253 #ifndef CONFIG_TRIM_DRM_AMD_DC_DCN2_0 254 struct pp_smu_funcs_nv nv_funcs; 255 #endif 256 257 }; 258 }; 259 260 #endif /* DM_PP_SMU_IF__H */ 261