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