Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
 33enum pp_smu_ver {
 34	/*
 35	 * PP_SMU_INTERFACE_X should be interpreted as the interface defined
 36	 * starting from X, where X is some family of ASICs.  This is as
 37	 * opposed to interfaces used only for X.  There will be some degree
 38	 * 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_MAX
 47};
 48
 49struct pp_smu {
 50	enum pp_smu_ver ver;
 51	const void *pp;
 52
 53	/*
 54	 * interim extra handle for backwards compatibility
 55	 * as some existing functionality not yet implemented
 56	 * by ppsmu
 57	 */
 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_UNSUPPORTED
 66};
 67
 68#define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MIN 0x0
 69#define PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_MAX 0xFFFF
 70
 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 4
 88
 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_SetDisplayCount
101	 * 0 triggers S0i2 optimization
102	 */
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_SetDriverDramAddrHigh
109	 * PPSMC_MSG_SetDriverDramAddrLow
110	 * PPSMC_MSG_TransferTableDram2Smu
111	 *
112	 * */
113	void (*set_wm_ranges)(struct pp_smu *pp,
114			struct pp_smu_wm_range_sets *ranges);
115
116	/* PPSMC_MSG_SetHardMinDcfclkByFreq
117	 * fixed clock at requested freq, either from FCH bypass or DFS
118	 */
119	void (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int mhz);
120
121	/* PPSMC_MSG_SetMinDeepSleepDcfclk
122	 * when DF is in cstate, dcf clock is further divided down
123	 * to just above given frequency
124	 */
125	void (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int mhz);
126
127	/* PPSMC_MSG_SetHardMinFclkByFreq
128	 * FCLK will vary with DPM, but never below requested hard min
129	 */
130	void (*set_hard_min_fclk_by_freq)(struct pp_smu *pp, int mhz);
131
132	/* PPSMC_MSG_SetHardMinSocclkByFreq
133	 * Needed for DWB support
134	 */
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_freq
142 *
143 */
144enum pp_smu_nv_clock_id {
145	PP_SMU_NV_DISPCLK,
146	PP_SMU_NV_PHYCLK,
147	PP_SMU_NV_PIXELCLK
148};
149
150/*
151 * Used by pp_smu_funcs_nv.get_maximum_sustainable_clocks
152 */
153struct pp_smu_nv_clock_table {
154	// voltage managed SMU, freq set by driver
155	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 SMU
162	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_SetDisplayCount
172	 * 0 triggers S0i2 optimization
173	 */
174	enum pp_smu_status (*set_display_count)(struct pp_smu *pp, int count);
175
176	/* PPSMC_MSG_SetHardMinDcfclkByFreq
177	 * fixed clock at requested freq, either from FCH bypass or DFS
178	 */
179	enum pp_smu_status (*set_hard_min_dcfclk_by_freq)(struct pp_smu *pp, int Mhz);
180
181	/* PPSMC_MSG_SetMinDeepSleepDcfclk
182	 * when DF is in cstate, dcf clock is further divided down
183	 * to just above given frequency
184	 */
185	enum pp_smu_status (*set_min_deep_sleep_dcfclk)(struct pp_smu *pp, int Mhz);
186
187	/* PPSMC_MSG_SetHardMinUclkByFreq
188	 * UCLK will vary with DPM, but never below requested hard min
189	 */
190	enum pp_smu_status (*set_hard_min_uclk_by_freq)(struct pp_smu *pp, int Mhz);
191
192	/* PPSMC_MSG_SetHardMinSocclkByFreq
193	 * Needed for DWB support
194	 */
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_SetHardMinByFreq
201	 * Needed to set ASIC voltages for clocks programmed by DAL
202	 */
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_SetDriverDramAddrHigh
209	 * PPSMC_MSG_SetDriverDramAddrLow
210	 * PPSMC_MSG_TransferTableDram2Smu
211	 *
212	 * on DCN20:
213	 * 	reader fill clk = uclk
214	 * 	reader drain clk = dcfclk
215	 * 	writer fill clk = socclk
216	 * 	writer drain clk = uclk
217	 * */
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 all
222	 * 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 available
228	 */
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 able
233	 * to perform pstate handshaking in its current state.  Typically this handshake
234	 * 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 means
237	 * DC will make the call BEFORE setting up the display state which would cause pstate
238	 * request to go un-acked.  Only when the call completes should such a state be applied to
239	 * DC hardware
240	 */
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  8
246#define PP_SMU_NUM_DCFCLK_DPM_LEVELS  8
247#define PP_SMU_NUM_FCLK_DPM_LEVELS    4
248#define PP_SMU_NUM_MEMCLK_DPM_LEVELS  4
249#define PP_SMU_NUM_DCLK_DPM_LEVELS    8
250#define PP_SMU_NUM_VCLK_DPM_LEVELS    8
251#define PP_SMU_NUM_VPECLK_DPM_LEVELS  8
252
253struct dpm_clock {
254  uint32_t  Freq;    // In MHz
255  uint32_t  Vol;     // Millivolts with 2 fractional bits
256};
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 table
276	 *
277	 * PPSMC_MSG_SetDriverDramAddrHigh
278	 * PPSMC_MSG_SetDriverDramAddrLow
279	 * PPSMC_MSG_TransferTableDram2Smu
280	 *
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 table
294	 *
295	 * PPSMC_MSG_SetDriverDramAddrHigh
296	 * PPSMC_MSG_SetDriverDramAddrLow
297	 * PPSMC_MSG_TransferTableDram2Smu
298	 *
299	 */
300	// TODO: Check whether this is moved to DAL, and remove as needed
301	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 needed
305	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 */