Merge tag 'asoc-fix-v5.6-rc4' of https://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_dpm.c
1 /*
2  * Copyright 2011 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: Alex Deucher
23  */
24
25 #include "amdgpu.h"
26 #include "amdgpu_atombios.h"
27 #include "amdgpu_i2c.h"
28 #include "amdgpu_dpm.h"
29 #include "atom.h"
30 #include "amd_pcie.h"
31
32 void amdgpu_dpm_print_class_info(u32 class, u32 class2)
33 {
34         const char *s;
35
36         switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
37         case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
38         default:
39                 s = "none";
40                 break;
41         case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
42                 s = "battery";
43                 break;
44         case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
45                 s = "balanced";
46                 break;
47         case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
48                 s = "performance";
49                 break;
50         }
51         printk("\tui class: %s\n", s);
52         printk("\tinternal class:");
53         if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
54             (class2 == 0))
55                 pr_cont(" none");
56         else {
57                 if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
58                         pr_cont(" boot");
59                 if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
60                         pr_cont(" thermal");
61                 if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
62                         pr_cont(" limited_pwr");
63                 if (class & ATOM_PPLIB_CLASSIFICATION_REST)
64                         pr_cont(" rest");
65                 if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
66                         pr_cont(" forced");
67                 if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
68                         pr_cont(" 3d_perf");
69                 if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
70                         pr_cont(" ovrdrv");
71                 if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
72                         pr_cont(" uvd");
73                 if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
74                         pr_cont(" 3d_low");
75                 if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
76                         pr_cont(" acpi");
77                 if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
78                         pr_cont(" uvd_hd2");
79                 if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
80                         pr_cont(" uvd_hd");
81                 if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
82                         pr_cont(" uvd_sd");
83                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
84                         pr_cont(" limited_pwr2");
85                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
86                         pr_cont(" ulv");
87                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
88                         pr_cont(" uvd_mvc");
89         }
90         pr_cont("\n");
91 }
92
93 void amdgpu_dpm_print_cap_info(u32 caps)
94 {
95         printk("\tcaps:");
96         if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
97                 pr_cont(" single_disp");
98         if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
99                 pr_cont(" video");
100         if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
101                 pr_cont(" no_dc");
102         pr_cont("\n");
103 }
104
105 void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
106                                 struct amdgpu_ps *rps)
107 {
108         printk("\tstatus:");
109         if (rps == adev->pm.dpm.current_ps)
110                 pr_cont(" c");
111         if (rps == adev->pm.dpm.requested_ps)
112                 pr_cont(" r");
113         if (rps == adev->pm.dpm.boot_ps)
114                 pr_cont(" b");
115         pr_cont("\n");
116 }
117
118 void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
119 {
120         struct drm_device *ddev = adev->ddev;
121         struct drm_crtc *crtc;
122         struct amdgpu_crtc *amdgpu_crtc;
123
124         adev->pm.dpm.new_active_crtcs = 0;
125         adev->pm.dpm.new_active_crtc_count = 0;
126         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
127                 list_for_each_entry(crtc,
128                                     &ddev->mode_config.crtc_list, head) {
129                         amdgpu_crtc = to_amdgpu_crtc(crtc);
130                         if (amdgpu_crtc->enabled) {
131                                 adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
132                                 adev->pm.dpm.new_active_crtc_count++;
133                         }
134                 }
135         }
136 }
137
138
139 u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
140 {
141         struct drm_device *dev = adev->ddev;
142         struct drm_crtc *crtc;
143         struct amdgpu_crtc *amdgpu_crtc;
144         u32 vblank_in_pixels;
145         u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
146
147         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
148                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
149                         amdgpu_crtc = to_amdgpu_crtc(crtc);
150                         if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
151                                 vblank_in_pixels =
152                                         amdgpu_crtc->hw_mode.crtc_htotal *
153                                         (amdgpu_crtc->hw_mode.crtc_vblank_end -
154                                         amdgpu_crtc->hw_mode.crtc_vdisplay +
155                                         (amdgpu_crtc->v_border * 2));
156
157                                 vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
158                                 break;
159                         }
160                 }
161         }
162
163         return vblank_time_us;
164 }
165
166 u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
167 {
168         struct drm_device *dev = adev->ddev;
169         struct drm_crtc *crtc;
170         struct amdgpu_crtc *amdgpu_crtc;
171         u32 vrefresh = 0;
172
173         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
174                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
175                         amdgpu_crtc = to_amdgpu_crtc(crtc);
176                         if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
177                                 vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
178                                 break;
179                         }
180                 }
181         }
182
183         return vrefresh;
184 }
185
186 bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor)
187 {
188         switch (sensor) {
189         case THERMAL_TYPE_RV6XX:
190         case THERMAL_TYPE_RV770:
191         case THERMAL_TYPE_EVERGREEN:
192         case THERMAL_TYPE_SUMO:
193         case THERMAL_TYPE_NI:
194         case THERMAL_TYPE_SI:
195         case THERMAL_TYPE_CI:
196         case THERMAL_TYPE_KV:
197                 return true;
198         case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
199         case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
200                 return false; /* need special handling */
201         case THERMAL_TYPE_NONE:
202         case THERMAL_TYPE_EXTERNAL:
203         case THERMAL_TYPE_EXTERNAL_GPIO:
204         default:
205                 return false;
206         }
207 }
208
209 union power_info {
210         struct _ATOM_POWERPLAY_INFO info;
211         struct _ATOM_POWERPLAY_INFO_V2 info_2;
212         struct _ATOM_POWERPLAY_INFO_V3 info_3;
213         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
214         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
215         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
216         struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
217         struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
218 };
219
220 union fan_info {
221         struct _ATOM_PPLIB_FANTABLE fan;
222         struct _ATOM_PPLIB_FANTABLE2 fan2;
223         struct _ATOM_PPLIB_FANTABLE3 fan3;
224 };
225
226 static int amdgpu_parse_clk_voltage_dep_table(struct amdgpu_clock_voltage_dependency_table *amdgpu_table,
227                                               ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
228 {
229         u32 size = atom_table->ucNumEntries *
230                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
231         int i;
232         ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry;
233
234         amdgpu_table->entries = kzalloc(size, GFP_KERNEL);
235         if (!amdgpu_table->entries)
236                 return -ENOMEM;
237
238         entry = &atom_table->entries[0];
239         for (i = 0; i < atom_table->ucNumEntries; i++) {
240                 amdgpu_table->entries[i].clk = le16_to_cpu(entry->usClockLow) |
241                         (entry->ucClockHigh << 16);
242                 amdgpu_table->entries[i].v = le16_to_cpu(entry->usVoltage);
243                 entry = (ATOM_PPLIB_Clock_Voltage_Dependency_Record *)
244                         ((u8 *)entry + sizeof(ATOM_PPLIB_Clock_Voltage_Dependency_Record));
245         }
246         amdgpu_table->count = atom_table->ucNumEntries;
247
248         return 0;
249 }
250
251 int amdgpu_get_platform_caps(struct amdgpu_device *adev)
252 {
253         struct amdgpu_mode_info *mode_info = &adev->mode_info;
254         union power_info *power_info;
255         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
256         u16 data_offset;
257         u8 frev, crev;
258
259         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
260                                    &frev, &crev, &data_offset))
261                 return -EINVAL;
262         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
263
264         adev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
265         adev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
266         adev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
267
268         return 0;
269 }
270
271 /* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
272 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
273 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
274 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
275 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
276 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
277 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
278 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8 24
279 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V9 26
280
281 int amdgpu_parse_extended_power_table(struct amdgpu_device *adev)
282 {
283         struct amdgpu_mode_info *mode_info = &adev->mode_info;
284         union power_info *power_info;
285         union fan_info *fan_info;
286         ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
287         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
288         u16 data_offset;
289         u8 frev, crev;
290         int ret, i;
291
292         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
293                                    &frev, &crev, &data_offset))
294                 return -EINVAL;
295         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
296
297         /* fan table */
298         if (le16_to_cpu(power_info->pplib.usTableSize) >=
299             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
300                 if (power_info->pplib3.usFanTableOffset) {
301                         fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
302                                                       le16_to_cpu(power_info->pplib3.usFanTableOffset));
303                         adev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
304                         adev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
305                         adev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
306                         adev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
307                         adev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
308                         adev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
309                         adev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
310                         if (fan_info->fan.ucFanTableFormat >= 2)
311                                 adev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
312                         else
313                                 adev->pm.dpm.fan.t_max = 10900;
314                         adev->pm.dpm.fan.cycle_delay = 100000;
315                         if (fan_info->fan.ucFanTableFormat >= 3) {
316                                 adev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
317                                 adev->pm.dpm.fan.default_max_fan_pwm =
318                                         le16_to_cpu(fan_info->fan3.usFanPWMMax);
319                                 adev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
320                                 adev->pm.dpm.fan.fan_output_sensitivity =
321                                         le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
322                         }
323                         adev->pm.dpm.fan.ucode_fan_control = true;
324                 }
325         }
326
327         /* clock dependancy tables, shedding tables */
328         if (le16_to_cpu(power_info->pplib.usTableSize) >=
329             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
330                 if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
331                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
332                                 (mode_info->atom_context->bios + data_offset +
333                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
334                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
335                                                                  dep_table);
336                         if (ret) {
337                                 amdgpu_free_extended_power_table(adev);
338                                 return ret;
339                         }
340                 }
341                 if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
342                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
343                                 (mode_info->atom_context->bios + data_offset +
344                                  le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
345                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
346                                                                  dep_table);
347                         if (ret) {
348                                 amdgpu_free_extended_power_table(adev);
349                                 return ret;
350                         }
351                 }
352                 if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
353                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
354                                 (mode_info->atom_context->bios + data_offset +
355                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
356                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
357                                                                  dep_table);
358                         if (ret) {
359                                 amdgpu_free_extended_power_table(adev);
360                                 return ret;
361                         }
362                 }
363                 if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
364                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
365                                 (mode_info->atom_context->bios + data_offset +
366                                  le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
367                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
368                                                                  dep_table);
369                         if (ret) {
370                                 amdgpu_free_extended_power_table(adev);
371                                 return ret;
372                         }
373                 }
374                 if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
375                         ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
376                                 (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
377                                 (mode_info->atom_context->bios + data_offset +
378                                  le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
379                         if (clk_v->ucNumEntries) {
380                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
381                                         le16_to_cpu(clk_v->entries[0].usSclkLow) |
382                                         (clk_v->entries[0].ucSclkHigh << 16);
383                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
384                                         le16_to_cpu(clk_v->entries[0].usMclkLow) |
385                                         (clk_v->entries[0].ucMclkHigh << 16);
386                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
387                                         le16_to_cpu(clk_v->entries[0].usVddc);
388                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
389                                         le16_to_cpu(clk_v->entries[0].usVddci);
390                         }
391                 }
392                 if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
393                         ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
394                                 (ATOM_PPLIB_PhaseSheddingLimits_Table *)
395                                 (mode_info->atom_context->bios + data_offset +
396                                  le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
397                         ATOM_PPLIB_PhaseSheddingLimits_Record *entry;
398
399                         adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
400                                 kcalloc(psl->ucNumEntries,
401                                         sizeof(struct amdgpu_phase_shedding_limits_entry),
402                                         GFP_KERNEL);
403                         if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
404                                 amdgpu_free_extended_power_table(adev);
405                                 return -ENOMEM;
406                         }
407
408                         entry = &psl->entries[0];
409                         for (i = 0; i < psl->ucNumEntries; i++) {
410                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
411                                         le16_to_cpu(entry->usSclkLow) | (entry->ucSclkHigh << 16);
412                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
413                                         le16_to_cpu(entry->usMclkLow) | (entry->ucMclkHigh << 16);
414                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
415                                         le16_to_cpu(entry->usVoltage);
416                                 entry = (ATOM_PPLIB_PhaseSheddingLimits_Record *)
417                                         ((u8 *)entry + sizeof(ATOM_PPLIB_PhaseSheddingLimits_Record));
418                         }
419                         adev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
420                                 psl->ucNumEntries;
421                 }
422         }
423
424         /* cac data */
425         if (le16_to_cpu(power_info->pplib.usTableSize) >=
426             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
427                 adev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
428                 adev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
429                 adev->pm.dpm.near_tdp_limit_adjusted = adev->pm.dpm.near_tdp_limit;
430                 adev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
431                 if (adev->pm.dpm.tdp_od_limit)
432                         adev->pm.dpm.power_control = true;
433                 else
434                         adev->pm.dpm.power_control = false;
435                 adev->pm.dpm.tdp_adjustment = 0;
436                 adev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
437                 adev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
438                 adev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
439                 if (power_info->pplib5.usCACLeakageTableOffset) {
440                         ATOM_PPLIB_CAC_Leakage_Table *cac_table =
441                                 (ATOM_PPLIB_CAC_Leakage_Table *)
442                                 (mode_info->atom_context->bios + data_offset +
443                                  le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
444                         ATOM_PPLIB_CAC_Leakage_Record *entry;
445                         u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table);
446                         adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
447                         if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) {
448                                 amdgpu_free_extended_power_table(adev);
449                                 return -ENOMEM;
450                         }
451                         entry = &cac_table->entries[0];
452                         for (i = 0; i < cac_table->ucNumEntries; i++) {
453                                 if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
454                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc1 =
455                                                 le16_to_cpu(entry->usVddc1);
456                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc2 =
457                                                 le16_to_cpu(entry->usVddc2);
458                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc3 =
459                                                 le16_to_cpu(entry->usVddc3);
460                                 } else {
461                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
462                                                 le16_to_cpu(entry->usVddc);
463                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
464                                                 le32_to_cpu(entry->ulLeakageValue);
465                                 }
466                                 entry = (ATOM_PPLIB_CAC_Leakage_Record *)
467                                         ((u8 *)entry + sizeof(ATOM_PPLIB_CAC_Leakage_Record));
468                         }
469                         adev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
470                 }
471         }
472
473         /* ext tables */
474         if (le16_to_cpu(power_info->pplib.usTableSize) >=
475             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
476                 ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
477                         (mode_info->atom_context->bios + data_offset +
478                          le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
479                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2) &&
480                         ext_hdr->usVCETableOffset) {
481                         VCEClockInfoArray *array = (VCEClockInfoArray *)
482                                 (mode_info->atom_context->bios + data_offset +
483                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1);
484                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *limits =
485                                 (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
486                                 (mode_info->atom_context->bios + data_offset +
487                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
488                                  1 + array->ucNumEntries * sizeof(VCEClockInfo));
489                         ATOM_PPLIB_VCE_State_Table *states =
490                                 (ATOM_PPLIB_VCE_State_Table *)
491                                 (mode_info->atom_context->bios + data_offset +
492                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
493                                  1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
494                                  1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
495                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
496                         ATOM_PPLIB_VCE_State_Record *state_entry;
497                         VCEClockInfo *vce_clk;
498                         u32 size = limits->numEntries *
499                                 sizeof(struct amdgpu_vce_clock_voltage_dependency_entry);
500                         adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
501                                 kzalloc(size, GFP_KERNEL);
502                         if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) {
503                                 amdgpu_free_extended_power_table(adev);
504                                 return -ENOMEM;
505                         }
506                         adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
507                                 limits->numEntries;
508                         entry = &limits->entries[0];
509                         state_entry = &states->entries[0];
510                         for (i = 0; i < limits->numEntries; i++) {
511                                 vce_clk = (VCEClockInfo *)
512                                         ((u8 *)&array->entries[0] +
513                                          (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
514                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
515                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
516                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].ecclk =
517                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
518                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].v =
519                                         le16_to_cpu(entry->usVoltage);
520                                 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
521                                         ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
522                         }
523                         adev->pm.dpm.num_of_vce_states =
524                                         states->numEntries > AMD_MAX_VCE_LEVELS ?
525                                         AMD_MAX_VCE_LEVELS : states->numEntries;
526                         for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
527                                 vce_clk = (VCEClockInfo *)
528                                         ((u8 *)&array->entries[0] +
529                                          (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
530                                 adev->pm.dpm.vce_states[i].evclk =
531                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
532                                 adev->pm.dpm.vce_states[i].ecclk =
533                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
534                                 adev->pm.dpm.vce_states[i].clk_idx =
535                                         state_entry->ucClockInfoIndex & 0x3f;
536                                 adev->pm.dpm.vce_states[i].pstate =
537                                         (state_entry->ucClockInfoIndex & 0xc0) >> 6;
538                                 state_entry = (ATOM_PPLIB_VCE_State_Record *)
539                                         ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
540                         }
541                 }
542                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
543                         ext_hdr->usUVDTableOffset) {
544                         UVDClockInfoArray *array = (UVDClockInfoArray *)
545                                 (mode_info->atom_context->bios + data_offset +
546                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1);
547                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *limits =
548                                 (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
549                                 (mode_info->atom_context->bios + data_offset +
550                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1 +
551                                  1 + (array->ucNumEntries * sizeof (UVDClockInfo)));
552                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *entry;
553                         u32 size = limits->numEntries *
554                                 sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry);
555                         adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries =
556                                 kzalloc(size, GFP_KERNEL);
557                         if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) {
558                                 amdgpu_free_extended_power_table(adev);
559                                 return -ENOMEM;
560                         }
561                         adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count =
562                                 limits->numEntries;
563                         entry = &limits->entries[0];
564                         for (i = 0; i < limits->numEntries; i++) {
565                                 UVDClockInfo *uvd_clk = (UVDClockInfo *)
566                                         ((u8 *)&array->entries[0] +
567                                          (entry->ucUVDClockInfoIndex * sizeof(UVDClockInfo)));
568                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].vclk =
569                                         le16_to_cpu(uvd_clk->usVClkLow) | (uvd_clk->ucVClkHigh << 16);
570                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk =
571                                         le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16);
572                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v =
573                                         le16_to_cpu(entry->usVoltage);
574                                 entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *)
575                                         ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record));
576                         }
577                 }
578                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4) &&
579                         ext_hdr->usSAMUTableOffset) {
580                         ATOM_PPLIB_SAMClk_Voltage_Limit_Table *limits =
581                                 (ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
582                                 (mode_info->atom_context->bios + data_offset +
583                                  le16_to_cpu(ext_hdr->usSAMUTableOffset) + 1);
584                         ATOM_PPLIB_SAMClk_Voltage_Limit_Record *entry;
585                         u32 size = limits->numEntries *
586                                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
587                         adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries =
588                                 kzalloc(size, GFP_KERNEL);
589                         if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) {
590                                 amdgpu_free_extended_power_table(adev);
591                                 return -ENOMEM;
592                         }
593                         adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count =
594                                 limits->numEntries;
595                         entry = &limits->entries[0];
596                         for (i = 0; i < limits->numEntries; i++) {
597                                 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].clk =
598                                         le16_to_cpu(entry->usSAMClockLow) | (entry->ucSAMClockHigh << 16);
599                                 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].v =
600                                         le16_to_cpu(entry->usVoltage);
601                                 entry = (ATOM_PPLIB_SAMClk_Voltage_Limit_Record *)
602                                         ((u8 *)entry + sizeof(ATOM_PPLIB_SAMClk_Voltage_Limit_Record));
603                         }
604                 }
605                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
606                     ext_hdr->usPPMTableOffset) {
607                         ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
608                                 (mode_info->atom_context->bios + data_offset +
609                                  le16_to_cpu(ext_hdr->usPPMTableOffset));
610                         adev->pm.dpm.dyn_state.ppm_table =
611                                 kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL);
612                         if (!adev->pm.dpm.dyn_state.ppm_table) {
613                                 amdgpu_free_extended_power_table(adev);
614                                 return -ENOMEM;
615                         }
616                         adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
617                         adev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
618                                 le16_to_cpu(ppm->usCpuCoreNumber);
619                         adev->pm.dpm.dyn_state.ppm_table->platform_tdp =
620                                 le32_to_cpu(ppm->ulPlatformTDP);
621                         adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
622                                 le32_to_cpu(ppm->ulSmallACPlatformTDP);
623                         adev->pm.dpm.dyn_state.ppm_table->platform_tdc =
624                                 le32_to_cpu(ppm->ulPlatformTDC);
625                         adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
626                                 le32_to_cpu(ppm->ulSmallACPlatformTDC);
627                         adev->pm.dpm.dyn_state.ppm_table->apu_tdp =
628                                 le32_to_cpu(ppm->ulApuTDP);
629                         adev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
630                                 le32_to_cpu(ppm->ulDGpuTDP);
631                         adev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
632                                 le32_to_cpu(ppm->ulDGpuUlvPower);
633                         adev->pm.dpm.dyn_state.ppm_table->tj_max =
634                                 le32_to_cpu(ppm->ulTjmax);
635                 }
636                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6) &&
637                         ext_hdr->usACPTableOffset) {
638                         ATOM_PPLIB_ACPClk_Voltage_Limit_Table *limits =
639                                 (ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
640                                 (mode_info->atom_context->bios + data_offset +
641                                  le16_to_cpu(ext_hdr->usACPTableOffset) + 1);
642                         ATOM_PPLIB_ACPClk_Voltage_Limit_Record *entry;
643                         u32 size = limits->numEntries *
644                                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
645                         adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries =
646                                 kzalloc(size, GFP_KERNEL);
647                         if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) {
648                                 amdgpu_free_extended_power_table(adev);
649                                 return -ENOMEM;
650                         }
651                         adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count =
652                                 limits->numEntries;
653                         entry = &limits->entries[0];
654                         for (i = 0; i < limits->numEntries; i++) {
655                                 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].clk =
656                                         le16_to_cpu(entry->usACPClockLow) | (entry->ucACPClockHigh << 16);
657                                 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].v =
658                                         le16_to_cpu(entry->usVoltage);
659                                 entry = (ATOM_PPLIB_ACPClk_Voltage_Limit_Record *)
660                                         ((u8 *)entry + sizeof(ATOM_PPLIB_ACPClk_Voltage_Limit_Record));
661                         }
662                 }
663                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) &&
664                         ext_hdr->usPowerTuneTableOffset) {
665                         u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset +
666                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
667                         ATOM_PowerTune_Table *pt;
668                         adev->pm.dpm.dyn_state.cac_tdp_table =
669                                 kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL);
670                         if (!adev->pm.dpm.dyn_state.cac_tdp_table) {
671                                 amdgpu_free_extended_power_table(adev);
672                                 return -ENOMEM;
673                         }
674                         if (rev > 0) {
675                                 ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *)
676                                         (mode_info->atom_context->bios + data_offset +
677                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
678                                 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
679                                         ppt->usMaximumPowerDeliveryLimit;
680                                 pt = &ppt->power_tune_table;
681                         } else {
682                                 ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
683                                         (mode_info->atom_context->bios + data_offset +
684                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
685                                 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255;
686                                 pt = &ppt->power_tune_table;
687                         }
688                         adev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP);
689                         adev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp =
690                                 le16_to_cpu(pt->usConfigurableTDP);
691                         adev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC);
692                         adev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit =
693                                 le16_to_cpu(pt->usBatteryPowerLimit);
694                         adev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit =
695                                 le16_to_cpu(pt->usSmallPowerLimit);
696                         adev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage =
697                                 le16_to_cpu(pt->usLowCACLeakage);
698                         adev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage =
699                                 le16_to_cpu(pt->usHighCACLeakage);
700                 }
701                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8) &&
702                                 ext_hdr->usSclkVddgfxTableOffset) {
703                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
704                                 (mode_info->atom_context->bios + data_offset +
705                                  le16_to_cpu(ext_hdr->usSclkVddgfxTableOffset));
706                         ret = amdgpu_parse_clk_voltage_dep_table(
707                                         &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk,
708                                         dep_table);
709                         if (ret) {
710                                 kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries);
711                                 return ret;
712                         }
713                 }
714         }
715
716         return 0;
717 }
718
719 void amdgpu_free_extended_power_table(struct amdgpu_device *adev)
720 {
721         struct amdgpu_dpm_dynamic_state *dyn_state = &adev->pm.dpm.dyn_state;
722
723         kfree(dyn_state->vddc_dependency_on_sclk.entries);
724         kfree(dyn_state->vddci_dependency_on_mclk.entries);
725         kfree(dyn_state->vddc_dependency_on_mclk.entries);
726         kfree(dyn_state->mvdd_dependency_on_mclk.entries);
727         kfree(dyn_state->cac_leakage_table.entries);
728         kfree(dyn_state->phase_shedding_limits_table.entries);
729         kfree(dyn_state->ppm_table);
730         kfree(dyn_state->cac_tdp_table);
731         kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
732         kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
733         kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
734         kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
735         kfree(dyn_state->vddgfx_dependency_on_sclk.entries);
736 }
737
738 static const char *pp_lib_thermal_controller_names[] = {
739         "NONE",
740         "lm63",
741         "adm1032",
742         "adm1030",
743         "max6649",
744         "lm64",
745         "f75375",
746         "RV6xx",
747         "RV770",
748         "adt7473",
749         "NONE",
750         "External GPIO",
751         "Evergreen",
752         "emc2103",
753         "Sumo",
754         "Northern Islands",
755         "Southern Islands",
756         "lm96163",
757         "Sea Islands",
758         "Kaveri/Kabini",
759 };
760
761 void amdgpu_add_thermal_controller(struct amdgpu_device *adev)
762 {
763         struct amdgpu_mode_info *mode_info = &adev->mode_info;
764         ATOM_PPLIB_POWERPLAYTABLE *power_table;
765         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
766         ATOM_PPLIB_THERMALCONTROLLER *controller;
767         struct amdgpu_i2c_bus_rec i2c_bus;
768         u16 data_offset;
769         u8 frev, crev;
770
771         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
772                                    &frev, &crev, &data_offset))
773                 return;
774         power_table = (ATOM_PPLIB_POWERPLAYTABLE *)
775                 (mode_info->atom_context->bios + data_offset);
776         controller = &power_table->sThermalController;
777
778         /* add the i2c bus for thermal/fan chip */
779         if (controller->ucType > 0) {
780                 if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
781                         adev->pm.no_fan = true;
782                 adev->pm.fan_pulses_per_revolution =
783                         controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
784                 if (adev->pm.fan_pulses_per_revolution) {
785                         adev->pm.fan_min_rpm = controller->ucFanMinRPM;
786                         adev->pm.fan_max_rpm = controller->ucFanMaxRPM;
787                 }
788                 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
789                         DRM_INFO("Internal thermal controller %s fan control\n",
790                                  (controller->ucFanParameters &
791                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
792                         adev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
793                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
794                         DRM_INFO("Internal thermal controller %s fan control\n",
795                                  (controller->ucFanParameters &
796                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
797                         adev->pm.int_thermal_type = THERMAL_TYPE_RV770;
798                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
799                         DRM_INFO("Internal thermal controller %s fan control\n",
800                                  (controller->ucFanParameters &
801                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
802                         adev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
803                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
804                         DRM_INFO("Internal thermal controller %s fan control\n",
805                                  (controller->ucFanParameters &
806                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
807                         adev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
808                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
809                         DRM_INFO("Internal thermal controller %s fan control\n",
810                                  (controller->ucFanParameters &
811                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
812                         adev->pm.int_thermal_type = THERMAL_TYPE_NI;
813                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
814                         DRM_INFO("Internal thermal controller %s fan control\n",
815                                  (controller->ucFanParameters &
816                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
817                         adev->pm.int_thermal_type = THERMAL_TYPE_SI;
818                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
819                         DRM_INFO("Internal thermal controller %s fan control\n",
820                                  (controller->ucFanParameters &
821                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
822                         adev->pm.int_thermal_type = THERMAL_TYPE_CI;
823                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
824                         DRM_INFO("Internal thermal controller %s fan control\n",
825                                  (controller->ucFanParameters &
826                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
827                         adev->pm.int_thermal_type = THERMAL_TYPE_KV;
828                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {
829                         DRM_INFO("External GPIO thermal controller %s fan control\n",
830                                  (controller->ucFanParameters &
831                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
832                         adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;
833                 } else if (controller->ucType ==
834                            ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {
835                         DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",
836                                  (controller->ucFanParameters &
837                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
838                         adev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;
839                 } else if (controller->ucType ==
840                            ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
841                         DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",
842                                  (controller->ucFanParameters &
843                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
844                         adev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;
845                 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
846                         DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
847                                  pp_lib_thermal_controller_names[controller->ucType],
848                                  controller->ucI2cAddress >> 1,
849                                  (controller->ucFanParameters &
850                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
851                         adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;
852                         i2c_bus = amdgpu_atombios_lookup_i2c_gpio(adev, controller->ucI2cLine);
853                         adev->pm.i2c_bus = amdgpu_i2c_lookup(adev, &i2c_bus);
854                         if (adev->pm.i2c_bus) {
855                                 struct i2c_board_info info = { };
856                                 const char *name = pp_lib_thermal_controller_names[controller->ucType];
857                                 info.addr = controller->ucI2cAddress >> 1;
858                                 strlcpy(info.type, name, sizeof(info.type));
859                                 i2c_new_device(&adev->pm.i2c_bus->adapter, &info);
860                         }
861                 } else {
862                         DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
863                                  controller->ucType,
864                                  controller->ucI2cAddress >> 1,
865                                  (controller->ucFanParameters &
866                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
867                 }
868         }
869 }
870
871 enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev,
872                                                  u32 sys_mask,
873                                                  enum amdgpu_pcie_gen asic_gen,
874                                                  enum amdgpu_pcie_gen default_gen)
875 {
876         switch (asic_gen) {
877         case AMDGPU_PCIE_GEN1:
878                 return AMDGPU_PCIE_GEN1;
879         case AMDGPU_PCIE_GEN2:
880                 return AMDGPU_PCIE_GEN2;
881         case AMDGPU_PCIE_GEN3:
882                 return AMDGPU_PCIE_GEN3;
883         default:
884                 if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&
885                     (default_gen == AMDGPU_PCIE_GEN3))
886                         return AMDGPU_PCIE_GEN3;
887                 else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&
888                          (default_gen == AMDGPU_PCIE_GEN2))
889                         return AMDGPU_PCIE_GEN2;
890                 else
891                         return AMDGPU_PCIE_GEN1;
892         }
893         return AMDGPU_PCIE_GEN1;
894 }
895
896 struct amd_vce_state*
897 amdgpu_get_vce_clock_state(void *handle, u32 idx)
898 {
899         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
900
901         if (idx < adev->pm.dpm.num_of_vce_states)
902                 return &adev->pm.dpm.vce_states[idx];
903
904         return NULL;
905 }
906
907 int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
908 {
909         uint32_t clk_freq;
910         int ret = 0;
911         if (is_support_sw_smu(adev)) {
912                 ret = smu_get_dpm_freq_range(&adev->smu, SMU_GFXCLK,
913                                              low ? &clk_freq : NULL,
914                                              !low ? &clk_freq : NULL,
915                                              true);
916                 if (ret)
917                         return 0;
918                 return clk_freq * 100;
919
920         } else {
921                 return (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
922         }
923 }
924
925 int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
926 {
927         uint32_t clk_freq;
928         int ret = 0;
929         if (is_support_sw_smu(adev)) {
930                 ret = smu_get_dpm_freq_range(&adev->smu, SMU_UCLK,
931                                              low ? &clk_freq : NULL,
932                                              !low ? &clk_freq : NULL,
933                                              true);
934                 if (ret)
935                         return 0;
936                 return clk_freq * 100;
937
938         } else {
939                 return (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
940         }
941 }
942
943 int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
944 {
945         int ret = 0;
946         bool swsmu = is_support_sw_smu(adev);
947
948         switch (block_type) {
949         case AMD_IP_BLOCK_TYPE_UVD:
950         case AMD_IP_BLOCK_TYPE_VCE:
951                 if (swsmu) {
952                         ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
953                 } else if (adev->powerplay.pp_funcs &&
954                            adev->powerplay.pp_funcs->set_powergating_by_smu) {
955                         /*
956                          * TODO: need a better lock mechanism
957                          *
958                          * Here adev->pm.mutex lock protection is enforced on
959                          * UVD and VCE cases only. Since for other cases, there
960                          * may be already lock protection in amdgpu_pm.c.
961                          * This is a quick fix for the deadlock issue below.
962                          *     NFO: task ocltst:2028 blocked for more than 120 seconds.
963                          *     Tainted: G           OE     5.0.0-37-generic #40~18.04.1-Ubuntu
964                          *     echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
965                          *     cltst          D    0  2028   2026 0x00000000
966                          *     all Trace:
967                          *     __schedule+0x2c0/0x870
968                          *     schedule+0x2c/0x70
969                          *     schedule_preempt_disabled+0xe/0x10
970                          *     __mutex_lock.isra.9+0x26d/0x4e0
971                          *     __mutex_lock_slowpath+0x13/0x20
972                          *     ? __mutex_lock_slowpath+0x13/0x20
973                          *     mutex_lock+0x2f/0x40
974                          *     amdgpu_dpm_set_powergating_by_smu+0x64/0xe0 [amdgpu]
975                          *     gfx_v8_0_enable_gfx_static_mg_power_gating+0x3c/0x70 [amdgpu]
976                          *     gfx_v8_0_set_powergating_state+0x66/0x260 [amdgpu]
977                          *     amdgpu_device_ip_set_powergating_state+0x62/0xb0 [amdgpu]
978                          *     pp_dpm_force_performance_level+0xe7/0x100 [amdgpu]
979                          *     amdgpu_set_dpm_forced_performance_level+0x129/0x330 [amdgpu]
980                          */
981                         mutex_lock(&adev->pm.mutex);
982                         ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
983                                 (adev)->powerplay.pp_handle, block_type, gate));
984                         mutex_unlock(&adev->pm.mutex);
985                 }
986                 break;
987         case AMD_IP_BLOCK_TYPE_GFX:
988         case AMD_IP_BLOCK_TYPE_VCN:
989         case AMD_IP_BLOCK_TYPE_SDMA:
990                 if (swsmu)
991                         ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
992                 else if (adev->powerplay.pp_funcs &&
993                          adev->powerplay.pp_funcs->set_powergating_by_smu)
994                         ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
995                                 (adev)->powerplay.pp_handle, block_type, gate));
996                 break;
997         case AMD_IP_BLOCK_TYPE_JPEG:
998                 if (swsmu)
999                         ret = smu_dpm_set_power_gate(&adev->smu, block_type, gate);
1000                 break;
1001         case AMD_IP_BLOCK_TYPE_GMC:
1002         case AMD_IP_BLOCK_TYPE_ACP:
1003                 if (adev->powerplay.pp_funcs &&
1004                     adev->powerplay.pp_funcs->set_powergating_by_smu)
1005                         ret = ((adev)->powerplay.pp_funcs->set_powergating_by_smu(
1006                                 (adev)->powerplay.pp_handle, block_type, gate));
1007                 break;
1008         default:
1009                 break;
1010         }
1011
1012         return ret;
1013 }
1014
1015 int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
1016 {
1017         const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1018         void *pp_handle = adev->powerplay.pp_handle;
1019         struct smu_context *smu = &adev->smu;
1020         int ret = 0;
1021
1022         if (is_support_sw_smu(adev)) {
1023                 ret = smu_baco_enter(smu);
1024         } else {
1025                 if (!pp_funcs || !pp_funcs->set_asic_baco_state)
1026                         return -ENOENT;
1027
1028                 /* enter BACO state */
1029                 ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
1030         }
1031
1032         return ret;
1033 }
1034
1035 int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
1036 {
1037         const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1038         void *pp_handle = adev->powerplay.pp_handle;
1039         struct smu_context *smu = &adev->smu;
1040         int ret = 0;
1041
1042         if (is_support_sw_smu(adev)) {
1043                 ret = smu_baco_exit(smu);
1044         } else {
1045                 if (!pp_funcs || !pp_funcs->set_asic_baco_state)
1046                         return -ENOENT;
1047
1048                 /* exit BACO state */
1049                 ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
1050         }
1051
1052         return ret;
1053 }
1054
1055 int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
1056                              enum pp_mp1_state mp1_state)
1057 {
1058         int ret = 0;
1059
1060         if (is_support_sw_smu(adev)) {
1061                 ret = smu_set_mp1_state(&adev->smu, mp1_state);
1062         } else if (adev->powerplay.pp_funcs &&
1063                    adev->powerplay.pp_funcs->set_mp1_state) {
1064                 ret = adev->powerplay.pp_funcs->set_mp1_state(
1065                                 adev->powerplay.pp_handle,
1066                                 mp1_state);
1067         }
1068
1069         return ret;
1070 }
1071
1072 bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
1073 {
1074         const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1075         void *pp_handle = adev->powerplay.pp_handle;
1076         struct smu_context *smu = &adev->smu;
1077         bool baco_cap;
1078
1079         if (is_support_sw_smu(adev)) {
1080                 return smu_baco_is_support(smu);
1081         } else {
1082                 if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
1083                         return false;
1084
1085                 if (pp_funcs->get_asic_baco_capability(pp_handle, &baco_cap))
1086                         return false;
1087
1088                 return baco_cap ? true : false;
1089         }
1090 }
1091
1092 int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
1093 {
1094         const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1095         void *pp_handle = adev->powerplay.pp_handle;
1096         struct smu_context *smu = &adev->smu;
1097
1098         if (is_support_sw_smu(adev)) {
1099                 return smu_mode2_reset(smu);
1100         } else {
1101                 if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
1102                         return -ENOENT;
1103
1104                 return pp_funcs->asic_reset_mode_2(pp_handle);
1105         }
1106 }
1107
1108 int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
1109 {
1110         const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1111         void *pp_handle = adev->powerplay.pp_handle;
1112         struct smu_context *smu = &adev->smu;
1113         int ret = 0;
1114
1115         dev_info(adev->dev, "GPU BACO reset\n");
1116
1117         if (is_support_sw_smu(adev)) {
1118                 ret = smu_baco_enter(smu);
1119                 if (ret)
1120                         return ret;
1121
1122                 ret = smu_baco_exit(smu);
1123                 if (ret)
1124                         return ret;
1125         } else {
1126                 if (!pp_funcs
1127                     || !pp_funcs->set_asic_baco_state)
1128                         return -ENOENT;
1129
1130                 /* enter BACO state */
1131                 ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
1132                 if (ret)
1133                         return ret;
1134
1135                 /* exit BACO state */
1136                 ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
1137                 if (ret)
1138                         return ret;
1139         }
1140
1141         return 0;
1142 }
1143
1144 int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
1145                                     enum PP_SMC_POWER_PROFILE type,
1146                                     bool en)
1147 {
1148         int ret = 0;
1149
1150         if (is_support_sw_smu(adev))
1151                 ret = smu_switch_power_profile(&adev->smu, type, en);
1152         else if (adev->powerplay.pp_funcs &&
1153                  adev->powerplay.pp_funcs->switch_power_profile)
1154                 ret = adev->powerplay.pp_funcs->switch_power_profile(
1155                         adev->powerplay.pp_handle, type, en);
1156
1157         return ret;
1158 }
1159
1160 int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
1161                                uint32_t pstate)
1162 {
1163         int ret = 0;
1164
1165         if (is_support_sw_smu_xgmi(adev))
1166                 ret = smu_set_xgmi_pstate(&adev->smu, pstate);
1167         else if (adev->powerplay.pp_funcs &&
1168                  adev->powerplay.pp_funcs->set_xgmi_pstate)
1169                 ret = adev->powerplay.pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
1170                                                                 pstate);
1171
1172         return ret;
1173 }