1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#ifndef _SMUMGR_H_
24#define _SMUMGR_H_
25#include <linux/types.h>
26#include "pp_instance.h"
27#include "amd_powerplay.h"
28
29struct pp_smumgr;
30struct pp_instance;
31struct pp_hwmgr;
32
33#define smu_lower_32_bits(n) ((uint32_t)(n))
34#define smu_upper_32_bits(n) ((uint32_t)(((n)>>16)>>16))
35
36enum AVFS_BTC_STATUS {
37 AVFS_BTC_BOOT = 0,
38 AVFS_BTC_BOOT_STARTEDSMU,
39 AVFS_LOAD_VIRUS,
40 AVFS_BTC_VIRUS_LOADED,
41 AVFS_BTC_VIRUS_FAIL,
42 AVFS_BTC_COMPLETED_PREVIOUSLY,
43 AVFS_BTC_ENABLEAVFS,
44 AVFS_BTC_STARTED,
45 AVFS_BTC_FAILED,
46 AVFS_BTC_RESTOREVFT_FAILED,
47 AVFS_BTC_SAVEVFT_FAILED,
48 AVFS_BTC_DPMTABLESETUP_FAILED,
49 AVFS_BTC_COMPLETED_UNSAVED,
50 AVFS_BTC_COMPLETED_SAVED,
51 AVFS_BTC_COMPLETED_RESTORED,
52 AVFS_BTC_DISABLED,
53 AVFS_BTC_NOTSUPPORTED,
54 AVFS_BTC_SMUMSG_ERROR
55};
56
57enum SMU_TABLE {
58 SMU_UVD_TABLE = 0,
59 SMU_VCE_TABLE,
60 SMU_SAMU_TABLE,
61 SMU_BIF_TABLE,
62};
63
64enum SMU_TYPE {
65 SMU_SoftRegisters = 0,
66 SMU_Discrete_DpmTable,
67};
68
69enum SMU_MEMBER {
70 HandshakeDisables = 0,
71 VoltageChangeTimeout,
72 AverageGraphicsActivity,
73 PreVBlankGap,
74 VBlankTimeout,
75 UcodeLoadStatus,
76 UvdBootLevel,
77 VceBootLevel,
78 SamuBootLevel,
79 LowSclkInterruptThreshold,
80};
81
82
83enum SMU_MAC_DEFINITION {
84 SMU_MAX_LEVELS_GRAPHICS = 0,
85 SMU_MAX_LEVELS_MEMORY,
86 SMU_MAX_LEVELS_LINK,
87 SMU_MAX_ENTRIES_SMIO,
88 SMU_MAX_LEVELS_VDDC,
89 SMU_MAX_LEVELS_VDDGFX,
90 SMU_MAX_LEVELS_VDDCI,
91 SMU_MAX_LEVELS_MVDD,
92 SMU_UVD_MCLK_HANDSHAKE_DISABLE,
93};
94
95
96struct pp_smumgr_func {
97 int (*smu_init)(struct pp_smumgr *smumgr);
98 int (*smu_fini)(struct pp_smumgr *smumgr);
99 int (*start_smu)(struct pp_smumgr *smumgr);
100 int (*check_fw_load_finish)(struct pp_smumgr *smumgr,
101 uint32_t firmware);
102 int (*request_smu_load_fw)(struct pp_smumgr *smumgr);
103 int (*request_smu_load_specific_fw)(struct pp_smumgr *smumgr,
104 uint32_t firmware);
105 int (*get_argument)(struct pp_smumgr *smumgr);
106 int (*send_msg_to_smc)(struct pp_smumgr *smumgr, uint16_t msg);
107 int (*send_msg_to_smc_with_parameter)(struct pp_smumgr *smumgr,
108 uint16_t msg, uint32_t parameter);
109 int (*download_pptable_settings)(struct pp_smumgr *smumgr,
110 void **table);
111 int (*upload_pptable_settings)(struct pp_smumgr *smumgr);
112 int (*update_smc_table)(struct pp_hwmgr *hwmgr, uint32_t type);
113 int (*process_firmware_header)(struct pp_hwmgr *hwmgr);
114 int (*update_sclk_threshold)(struct pp_hwmgr *hwmgr);
115 int (*thermal_setup_fan_table)(struct pp_hwmgr *hwmgr);
116 int (*thermal_avfs_enable)(struct pp_hwmgr *hwmgr);
117 int (*init_smc_table)(struct pp_hwmgr *hwmgr);
118 int (*populate_all_graphic_levels)(struct pp_hwmgr *hwmgr);
119 int (*populate_all_memory_levels)(struct pp_hwmgr *hwmgr);
120 int (*initialize_mc_reg_table)(struct pp_hwmgr *hwmgr);
121 uint32_t (*get_offsetof)(uint32_t type, uint32_t member);
122 uint32_t (*get_mac_definition)(uint32_t value);
123 bool (*is_dpm_running)(struct pp_hwmgr *hwmgr);
124};
125
126struct pp_smumgr {
127 uint32_t chip_family;
128 uint32_t chip_id;
129 void *device;
130 void *backend;
131 uint32_t usec_timeout;
132 bool reload_fw;
133 const struct pp_smumgr_func *smumgr_funcs;
134};
135
136
137extern int smum_init(struct amd_pp_init *pp_init,
138 struct pp_instance *handle);
139
140extern int smum_fini(struct pp_smumgr *smumgr);
141
142extern int smum_get_argument(struct pp_smumgr *smumgr);
143
144extern int smum_download_powerplay_table(struct pp_smumgr *smumgr, void **table);
145
146extern int smum_upload_powerplay_table(struct pp_smumgr *smumgr);
147
148extern int smum_send_msg_to_smc(struct pp_smumgr *smumgr, uint16_t msg);
149
150extern int smum_send_msg_to_smc_with_parameter(struct pp_smumgr *smumgr,
151 uint16_t msg, uint32_t parameter);
152
153extern int smum_wait_on_register(struct pp_smumgr *smumgr,
154 uint32_t index, uint32_t value, uint32_t mask);
155
156extern int smum_wait_for_register_unequal(struct pp_smumgr *smumgr,
157 uint32_t index, uint32_t value, uint32_t mask);
158
159extern int smum_wait_on_indirect_register(struct pp_smumgr *smumgr,
160 uint32_t indirect_port, uint32_t index,
161 uint32_t value, uint32_t mask);
162
163
164extern void smum_wait_for_indirect_register_unequal(
165 struct pp_smumgr *smumgr,
166 uint32_t indirect_port, uint32_t index,
167 uint32_t value, uint32_t mask);
168
169extern int smu_allocate_memory(void *device, uint32_t size,
170 enum cgs_gpu_mem_type type,
171 uint32_t byte_align, uint64_t *mc_addr,
172 void **kptr, void *handle);
173
174extern int smu_free_memory(void *device, void *handle);
175
176extern int cz_smum_init(struct pp_smumgr *smumgr);
177extern int iceland_smum_init(struct pp_smumgr *smumgr);
178extern int tonga_smum_init(struct pp_smumgr *smumgr);
179extern int fiji_smum_init(struct pp_smumgr *smumgr);
180extern int polaris10_smum_init(struct pp_smumgr *smumgr);
181
182extern int smum_update_sclk_threshold(struct pp_hwmgr *hwmgr);
183
184extern int smum_update_smc_table(struct pp_hwmgr *hwmgr, uint32_t type);
185extern int smum_process_firmware_header(struct pp_hwmgr *hwmgr);
186extern int smum_thermal_avfs_enable(struct pp_hwmgr *hwmgr,
187 void *input, void *output, void *storage, int result);
188extern int smum_thermal_setup_fan_table(struct pp_hwmgr *hwmgr,
189 void *input, void *output, void *storage, int result);
190extern int smum_init_smc_table(struct pp_hwmgr *hwmgr);
191extern int smum_populate_all_graphic_levels(struct pp_hwmgr *hwmgr);
192extern int smum_populate_all_memory_levels(struct pp_hwmgr *hwmgr);
193extern int smum_initialize_mc_reg_table(struct pp_hwmgr *hwmgr);
194extern uint32_t smum_get_offsetof(struct pp_smumgr *smumgr,
195 uint32_t type, uint32_t member);
196extern uint32_t smum_get_mac_definition(struct pp_smumgr *smumgr, uint32_t value);
197
198extern bool smum_is_dpm_running(struct pp_hwmgr *hwmgr);
199
200#define SMUM_FIELD_SHIFT(reg, field) reg##__##field##__SHIFT
201
202#define SMUM_FIELD_MASK(reg, field) reg##__##field##_MASK
203
204#define SMUM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(smumgr, \
205 port, index, value, mask) \
206 smum_wait_on_indirect_register(smumgr, \
207 mm##port##_INDEX, index, value, mask)
208
209#define SMUM_WAIT_INDIRECT_REGISTER(smumgr, port, reg, value, mask) \
210 SMUM_WAIT_INDIRECT_REGISTER_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
211
212#define SMUM_WAIT_INDIRECT_FIELD(smumgr, port, reg, field, fieldval) \
213 SMUM_WAIT_INDIRECT_REGISTER(smumgr, port, reg, (fieldval) << SMUM_FIELD_SHIFT(reg, field), \
214 SMUM_FIELD_MASK(reg, field) )
215
216#define SMUM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, \
217 index, value, mask) \
218 smum_wait_for_register_unequal(smumgr, \
219 index, value, mask)
220
221#define SMUM_WAIT_REGISTER_UNEQUAL(smumgr, reg, value, mask) \
222 SMUM_WAIT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, \
223 mm##reg, value, mask)
224
225#define SMUM_WAIT_FIELD_UNEQUAL(smumgr, reg, field, fieldval) \
226 SMUM_WAIT_REGISTER_UNEQUAL(smumgr, reg, \
227 (fieldval) << SMUM_FIELD_SHIFT(reg, field), \
228 SMUM_FIELD_MASK(reg, field))
229
230#define SMUM_GET_FIELD(value, reg, field) \
231 (((value) & SMUM_FIELD_MASK(reg, field)) \
232 >> SMUM_FIELD_SHIFT(reg, field))
233
234#define SMUM_READ_FIELD(device, reg, field) \
235 SMUM_GET_FIELD(cgs_read_register(device, mm##reg), reg, field)
236
237#define SMUM_SET_FIELD(value, reg, field, field_val) \
238 (((value) & ~SMUM_FIELD_MASK(reg, field)) | \
239 (SMUM_FIELD_MASK(reg, field) & ((field_val) << \
240 SMUM_FIELD_SHIFT(reg, field))))
241
242#define SMUM_READ_INDIRECT_FIELD(device, port, reg, field) \
243 SMUM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
244 reg, field)
245
246#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(smumgr, \
247 port, index, value, mask) \
248 smum_wait_on_indirect_register(smumgr, \
249 mm##port##_INDEX_0, index, value, mask)
250
251#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, \
252 port, index, value, mask) \
253 smum_wait_for_indirect_register_unequal(smumgr, \
254 mm##port##_INDEX_0, index, value, mask)
255
256
257#define SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, port, reg, value, mask) \
258 SMUM_WAIT_VFPF_INDIRECT_REGISTER_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
259
260#define SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg, value, mask) \
261 SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
262
263
264
265
266#define SMUM_READ_VFPF_INDIRECT_FIELD(device, port, reg, field) \
267 SMUM_GET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
268 reg, field)
269
270#define SMUM_WRITE_FIELD(device, reg, field, fieldval) \
271 cgs_write_register(device, mm##reg, \
272 SMUM_SET_FIELD(cgs_read_register(device, mm##reg), reg, field, fieldval))
273
274#define SMUM_WRITE_VFPF_INDIRECT_FIELD(device, port, reg, field, fieldval) \
275 cgs_write_ind_register(device, port, ix##reg, \
276 SMUM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
277 reg, field, fieldval))
278
279
280#define SMUM_WRITE_INDIRECT_FIELD(device, port, reg, field, fieldval) \
281 cgs_write_ind_register(device, port, ix##reg, \
282 SMUM_SET_FIELD(cgs_read_ind_register(device, port, ix##reg), \
283 reg, field, fieldval))
284
285
286#define SMUM_WAIT_VFPF_INDIRECT_FIELD(smumgr, port, reg, field, fieldval) \
287 SMUM_WAIT_VFPF_INDIRECT_REGISTER(smumgr, port, reg, \
288 (fieldval) << SMUM_FIELD_SHIFT(reg, field), \
289 SMUM_FIELD_MASK(reg, field))
290
291#define SMUM_WAIT_VFPF_INDIRECT_FIELD_UNEQUAL(smumgr, port, reg, field, fieldval) \
292 SMUM_WAIT_VFPF_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg, \
293 (fieldval) << SMUM_FIELD_SHIFT(reg, field), \
294 SMUM_FIELD_MASK(reg, field))
295
296#define SMUM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, port, index, value, mask) \
297 smum_wait_for_indirect_register_unequal(smumgr, \
298 mm##port##_INDEX, index, value, mask)
299
300#define SMUM_WAIT_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg, value, mask) \
301 SMUM_WAIT_INDIRECT_REGISTER_UNEQUAL_GIVEN_INDEX(smumgr, port, ix##reg, value, mask)
302
303#define SMUM_WAIT_INDIRECT_FIELD_UNEQUAL(smumgr, port, reg, field, fieldval) \
304 SMUM_WAIT_INDIRECT_REGISTER_UNEQUAL(smumgr, port, reg, (fieldval) << SMUM_FIELD_SHIFT(reg, field), \
305 SMUM_FIELD_MASK(reg, field) )
306
307#endif
308