Merge branch 'core-debugobjects-for-linus' of git://git.kernel.org/pub/scm/linux...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / powerplay / hwmgr / hwmgr.c
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
24 #include "pp_debug.h"
25 #include <linux/delay.h>
26 #include <linux/kernel.h>
27 #include <linux/slab.h>
28 #include <linux/types.h>
29 #include <linux/pci.h>
30 #include <drm/amdgpu_drm.h>
31 #include "power_state.h"
32 #include "hwmgr.h"
33 #include "ppsmc.h"
34 #include "amd_acpi.h"
35 #include "pp_psm.h"
36
37 extern const struct pp_smumgr_func ci_smu_funcs;
38 extern const struct pp_smumgr_func smu8_smu_funcs;
39 extern const struct pp_smumgr_func iceland_smu_funcs;
40 extern const struct pp_smumgr_func tonga_smu_funcs;
41 extern const struct pp_smumgr_func fiji_smu_funcs;
42 extern const struct pp_smumgr_func polaris10_smu_funcs;
43 extern const struct pp_smumgr_func vega10_smu_funcs;
44 extern const struct pp_smumgr_func vega12_smu_funcs;
45 extern const struct pp_smumgr_func smu10_smu_funcs;
46
47 extern int smu7_init_function_pointers(struct pp_hwmgr *hwmgr);
48 extern int smu8_init_function_pointers(struct pp_hwmgr *hwmgr);
49 extern int vega10_hwmgr_init(struct pp_hwmgr *hwmgr);
50 extern int vega12_hwmgr_init(struct pp_hwmgr *hwmgr);
51 extern int smu10_init_function_pointers(struct pp_hwmgr *hwmgr);
52
53 static int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr);
54 static void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr);
55 static int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr);
56 static int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr);
57 static int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr);
58 static int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr);
59 static int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr);
60
61
62 static void hwmgr_init_workload_prority(struct pp_hwmgr *hwmgr)
63 {
64         hwmgr->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 2;
65         hwmgr->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 0;
66         hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VIDEO] = 1;
67         hwmgr->workload_prority[PP_SMC_POWER_PROFILE_VR] = 3;
68         hwmgr->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 4;
69
70         hwmgr->workload_setting[0] = PP_SMC_POWER_PROFILE_POWERSAVING;
71         hwmgr->workload_setting[1] = PP_SMC_POWER_PROFILE_VIDEO;
72         hwmgr->workload_setting[2] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
73         hwmgr->workload_setting[3] = PP_SMC_POWER_PROFILE_VR;
74         hwmgr->workload_setting[4] = PP_SMC_POWER_PROFILE_COMPUTE;
75 }
76
77 int hwmgr_early_init(struct pp_hwmgr *hwmgr)
78 {
79         if (hwmgr == NULL)
80                 return -EINVAL;
81
82         hwmgr->usec_timeout = AMD_MAX_USEC_TIMEOUT;
83         hwmgr->power_source = PP_PowerSource_AC;
84         hwmgr->pp_table_version = PP_TABLE_V1;
85         hwmgr->dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
86         hwmgr->request_dpm_level = AMD_DPM_FORCED_LEVEL_AUTO;
87         hwmgr_init_default_caps(hwmgr);
88         hwmgr_set_user_specify_caps(hwmgr);
89         hwmgr->fan_ctrl_is_in_default_mode = true;
90         hwmgr->reload_fw = 1;
91         hwmgr_init_workload_prority(hwmgr);
92
93         switch (hwmgr->chip_family) {
94         case AMDGPU_FAMILY_CI:
95                 hwmgr->smumgr_funcs = &ci_smu_funcs;
96                 ci_set_asic_special_caps(hwmgr);
97                 hwmgr->feature_mask &= ~(PP_VBI_TIME_SUPPORT_MASK |
98                                         PP_ENABLE_GFX_CG_THRU_SMU);
99                 hwmgr->pp_table_version = PP_TABLE_V0;
100                 hwmgr->od_enabled = false;
101                 smu7_init_function_pointers(hwmgr);
102                 break;
103         case AMDGPU_FAMILY_CZ:
104                 hwmgr->od_enabled = false;
105                 hwmgr->smumgr_funcs = &smu8_smu_funcs;
106                 smu8_init_function_pointers(hwmgr);
107                 break;
108         case AMDGPU_FAMILY_VI:
109                 switch (hwmgr->chip_id) {
110                 case CHIP_TOPAZ:
111                         hwmgr->smumgr_funcs = &iceland_smu_funcs;
112                         topaz_set_asic_special_caps(hwmgr);
113                         hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK |
114                                                 PP_ENABLE_GFX_CG_THRU_SMU);
115                         hwmgr->pp_table_version = PP_TABLE_V0;
116                         hwmgr->od_enabled = false;
117                         break;
118                 case CHIP_TONGA:
119                         hwmgr->smumgr_funcs = &tonga_smu_funcs;
120                         tonga_set_asic_special_caps(hwmgr);
121                         hwmgr->feature_mask &= ~PP_VBI_TIME_SUPPORT_MASK;
122                         break;
123                 case CHIP_FIJI:
124                         hwmgr->smumgr_funcs = &fiji_smu_funcs;
125                         fiji_set_asic_special_caps(hwmgr);
126                         hwmgr->feature_mask &= ~ (PP_VBI_TIME_SUPPORT_MASK |
127                                                 PP_ENABLE_GFX_CG_THRU_SMU);
128                         break;
129                 case CHIP_POLARIS11:
130                 case CHIP_POLARIS10:
131                 case CHIP_POLARIS12:
132                         hwmgr->smumgr_funcs = &polaris10_smu_funcs;
133                         polaris_set_asic_special_caps(hwmgr);
134                         hwmgr->feature_mask &= ~(PP_UVD_HANDSHAKE_MASK);
135                         break;
136                 default:
137                         return -EINVAL;
138                 }
139                 smu7_init_function_pointers(hwmgr);
140                 break;
141         case AMDGPU_FAMILY_AI:
142                 switch (hwmgr->chip_id) {
143                 case CHIP_VEGA10:
144                         hwmgr->smumgr_funcs = &vega10_smu_funcs;
145                         vega10_hwmgr_init(hwmgr);
146                         break;
147                 case CHIP_VEGA12:
148                         hwmgr->smumgr_funcs = &vega12_smu_funcs;
149                         vega12_hwmgr_init(hwmgr);
150                         break;
151                 default:
152                         return -EINVAL;
153                 }
154                 break;
155         case AMDGPU_FAMILY_RV:
156                 switch (hwmgr->chip_id) {
157                 case CHIP_RAVEN:
158                         hwmgr->od_enabled = false;
159                         hwmgr->smumgr_funcs = &smu10_smu_funcs;
160                         smu10_init_function_pointers(hwmgr);
161                         break;
162                 default:
163                         return -EINVAL;
164                 }
165                 break;
166         default:
167                 return -EINVAL;
168         }
169
170         return 0;
171 }
172
173 int hwmgr_hw_init(struct pp_hwmgr *hwmgr)
174 {
175         int ret = 0;
176
177         if (hwmgr == NULL)
178                 return -EINVAL;
179
180         if (hwmgr->pptable_func == NULL ||
181             hwmgr->pptable_func->pptable_init == NULL ||
182             hwmgr->hwmgr_func->backend_init == NULL)
183                 return -EINVAL;
184
185         ret = hwmgr->pptable_func->pptable_init(hwmgr);
186         if (ret)
187                 goto err;
188
189         ret = hwmgr->hwmgr_func->backend_init(hwmgr);
190         if (ret)
191                 goto err1;
192
193         ret = psm_init_power_state_table(hwmgr);
194         if (ret)
195                 goto err2;
196
197         ret = phm_setup_asic(hwmgr);
198         if (ret)
199                 goto err2;
200
201         ret = phm_enable_dynamic_state_management(hwmgr);
202         if (ret)
203                 goto err2;
204         ret = phm_start_thermal_controller(hwmgr);
205         ret |= psm_set_performance_states(hwmgr);
206         if (ret)
207                 goto err2;
208
209         return 0;
210 err2:
211         if (hwmgr->hwmgr_func->backend_fini)
212                 hwmgr->hwmgr_func->backend_fini(hwmgr);
213 err1:
214         if (hwmgr->pptable_func->pptable_fini)
215                 hwmgr->pptable_func->pptable_fini(hwmgr);
216 err:
217         pr_err("amdgpu: powerplay initialization failed\n");
218         return ret;
219 }
220
221 int hwmgr_hw_fini(struct pp_hwmgr *hwmgr)
222 {
223         if (hwmgr == NULL)
224                 return -EINVAL;
225
226         phm_stop_thermal_controller(hwmgr);
227         psm_set_boot_states(hwmgr);
228         psm_adjust_power_state_dynamic(hwmgr, false, NULL);
229         phm_disable_dynamic_state_management(hwmgr);
230         phm_disable_clock_power_gatings(hwmgr);
231
232         if (hwmgr->hwmgr_func->backend_fini)
233                 hwmgr->hwmgr_func->backend_fini(hwmgr);
234         if (hwmgr->pptable_func->pptable_fini)
235                 hwmgr->pptable_func->pptable_fini(hwmgr);
236         return psm_fini_power_state_table(hwmgr);
237 }
238
239 int hwmgr_hw_suspend(struct pp_hwmgr *hwmgr)
240 {
241         int ret = 0;
242
243         if (hwmgr == NULL)
244                 return -EINVAL;
245
246         phm_disable_smc_firmware_ctf(hwmgr);
247         ret = psm_set_boot_states(hwmgr);
248         if (ret)
249                 return ret;
250         ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
251         if (ret)
252                 return ret;
253         ret = phm_power_down_asic(hwmgr);
254
255         return ret;
256 }
257
258 int hwmgr_hw_resume(struct pp_hwmgr *hwmgr)
259 {
260         int ret = 0;
261
262         if (hwmgr == NULL)
263                 return -EINVAL;
264
265         ret = phm_setup_asic(hwmgr);
266         if (ret)
267                 return ret;
268
269         ret = phm_enable_dynamic_state_management(hwmgr);
270         if (ret)
271                 return ret;
272         ret = phm_start_thermal_controller(hwmgr);
273         if (ret)
274                 return ret;
275
276         ret |= psm_set_performance_states(hwmgr);
277         if (ret)
278                 return ret;
279
280         ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
281
282         return ret;
283 }
284
285 static enum PP_StateUILabel power_state_convert(enum amd_pm_state_type  state)
286 {
287         switch (state) {
288         case POWER_STATE_TYPE_BATTERY:
289                 return PP_StateUILabel_Battery;
290         case POWER_STATE_TYPE_BALANCED:
291                 return PP_StateUILabel_Balanced;
292         case POWER_STATE_TYPE_PERFORMANCE:
293                 return PP_StateUILabel_Performance;
294         default:
295                 return PP_StateUILabel_None;
296         }
297 }
298
299 int hwmgr_handle_task(struct pp_hwmgr *hwmgr, enum amd_pp_task task_id,
300                 enum amd_pm_state_type *user_state)
301 {
302         int ret = 0;
303
304         if (hwmgr == NULL)
305                 return -EINVAL;
306
307         switch (task_id) {
308         case AMD_PP_TASK_DISPLAY_CONFIG_CHANGE:
309                 ret = phm_set_cpu_power_state(hwmgr);
310                 if (ret)
311                         return ret;
312                 ret = psm_set_performance_states(hwmgr);
313                 if (ret)
314                         return ret;
315                 ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
316                 break;
317         case AMD_PP_TASK_ENABLE_USER_STATE:
318         {
319                 enum PP_StateUILabel requested_ui_label;
320                 struct pp_power_state *requested_ps = NULL;
321
322                 if (user_state == NULL) {
323                         ret = -EINVAL;
324                         break;
325                 }
326
327                 requested_ui_label = power_state_convert(*user_state);
328                 ret = psm_set_user_performance_state(hwmgr, requested_ui_label, &requested_ps);
329                 if (ret)
330                         return ret;
331                 ret = psm_adjust_power_state_dynamic(hwmgr, false, requested_ps);
332                 break;
333         }
334         case AMD_PP_TASK_COMPLETE_INIT:
335         case AMD_PP_TASK_READJUST_POWER_STATE:
336                 ret = psm_adjust_power_state_dynamic(hwmgr, false, NULL);
337                 break;
338         default:
339                 break;
340         }
341         return ret;
342 }
343
344 void hwmgr_init_default_caps(struct pp_hwmgr *hwmgr)
345 {
346         phm_cap_unset(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
347
348         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_UVDDPM);
349         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_VCEDPM);
350
351 #if defined(CONFIG_ACPI)
352         if (amdgpu_acpi_is_pcie_performance_request_supported(hwmgr->adev))
353                 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PCIEPerformanceRequest);
354 #endif
355
356         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
357                 PHM_PlatformCaps_DynamicPatchPowerState);
358
359         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
360                 PHM_PlatformCaps_EnableSMU7ThermalManagement);
361
362         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
363                         PHM_PlatformCaps_DynamicPowerManagement);
364
365         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
366                                         PHM_PlatformCaps_SMC);
367
368         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
369                                         PHM_PlatformCaps_DynamicUVDState);
370
371         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
372                                                 PHM_PlatformCaps_FanSpeedInTableIsRPM);
373         return;
374 }
375
376 int hwmgr_set_user_specify_caps(struct pp_hwmgr *hwmgr)
377 {
378         if (hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK)
379                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
380                         PHM_PlatformCaps_SclkDeepSleep);
381         else
382                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
383                         PHM_PlatformCaps_SclkDeepSleep);
384
385         if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {
386                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
387                             PHM_PlatformCaps_PowerContainment);
388                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
389                         PHM_PlatformCaps_CAC);
390         } else {
391                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
392                             PHM_PlatformCaps_PowerContainment);
393                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
394                         PHM_PlatformCaps_CAC);
395         }
396
397         if (hwmgr->feature_mask & PP_OVERDRIVE_MASK)
398                 hwmgr->od_enabled = true;
399
400         return 0;
401 }
402
403 int polaris_set_asic_special_caps(struct pp_hwmgr *hwmgr)
404 {
405         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
406                                                 PHM_PlatformCaps_EVV);
407         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
408                                                 PHM_PlatformCaps_SQRamping);
409         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
410                                                 PHM_PlatformCaps_RegulatorHot);
411
412         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
413                                         PHM_PlatformCaps_AutomaticDCTransition);
414
415         if (hwmgr->chip_id != CHIP_POLARIS10)
416                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
417                                         PHM_PlatformCaps_SPLLShutdownSupport);
418
419         if (hwmgr->chip_id != CHIP_POLARIS11) {
420                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
421                                                         PHM_PlatformCaps_DBRamping);
422                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
423                                                         PHM_PlatformCaps_TDRamping);
424                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
425                                                         PHM_PlatformCaps_TCPRamping);
426         }
427         return 0;
428 }
429
430 int fiji_set_asic_special_caps(struct pp_hwmgr *hwmgr)
431 {
432         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
433                                                 PHM_PlatformCaps_EVV);
434         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
435                         PHM_PlatformCaps_SQRamping);
436         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
437                         PHM_PlatformCaps_DBRamping);
438         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
439                         PHM_PlatformCaps_TDRamping);
440         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
441                         PHM_PlatformCaps_TCPRamping);
442         return 0;
443 }
444
445 int tonga_set_asic_special_caps(struct pp_hwmgr *hwmgr)
446 {
447         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
448                                                 PHM_PlatformCaps_EVV);
449         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
450                         PHM_PlatformCaps_SQRamping);
451         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
452                         PHM_PlatformCaps_DBRamping);
453         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
454                         PHM_PlatformCaps_TDRamping);
455         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
456                         PHM_PlatformCaps_TCPRamping);
457
458         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
459                       PHM_PlatformCaps_UVDPowerGating);
460         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
461                       PHM_PlatformCaps_VCEPowerGating);
462         return 0;
463 }
464
465 int topaz_set_asic_special_caps(struct pp_hwmgr *hwmgr)
466 {
467         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
468                                                 PHM_PlatformCaps_EVV);
469         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
470                         PHM_PlatformCaps_SQRamping);
471         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
472                         PHM_PlatformCaps_DBRamping);
473         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
474                         PHM_PlatformCaps_TDRamping);
475         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
476                         PHM_PlatformCaps_TCPRamping);
477         return 0;
478 }
479
480 int ci_set_asic_special_caps(struct pp_hwmgr *hwmgr)
481 {
482         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
483                         PHM_PlatformCaps_SQRamping);
484         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
485                         PHM_PlatformCaps_DBRamping);
486         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
487                         PHM_PlatformCaps_TDRamping);
488         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
489                         PHM_PlatformCaps_TCPRamping);
490         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
491                         PHM_PlatformCaps_MemorySpreadSpectrumSupport);
492         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
493                         PHM_PlatformCaps_EngineSpreadSpectrumSupport);
494         return 0;
495 }