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