Home | History | Annotate | Line # | Download | only in dc
      1 /*	$NetBSD: dm_pp_smu.h,v 1.3 2021/12/19 10:59:01 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2017 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #ifndef DM_PP_SMU_IF__H
     29 #define DM_PP_SMU_IF__H
     30 
     31 /*
     32  * interface to PPLIB/SMU to setup clocks and pstate requirements on SoC
     33  */
     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 	PP_SMU_VER_NV,
     45 	PP_SMU_VER_RN,
     46 
     47 	PP_SMU_VER_MAX
     48 };
     49 
     50 struct pp_smu {
     51 	enum pp_smu_ver ver;
     52 	const void *pp;
     53 
     54 	/*
     55 	 * interim extra handle for backwards compatibility
     56 	 * as some existing functionality not yet implemented
     57 	 * by ppsmu
     58 	 */
     59 	const void *dm;
     60 };
     61 
     62 enum pp_smu_status {
     63 	PP_SMU_RESULT_UNDEFINED = 0,
     64 	PP_SMU_RESULT_OK = 1,
     65 	PP_SMU_RESULT_FAIL,
     66 	PP_SMU_RESULT_UNSUPPORTED
     67 };
     68 
     69 #define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN 0x0
     70 #define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX 0xFFFF
     71 
     72 enum wm_type {
     73 	WM_TYPE_PSTATE_CHG = 0,
     74 	WM_TYPE_RETRAINING = 1,
     75 };
     76 
     77 /* This structure is a copy of WatermarkRowGeneric_t defined by smuxx_driver_if.h*/
     78 struct pp_smu_wm_set_range {
     79 	uint16_t min_fill_clk_mhz;
     80 	uint16_t max_fill_clk_mhz;
     81 	uint16_t min_drain_clk_mhz;
     82 	uint16_t max_drain_clk_mhz;
     83 
     84 	uint8_t wm_inst;
     85 	uint8_t wm_type;
     86 };
     87 
     88 #define MAX_WATERMARK_SETS 4
     89 
     90 struct pp_smu_wm_range_sets {
     91 	unsigned int num_reader_wm_sets;
     92 	struct pp_smu_wm_set_range reader_wm_sets[MAX_WATERMARK_SETS];
     93 
     94 	unsigned int num_writer_wm_sets;
     95 	struct pp_smu_wm_set_range writer_wm_sets[MAX_WATERMARK_SETS];
     96 };
     97 
     98 struct pp_smu_funcs_rv {
     99 	struct pp_smu pp_smu;
    100 
    101 	/* PPSMC_MSG_SetDisplayCount
    102 	 * 0 triggers S0i2 optimization
    103 	 */
    104 
    105 	void (*set_display_count)(struct pp_smu *pp, int count);
    106 
    107 	/* reader and writer WM's are sent together as part of one table*/
    108 	/*
    109 	 * PPSMC_MSG_SetDriverDramAddrHigh
    110 	 * PPSMC_MSG_SetDriverDramAddrLow
    111 	 * PPSMC_MSG_TransferTableDram2Smu
    112 	 *
    113 	 * */
    114 	void (*set_wm_ranges)(struct pp_smu *pp,
    115 			struct pp_smu_wm_range_sets *ranges);
    116 
    117 	/* PPSMC_MSG_SetHardMinDcfclkByFreq
    118 	 * fixed clock at requested freq, either from FCH bypass or DFS
    119 	 */
    120 	void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int mhz);
    121 
    122 	/* PPSMC_MSG_SetMinDeepSleepDcfclk
    123 	 * when DF is in cstate, dcf clock is further divided down
    124 	 * to just above given frequency
    125 	 */
    126 	void (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int mhz);
    127 
    128 	/* PPSMC_MSG_SetHardMinFclkByFreq
    129 	 * FCLK will vary with DPM, but never below requested hard min
    130 	 */
    131 	void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int mhz);
    132 
    133 	/* PPSMC_MSG_SetHardMinSocclkByFreq
    134 	 * Needed for DWB support
    135 	 */
    136 	void (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int mhz);
    137 
    138 	/* PME w/a */
    139 	void (*set_pme_wa_enable)(struct pp_smu *pp);
    140 };
    141 
    142 /* Used by pp_smu_funcs_nv.set_voltage_by_freq
    143  *
    144  */
    145 enum pp_smu_nv_clock_id {
    146 	PP_SMU_NV_DISPCLK,
    147 	PP_SMU_NV_PHYCLK,
    148 	PP_SMU_NV_PIXELCLK
    149 };
    150 
    151 /*
    152  * Used by pp_smu_funcs_nv.get_maximum_sustainable_clocks
    153  */
    154 struct pp_smu_nv_clock_table {
    155 	// voltage managed SMU, freq set by driver
    156 	unsigned int    displayClockInKhz;
    157 	unsigned int	dppClockInKhz;
    158 	unsigned int    phyClockInKhz;
    159 	unsigned int    pixelClockInKhz;
    160 	unsigned int	dscClockInKhz;
    161 
    162 	// freq/voltage managed by SMU
    163 	unsigned int	fabricClockInKhz;
    164 	unsigned int	socClockInKhz;
    165 	unsigned int    dcfClockInKhz;
    166 	unsigned int    uClockInKhz;
    167 };
    168 
    169 struct pp_smu_funcs_nv {
    170 	struct pp_smu pp_smu;
    171 
    172 	/* PPSMC_MSG_SetDisplayCount
    173 	 * 0 triggers S0i2 optimization
    174 	 */
    175 	enum pp_smu_status (*set_display_count)(struct pp_smu *pp, int count);
    176 
    177 	/* PPSMC_MSG_SetHardMinDcfclkByFreq
    178 	 * fixed clock at requested freq, either from FCH bypass or DFS
    179 	 */
    180 	enum pp_smu_status (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int Mhz);
    181 
    182 	/* PPSMC_MSG_SetMinDeepSleepDcfclk
    183 	 * when DF is in cstate, dcf clock is further divided down
    184 	 * to just above given frequency
    185 	 */
    186 	enum pp_smu_status (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int Mhz);
    187 
    188 	/* PPSMC_MSG_SetHardMinUclkByFreq
    189 	 * UCLK will vary with DPM, but never below requested hard min
    190 	 */
    191 	enum pp_smu_status (*set_hard_min_uclk_by_freq)(struct pp_smu *pp, int Mhz);
    192 
    193 	/* PPSMC_MSG_SetHardMinSocclkByFreq
    194 	 * Needed for DWB support
    195 	 */
    196 	enum pp_smu_status (*set_hard_min_socclk_by_freq)(struct pp_smu *pp, int Mhz);
    197 
    198 	/* PME w/a */
    199 	enum pp_smu_status (*set_pme_wa_enable)(struct pp_smu *pp);
    200 
    201 	/* PPSMC_MSG_SetHardMinByFreq
    202 	 * Needed to set ASIC voltages for clocks programmed by DAL
    203 	 */
    204 	enum pp_smu_status (*set_voltage_by_freq)(struct pp_smu *pp,
    205 			enum pp_smu_nv_clock_id clock_id, int Mhz);
    206 
    207 	/* reader and writer WM's are sent together as part of one table*/
    208 	/*
    209 	 * PPSMC_MSG_SetDriverDramAddrHigh
    210 	 * PPSMC_MSG_SetDriverDramAddrLow
    211 	 * PPSMC_MSG_TransferTableDram2Smu
    212 	 *
    213 	 * on DCN20:
    214 	 * 	reader fill clk = uclk
    215 	 * 	reader drain clk = dcfclk
    216 	 * 	writer fill clk = socclk
    217 	 * 	writer drain clk = uclk
    218 	 * */
    219 	enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,
    220 			struct pp_smu_wm_range_sets *ranges);
    221 
    222 	/* Not a single SMU message.  This call should return maximum sustainable limit for all
    223 	 * clocks that DC depends on.  These will be used as basis for mode enumeration.
    224 	 */
    225 	enum pp_smu_status (*get_maximum_sustainable_clocks)(struct pp_smu *pp,
    226 			struct pp_smu_nv_clock_table *max_clocks);
    227 
    228 	/* This call should return the discrete uclk DPM states available
    229 	 */
    230 	enum pp_smu_status (*get_uclk_dpm_states)(struct pp_smu *pp,
    231 			unsigned int *clock_values_in_khz, unsigned int *num_states);
    232 
    233 	/* Not a single SMU message.  This call informs PPLIB that display will not be able
    234 	 * to perform pstate handshaking in its current state.  Typically this handshake
    235 	 * is used to perform uCLK switching, so disabling pstate disables uCLK switching.
    236 	 *
    237 	 * Note that when setting handshake to unsupported, the call is pre-emptive.  That means
    238 	 * DC will make the call BEFORE setting up the display state which would cause pstate
    239 	 * request to go un-acked.  Only when the call completes should such a state be applied to
    240 	 * DC hardware
    241 	 */
    242 	enum pp_smu_status (*set_pstate_handshake_support)(struct pp_smu *pp,
    243 			bool pstate_handshake_supported);
    244 };
    245 
    246 #define PP_SMU_NUM_SOCCLK_DPM_LEVELS  8
    247 #define PP_SMU_NUM_DCFCLK_DPM_LEVELS  8
    248 #define PP_SMU_NUM_FCLK_DPM_LEVELS    4
    249 #define PP_SMU_NUM_MEMCLK_DPM_LEVELS  4
    250 
    251 struct dpm_clock {
    252   uint32_t  Freq;    // In MHz
    253   uint32_t  Vol;     // Millivolts with 2 fractional bits
    254 };
    255 
    256 
    257 /* this is a copy of the structure defined in smuxx_driver_if.h*/
    258 struct dpm_clocks {
    259 	struct dpm_clock DcfClocks[PP_SMU_NUM_DCFCLK_DPM_LEVELS];
    260 	struct dpm_clock SocClocks[PP_SMU_NUM_SOCCLK_DPM_LEVELS];
    261 	struct dpm_clock FClocks[PP_SMU_NUM_FCLK_DPM_LEVELS];
    262 	struct dpm_clock MemClocks[PP_SMU_NUM_MEMCLK_DPM_LEVELS];
    263 };
    264 
    265 
    266 struct pp_smu_funcs_rn {
    267 	struct pp_smu pp_smu;
    268 
    269 	/*
    270 	 * reader and writer WM's are sent together as part of one table
    271 	 *
    272 	 * PPSMC_MSG_SetDriverDramAddrHigh
    273 	 * PPSMC_MSG_SetDriverDramAddrLow
    274 	 * PPSMC_MSG_TransferTableDram2Smu
    275 	 *
    276 	 */
    277 	enum pp_smu_status (*set_wm_ranges)(struct pp_smu *pp,
    278 			struct pp_smu_wm_range_sets *ranges);
    279 
    280 	enum pp_smu_status (*get_dpm_clock_table) (struct pp_smu *pp,
    281 			struct dpm_clocks *clock_table);
    282 };
    283 
    284 struct pp_smu_funcs {
    285 	struct pp_smu ctx;
    286 	union {
    287 		struct pp_smu_funcs_rv rv_funcs;
    288 		struct pp_smu_funcs_nv nv_funcs;
    289 		struct pp_smu_funcs_rn rn_funcs;
    290 
    291 	};
    292 };
    293 
    294 #endif /* DM_PP_SMU_IF__H */
    295