322 lines · c
1/*2 * Copyright 2017 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#ifndef DM_PP_SMU_IF__H27#define DM_PP_SMU_IF__H28 29/*30 * interface to PPLIB/SMU to setup clocks and pstate requirements on SoC31 */32 33enum pp_smu_ver {34 /*35 * PP_SMU_INTERFACE_X should be interpreted as the interface defined36 * starting from X, where X is some family of ASICs. This is as37 * opposed to interfaces used only for X. There will be some degree38 * of interface sharing between families of ASIcs.39 */40 PP_SMU_UNSUPPORTED,41 PP_SMU_VER_RV,42 PP_SMU_VER_NV,43 44 PP_SMU_VER_RN,45 PP_SMU_VER_VG,46 PP_SMU_VER_MAX47};48 49struct pp_smu {50 enum pp_smu_ver ver;51 const void *pp;52 53 /*54 * interim extra handle for backwards compatibility55 * as some existing functionality not yet implemented56 * by ppsmu57 */58 const void *dm;59};60 61enum pp_smu_status {62 PP_SMU_RESULT_UNDEFINED = 0,63 PP_SMU_RESULT_OK = 1,64 PP_SMU_RESULT_FAIL,65 PP_SMU_RESULT_UNSUPPORTED66};67 68#define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN 0x069#define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX 0xFFFF70 71enum wm_type {72 WM_TYPE_PSTATE_CHG = 0,73 WM_TYPE_RETRAINING = 1,74};75 76/* This structure is a copy of WatermarkRowGeneric_t defined by smuxx_driver_if.h*/77struct pp_smu_wm_set_range {78 uint16_t min_fill_clk_mhz;79 uint16_t max_fill_clk_mhz;80 uint16_t min_drain_clk_mhz;81 uint16_t max_drain_clk_mhz;82 83 uint8_t wm_inst;84 uint8_t wm_type;85};86 87#define MAX_WATERMARK_SETS 488 89struct pp_smu_wm_range_sets {90 unsigned int num_reader_wm_sets;91 struct pp_smu_wm_set_range reader_wm_sets[MAX_WATERMARK_SETS];92 93 unsigned int num_writer_wm_sets;94 struct pp_smu_wm_set_range writer_wm_sets[MAX_WATERMARK_SETS];95};96 97struct pp_smu_funcs_rv {98 struct pp_smu pp_smu;99 100 /* PPSMC_MSG_SetDisplayCount101 * 0 triggers S0i2 optimization102 */103 104 void (*set_display_count)(struct pp_smu *pp, int count);105 106 /* reader and writer WM's are sent together as part of one table*/107 /*108 * PPSMC_MSG_SetDriverDramAddrHigh109 * PPSMC_MSG_SetDriverDramAddrLow110 * PPSMC_MSG_TransferTableDram2Smu111 *112 * */113 void (*set_wm_ranges)(struct pp_smu *pp,114 struct pp_smu_wm_range_sets *ranges);115 116 /* PPSMC_MSG_SetHardMinDcfclkByFreq117 * fixed clock at requested freq, either from FCH bypass or DFS118 */119 void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int mhz);120 121 /* PPSMC_MSG_SetMinDeepSleepDcfclk122 * when DF is in cstate, dcf clock is further divided down123 * to just above given frequency124 */125 void (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int mhz);126 127 /* PPSMC_MSG_SetHardMinFclkByFreq128 * FCLK will vary with DPM, but never below requested hard min129 */130 void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int mhz);131 132 /* PPSMC_MSG_SetHardMinSocclkByFreq133 * Needed for DWB support134 */135 void (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int mhz);136 137 /* PME w/a */138 void (*set_pme_wa_enable)(struct pp_smu *pp);139};140 141/* Used by pp_smu_funcs_nv.set_voltage_by_freq142 *143 */144enum pp_smu_nv_clock_id {145 PP_SMU_NV_DISPCLK,146 PP_SMU_NV_PHYCLK,147 PP_SMU_NV_PIXELCLK148};149 150/*151 * Used by pp_smu_funcs_nv.get_maximum_sustainable_clocks152 */153struct pp_smu_nv_clock_table {154 // voltage managed SMU, freq set by driver155 unsigned int displayClockInKhz;156 unsigned int dppClockInKhz;157 unsigned int phyClockInKhz;158 unsigned int pixelClockInKhz;159 unsigned int dscClockInKhz;160 161 // freq/voltage managed by SMU162 unsigned int fabricClockInKhz;163 unsigned int socClockInKhz;164 unsigned int dcfClockInKhz;165 unsigned int uClockInKhz;166};167 168struct pp_smu_funcs_nv {169 struct pp_smu pp_smu;170 171 /* PPSMC_MSG_SetDisplayCount172 * 0 triggers S0i2 optimization173 */174 enum pp_smu_status (*set_display_count)(struct pp_smu *pp, int count);175 176 /* PPSMC_MSG_SetHardMinDcfclkByFreq177 * fixed clock at requested freq, either from FCH bypass or DFS178 */179 enum pp_smu_status (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int Mhz);180 181 /* PPSMC_MSG_SetMinDeepSleepDcfclk182 * when DF is in cstate, dcf clock is further divided down183 * to just above given frequency184 */185 enum pp_smu_status (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int Mhz);186 187 /* PPSMC_MSG_SetHardMinUclkByFreq188 * UCLK will vary with DPM, but never below requested hard min189 */190 enum pp_smu_status (*set_hard_min_uclk_by_freq)(struct pp_smu *pp, int Mhz);191 192 /* PPSMC_MSG_SetHardMinSocclkByFreq193 * Needed for DWB support194 */195 enum pp_smu_status (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int Mhz);196 197 /* PME w/a */198 enum pp_smu_status (*set_pme_wa_enable)(struct pp_smu *pp);199 200 /* PPSMC_MSG_SetHardMinByFreq201 * Needed to set ASIC voltages for clocks programmed by DAL202 */203 enum pp_smu_status (*set_voltage_by_freq)(struct pp_smu *pp,204 enum pp_smu_nv_clock_id clock_id, int Mhz);205 206 /* reader and writer WM's are sent together as part of one table*/207 /*208 * PPSMC_MSG_SetDriverDramAddrHigh209 * PPSMC_MSG_SetDriverDramAddrLow210 * PPSMC_MSG_TransferTableDram2Smu211 *212 * on DCN20:213 * reader fill clk = uclk214 * reader drain clk = dcfclk215 * writer fill clk = socclk216 * writer drain clk = uclk217 * */218 enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,219 struct pp_smu_wm_range_sets *ranges);220 221 /* Not a single SMU message. This call should return maximum sustainable limit for all222 * clocks that DC depends on. These will be used as basis for mode enumeration.223 */224 enum pp_smu_status (*get_maximum_sustainable_clocks)(struct pp_smu *pp,225 struct pp_smu_nv_clock_table *max_clocks);226 227 /* This call should return the discrete uclk DPM states available228 */229 enum pp_smu_status (*get_uclk_dpm_states)(struct pp_smu *pp,230 unsigned int *clock_values_in_khz, unsigned int *num_states);231 232 /* Not a single SMU message. This call informs PPLIB that display will not be able233 * to perform pstate handshaking in its current state. Typically this handshake234 * is used to perform uCLK switching, so disabling pstate disables uCLK switching.235 *236 * Note that when setting handshake to unsupported, the call is pre-emptive. That means237 * DC will make the call BEFORE setting up the display state which would cause pstate238 * request to go un-acked. Only when the call completes should such a state be applied to239 * DC hardware240 */241 enum pp_smu_status (*set_pstate_handshake_support)(struct pp_smu *pp,242 bool pstate_handshake_supported);243};244 245#define PP_SMU_NUM_SOCCLK_DPM_LEVELS 8246#define PP_SMU_NUM_DCFCLK_DPM_LEVELS 8247#define PP_SMU_NUM_FCLK_DPM_LEVELS 4248#define PP_SMU_NUM_MEMCLK_DPM_LEVELS 4249#define PP_SMU_NUM_DCLK_DPM_LEVELS 8250#define PP_SMU_NUM_VCLK_DPM_LEVELS 8251#define PP_SMU_NUM_VPECLK_DPM_LEVELS 8252 253struct dpm_clock {254 uint32_t Freq; // In MHz255 uint32_t Vol; // Millivolts with 2 fractional bits256};257 258 259/* this is a copy of the structure defined in smuxx_driver_if.h*/260struct dpm_clocks {261 struct dpm_clock DcfClocks[PP_SMU_NUM_DCFCLK_DPM_LEVELS];262 struct dpm_clock SocClocks[PP_SMU_NUM_SOCCLK_DPM_LEVELS];263 struct dpm_clock FClocks[PP_SMU_NUM_FCLK_DPM_LEVELS];264 struct dpm_clock MemClocks[PP_SMU_NUM_MEMCLK_DPM_LEVELS];265 struct dpm_clock VClocks[PP_SMU_NUM_VCLK_DPM_LEVELS];266 struct dpm_clock DClocks[PP_SMU_NUM_DCLK_DPM_LEVELS];267 struct dpm_clock VPEClocks[PP_SMU_NUM_VPECLK_DPM_LEVELS];268};269 270 271struct pp_smu_funcs_rn {272 struct pp_smu pp_smu;273 274 /*275 * reader and writer WM's are sent together as part of one table276 *277 * PPSMC_MSG_SetDriverDramAddrHigh278 * PPSMC_MSG_SetDriverDramAddrLow279 * PPSMC_MSG_TransferTableDram2Smu280 *281 */282 enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,283 struct pp_smu_wm_range_sets *ranges);284 285 enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp,286 struct dpm_clocks *clock_table);287};288 289struct pp_smu_funcs_vgh {290 struct pp_smu pp_smu;291 292 /*293 * reader and writer WM's are sent together as part of one table294 *295 * PPSMC_MSG_SetDriverDramAddrHigh296 * PPSMC_MSG_SetDriverDramAddrLow297 * PPSMC_MSG_TransferTableDram2Smu298 *299 */300 // TODO: Check whether this is moved to DAL, and remove as needed301 enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,302 struct pp_smu_wm_range_sets *ranges);303 304 // TODO: Check whether this is moved to DAL, and remove as needed305 enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp,306 struct dpm_clocks *clock_table);307 308 enum pp_smu_status (*notify_smu_timeout) (struct pp_smu *pp);309};310 311struct pp_smu_funcs {312 struct pp_smu ctx;313 union {314 struct pp_smu_funcs_rv rv_funcs;315 struct pp_smu_funcs_nv nv_funcs;316 struct pp_smu_funcs_rn rn_funcs;317 struct pp_smu_funcs_vgh vgh_funcs;318 };319};320 321#endif /* DM_PP_SMU_IF__H */322