drm/amdgpu: Add a new flag to AMDGPU_CTX_OP_QUERY_STATE2
[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 <drm/drmP.h>
26 #include "amdgpu.h"
27 #include "amdgpu_atombios.h"
28 #include "amdgpu_i2c.h"
29 #include "amdgpu_dpm.h"
30 #include "atom.h"
31 #include "amd_pcie.h"
32
33 void amdgpu_dpm_print_class_info(u32 class, u32 class2)
34 {
35         const char *s;
36
37         switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
38         case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
39         default:
40                 s = "none";
41                 break;
42         case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
43                 s = "battery";
44                 break;
45         case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
46                 s = "balanced";
47                 break;
48         case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
49                 s = "performance";
50                 break;
51         }
52         printk("\tui class: %s\n", s);
53         printk("\tinternal class:");
54         if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
55             (class2 == 0))
56                 pr_cont(" none");
57         else {
58                 if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
59                         pr_cont(" boot");
60                 if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
61                         pr_cont(" thermal");
62                 if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
63                         pr_cont(" limited_pwr");
64                 if (class & ATOM_PPLIB_CLASSIFICATION_REST)
65                         pr_cont(" rest");
66                 if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
67                         pr_cont(" forced");
68                 if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
69                         pr_cont(" 3d_perf");
70                 if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
71                         pr_cont(" ovrdrv");
72                 if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
73                         pr_cont(" uvd");
74                 if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
75                         pr_cont(" 3d_low");
76                 if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
77                         pr_cont(" acpi");
78                 if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
79                         pr_cont(" uvd_hd2");
80                 if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
81                         pr_cont(" uvd_hd");
82                 if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
83                         pr_cont(" uvd_sd");
84                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
85                         pr_cont(" limited_pwr2");
86                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
87                         pr_cont(" ulv");
88                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
89                         pr_cont(" uvd_mvc");
90         }
91         pr_cont("\n");
92 }
93
94 void amdgpu_dpm_print_cap_info(u32 caps)
95 {
96         printk("\tcaps:");
97         if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
98                 pr_cont(" single_disp");
99         if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
100                 pr_cont(" video");
101         if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
102                 pr_cont(" no_dc");
103         pr_cont("\n");
104 }
105
106 void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
107                                 struct amdgpu_ps *rps)
108 {
109         printk("\tstatus:");
110         if (rps == adev->pm.dpm.current_ps)
111                 pr_cont(" c");
112         if (rps == adev->pm.dpm.requested_ps)
113                 pr_cont(" r");
114         if (rps == adev->pm.dpm.boot_ps)
115                 pr_cont(" b");
116         pr_cont("\n");
117 }
118
119 void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
120 {
121         struct drm_device *ddev = adev->ddev;
122         struct drm_crtc *crtc;
123         struct amdgpu_crtc *amdgpu_crtc;
124
125         adev->pm.dpm.new_active_crtcs = 0;
126         adev->pm.dpm.new_active_crtc_count = 0;
127         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
128                 list_for_each_entry(crtc,
129                                     &ddev->mode_config.crtc_list, head) {
130                         amdgpu_crtc = to_amdgpu_crtc(crtc);
131                         if (amdgpu_crtc->enabled) {
132                                 adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
133                                 adev->pm.dpm.new_active_crtc_count++;
134                         }
135                 }
136         }
137 }
138
139
140 u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
141 {
142         struct drm_device *dev = adev->ddev;
143         struct drm_crtc *crtc;
144         struct amdgpu_crtc *amdgpu_crtc;
145         u32 vblank_in_pixels;
146         u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
147
148         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
149                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
150                         amdgpu_crtc = to_amdgpu_crtc(crtc);
151                         if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
152                                 vblank_in_pixels =
153                                         amdgpu_crtc->hw_mode.crtc_htotal *
154                                         (amdgpu_crtc->hw_mode.crtc_vblank_end -
155                                         amdgpu_crtc->hw_mode.crtc_vdisplay +
156                                         (amdgpu_crtc->v_border * 2));
157
158                                 vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
159                                 break;
160                         }
161                 }
162         }
163
164         return vblank_time_us;
165 }
166
167 u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
168 {
169         struct drm_device *dev = adev->ddev;
170         struct drm_crtc *crtc;
171         struct amdgpu_crtc *amdgpu_crtc;
172         u32 vrefresh = 0;
173
174         if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
175                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
176                         amdgpu_crtc = to_amdgpu_crtc(crtc);
177                         if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
178                                 vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
179                                 break;
180                         }
181                 }
182         }
183
184         return vrefresh;
185 }
186
187 bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor)
188 {
189         switch (sensor) {
190         case THERMAL_TYPE_RV6XX:
191         case THERMAL_TYPE_RV770:
192         case THERMAL_TYPE_EVERGREEN:
193         case THERMAL_TYPE_SUMO:
194         case THERMAL_TYPE_NI:
195         case THERMAL_TYPE_SI:
196         case THERMAL_TYPE_CI:
197         case THERMAL_TYPE_KV:
198                 return true;
199         case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
200         case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
201                 return false; /* need special handling */
202         case THERMAL_TYPE_NONE:
203         case THERMAL_TYPE_EXTERNAL:
204         case THERMAL_TYPE_EXTERNAL_GPIO:
205         default:
206                 return false;
207         }
208 }
209
210 union power_info {
211         struct _ATOM_POWERPLAY_INFO info;
212         struct _ATOM_POWERPLAY_INFO_V2 info_2;
213         struct _ATOM_POWERPLAY_INFO_V3 info_3;
214         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
215         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
216         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
217         struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
218         struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
219 };
220
221 union fan_info {
222         struct _ATOM_PPLIB_FANTABLE fan;
223         struct _ATOM_PPLIB_FANTABLE2 fan2;
224         struct _ATOM_PPLIB_FANTABLE3 fan3;
225 };
226
227 static int amdgpu_parse_clk_voltage_dep_table(struct amdgpu_clock_voltage_dependency_table *amdgpu_table,
228                                               ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
229 {
230         u32 size = atom_table->ucNumEntries *
231                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
232         int i;
233         ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry;
234
235         amdgpu_table->entries = kzalloc(size, GFP_KERNEL);
236         if (!amdgpu_table->entries)
237                 return -ENOMEM;
238
239         entry = &atom_table->entries[0];
240         for (i = 0; i < atom_table->ucNumEntries; i++) {
241                 amdgpu_table->entries[i].clk = le16_to_cpu(entry->usClockLow) |
242                         (entry->ucClockHigh << 16);
243                 amdgpu_table->entries[i].v = le16_to_cpu(entry->usVoltage);
244                 entry = (ATOM_PPLIB_Clock_Voltage_Dependency_Record *)
245                         ((u8 *)entry + sizeof(ATOM_PPLIB_Clock_Voltage_Dependency_Record));
246         }
247         amdgpu_table->count = atom_table->ucNumEntries;
248
249         return 0;
250 }
251
252 int amdgpu_get_platform_caps(struct amdgpu_device *adev)
253 {
254         struct amdgpu_mode_info *mode_info = &adev->mode_info;
255         union power_info *power_info;
256         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
257         u16 data_offset;
258         u8 frev, crev;
259
260         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
261                                    &frev, &crev, &data_offset))
262                 return -EINVAL;
263         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
264
265         adev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
266         adev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
267         adev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
268
269         return 0;
270 }
271
272 /* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
273 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
274 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
275 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
276 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
277 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
278 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
279 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8 24
280 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V9 26
281
282 int amdgpu_parse_extended_power_table(struct amdgpu_device *adev)
283 {
284         struct amdgpu_mode_info *mode_info = &adev->mode_info;
285         union power_info *power_info;
286         union fan_info *fan_info;
287         ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
288         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
289         u16 data_offset;
290         u8 frev, crev;
291         int ret, i;
292
293         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
294                                    &frev, &crev, &data_offset))
295                 return -EINVAL;
296         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
297
298         /* fan table */
299         if (le16_to_cpu(power_info->pplib.usTableSize) >=
300             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
301                 if (power_info->pplib3.usFanTableOffset) {
302                         fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
303                                                       le16_to_cpu(power_info->pplib3.usFanTableOffset));
304                         adev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
305                         adev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
306                         adev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
307                         adev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
308                         adev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
309                         adev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
310                         adev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
311                         if (fan_info->fan.ucFanTableFormat >= 2)
312                                 adev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
313                         else
314                                 adev->pm.dpm.fan.t_max = 10900;
315                         adev->pm.dpm.fan.cycle_delay = 100000;
316                         if (fan_info->fan.ucFanTableFormat >= 3) {
317                                 adev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
318                                 adev->pm.dpm.fan.default_max_fan_pwm =
319                                         le16_to_cpu(fan_info->fan3.usFanPWMMax);
320                                 adev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
321                                 adev->pm.dpm.fan.fan_output_sensitivity =
322                                         le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
323                         }
324                         adev->pm.dpm.fan.ucode_fan_control = true;
325                 }
326         }
327
328         /* clock dependancy tables, shedding tables */
329         if (le16_to_cpu(power_info->pplib.usTableSize) >=
330             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
331                 if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
332                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
333                                 (mode_info->atom_context->bios + data_offset +
334                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
335                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
336                                                                  dep_table);
337                         if (ret) {
338                                 amdgpu_free_extended_power_table(adev);
339                                 return ret;
340                         }
341                 }
342                 if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
343                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
344                                 (mode_info->atom_context->bios + data_offset +
345                                  le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
346                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
347                                                                  dep_table);
348                         if (ret) {
349                                 amdgpu_free_extended_power_table(adev);
350                                 return ret;
351                         }
352                 }
353                 if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
354                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
355                                 (mode_info->atom_context->bios + data_offset +
356                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
357                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
358                                                                  dep_table);
359                         if (ret) {
360                                 amdgpu_free_extended_power_table(adev);
361                                 return ret;
362                         }
363                 }
364                 if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
365                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
366                                 (mode_info->atom_context->bios + data_offset +
367                                  le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
368                         ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
369                                                                  dep_table);
370                         if (ret) {
371                                 amdgpu_free_extended_power_table(adev);
372                                 return ret;
373                         }
374                 }
375                 if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
376                         ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
377                                 (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
378                                 (mode_info->atom_context->bios + data_offset +
379                                  le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
380                         if (clk_v->ucNumEntries) {
381                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
382                                         le16_to_cpu(clk_v->entries[0].usSclkLow) |
383                                         (clk_v->entries[0].ucSclkHigh << 16);
384                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
385                                         le16_to_cpu(clk_v->entries[0].usMclkLow) |
386                                         (clk_v->entries[0].ucMclkHigh << 16);
387                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
388                                         le16_to_cpu(clk_v->entries[0].usVddc);
389                                 adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
390                                         le16_to_cpu(clk_v->entries[0].usVddci);
391                         }
392                 }
393                 if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
394                         ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
395                                 (ATOM_PPLIB_PhaseSheddingLimits_Table *)
396                                 (mode_info->atom_context->bios + data_offset +
397                                  le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
398                         ATOM_PPLIB_PhaseSheddingLimits_Record *entry;
399
400                         adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
401                                 kcalloc(psl->ucNumEntries,
402                                         sizeof(struct amdgpu_phase_shedding_limits_entry),
403                                         GFP_KERNEL);
404                         if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
405                                 amdgpu_free_extended_power_table(adev);
406                                 return -ENOMEM;
407                         }
408
409                         entry = &psl->entries[0];
410                         for (i = 0; i < psl->ucNumEntries; i++) {
411                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
412                                         le16_to_cpu(entry->usSclkLow) | (entry->ucSclkHigh << 16);
413                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
414                                         le16_to_cpu(entry->usMclkLow) | (entry->ucMclkHigh << 16);
415                                 adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
416                                         le16_to_cpu(entry->usVoltage);
417                                 entry = (ATOM_PPLIB_PhaseSheddingLimits_Record *)
418                                         ((u8 *)entry + sizeof(ATOM_PPLIB_PhaseSheddingLimits_Record));
419                         }
420                         adev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
421                                 psl->ucNumEntries;
422                 }
423         }
424
425         /* cac data */
426         if (le16_to_cpu(power_info->pplib.usTableSize) >=
427             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
428                 adev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
429                 adev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
430                 adev->pm.dpm.near_tdp_limit_adjusted = adev->pm.dpm.near_tdp_limit;
431                 adev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
432                 if (adev->pm.dpm.tdp_od_limit)
433                         adev->pm.dpm.power_control = true;
434                 else
435                         adev->pm.dpm.power_control = false;
436                 adev->pm.dpm.tdp_adjustment = 0;
437                 adev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
438                 adev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
439                 adev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
440                 if (power_info->pplib5.usCACLeakageTableOffset) {
441                         ATOM_PPLIB_CAC_Leakage_Table *cac_table =
442                                 (ATOM_PPLIB_CAC_Leakage_Table *)
443                                 (mode_info->atom_context->bios + data_offset +
444                                  le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
445                         ATOM_PPLIB_CAC_Leakage_Record *entry;
446                         u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table);
447                         adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
448                         if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) {
449                                 amdgpu_free_extended_power_table(adev);
450                                 return -ENOMEM;
451                         }
452                         entry = &cac_table->entries[0];
453                         for (i = 0; i < cac_table->ucNumEntries; i++) {
454                                 if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
455                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc1 =
456                                                 le16_to_cpu(entry->usVddc1);
457                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc2 =
458                                                 le16_to_cpu(entry->usVddc2);
459                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc3 =
460                                                 le16_to_cpu(entry->usVddc3);
461                                 } else {
462                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
463                                                 le16_to_cpu(entry->usVddc);
464                                         adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
465                                                 le32_to_cpu(entry->ulLeakageValue);
466                                 }
467                                 entry = (ATOM_PPLIB_CAC_Leakage_Record *)
468                                         ((u8 *)entry + sizeof(ATOM_PPLIB_CAC_Leakage_Record));
469                         }
470                         adev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
471                 }
472         }
473
474         /* ext tables */
475         if (le16_to_cpu(power_info->pplib.usTableSize) >=
476             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
477                 ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
478                         (mode_info->atom_context->bios + data_offset +
479                          le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
480                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2) &&
481                         ext_hdr->usVCETableOffset) {
482                         VCEClockInfoArray *array = (VCEClockInfoArray *)
483                                 (mode_info->atom_context->bios + data_offset +
484                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1);
485                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *limits =
486                                 (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
487                                 (mode_info->atom_context->bios + data_offset +
488                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
489                                  1 + array->ucNumEntries * sizeof(VCEClockInfo));
490                         ATOM_PPLIB_VCE_State_Table *states =
491                                 (ATOM_PPLIB_VCE_State_Table *)
492                                 (mode_info->atom_context->bios + data_offset +
493                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
494                                  1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
495                                  1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
496                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
497                         ATOM_PPLIB_VCE_State_Record *state_entry;
498                         VCEClockInfo *vce_clk;
499                         u32 size = limits->numEntries *
500                                 sizeof(struct amdgpu_vce_clock_voltage_dependency_entry);
501                         adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
502                                 kzalloc(size, GFP_KERNEL);
503                         if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) {
504                                 amdgpu_free_extended_power_table(adev);
505                                 return -ENOMEM;
506                         }
507                         adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
508                                 limits->numEntries;
509                         entry = &limits->entries[0];
510                         state_entry = &states->entries[0];
511                         for (i = 0; i < limits->numEntries; i++) {
512                                 vce_clk = (VCEClockInfo *)
513                                         ((u8 *)&array->entries[0] +
514                                          (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
515                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
516                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
517                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].ecclk =
518                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
519                                 adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].v =
520                                         le16_to_cpu(entry->usVoltage);
521                                 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
522                                         ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
523                         }
524                         adev->pm.dpm.num_of_vce_states =
525                                         states->numEntries > AMD_MAX_VCE_LEVELS ?
526                                         AMD_MAX_VCE_LEVELS : states->numEntries;
527                         for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
528                                 vce_clk = (VCEClockInfo *)
529                                         ((u8 *)&array->entries[0] +
530                                          (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
531                                 adev->pm.dpm.vce_states[i].evclk =
532                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
533                                 adev->pm.dpm.vce_states[i].ecclk =
534                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
535                                 adev->pm.dpm.vce_states[i].clk_idx =
536                                         state_entry->ucClockInfoIndex & 0x3f;
537                                 adev->pm.dpm.vce_states[i].pstate =
538                                         (state_entry->ucClockInfoIndex & 0xc0) >> 6;
539                                 state_entry = (ATOM_PPLIB_VCE_State_Record *)
540                                         ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
541                         }
542                 }
543                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
544                         ext_hdr->usUVDTableOffset) {
545                         UVDClockInfoArray *array = (UVDClockInfoArray *)
546                                 (mode_info->atom_context->bios + data_offset +
547                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1);
548                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *limits =
549                                 (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
550                                 (mode_info->atom_context->bios + data_offset +
551                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1 +
552                                  1 + (array->ucNumEntries * sizeof (UVDClockInfo)));
553                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *entry;
554                         u32 size = limits->numEntries *
555                                 sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry);
556                         adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries =
557                                 kzalloc(size, GFP_KERNEL);
558                         if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) {
559                                 amdgpu_free_extended_power_table(adev);
560                                 return -ENOMEM;
561                         }
562                         adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count =
563                                 limits->numEntries;
564                         entry = &limits->entries[0];
565                         for (i = 0; i < limits->numEntries; i++) {
566                                 UVDClockInfo *uvd_clk = (UVDClockInfo *)
567                                         ((u8 *)&array->entries[0] +
568                                          (entry->ucUVDClockInfoIndex * sizeof(UVDClockInfo)));
569                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].vclk =
570                                         le16_to_cpu(uvd_clk->usVClkLow) | (uvd_clk->ucVClkHigh << 16);
571                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk =
572                                         le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16);
573                                 adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v =
574                                         le16_to_cpu(entry->usVoltage);
575                                 entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *)
576                                         ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record));
577                         }
578                 }
579                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4) &&
580                         ext_hdr->usSAMUTableOffset) {
581                         ATOM_PPLIB_SAMClk_Voltage_Limit_Table *limits =
582                                 (ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
583                                 (mode_info->atom_context->bios + data_offset +
584                                  le16_to_cpu(ext_hdr->usSAMUTableOffset) + 1);
585                         ATOM_PPLIB_SAMClk_Voltage_Limit_Record *entry;
586                         u32 size = limits->numEntries *
587                                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
588                         adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries =
589                                 kzalloc(size, GFP_KERNEL);
590                         if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) {
591                                 amdgpu_free_extended_power_table(adev);
592                                 return -ENOMEM;
593                         }
594                         adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count =
595                                 limits->numEntries;
596                         entry = &limits->entries[0];
597                         for (i = 0; i < limits->numEntries; i++) {
598                                 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].clk =
599                                         le16_to_cpu(entry->usSAMClockLow) | (entry->ucSAMClockHigh << 16);
600                                 adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].v =
601                                         le16_to_cpu(entry->usVoltage);
602                                 entry = (ATOM_PPLIB_SAMClk_Voltage_Limit_Record *)
603                                         ((u8 *)entry + sizeof(ATOM_PPLIB_SAMClk_Voltage_Limit_Record));
604                         }
605                 }
606                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
607                     ext_hdr->usPPMTableOffset) {
608                         ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
609                                 (mode_info->atom_context->bios + data_offset +
610                                  le16_to_cpu(ext_hdr->usPPMTableOffset));
611                         adev->pm.dpm.dyn_state.ppm_table =
612                                 kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL);
613                         if (!adev->pm.dpm.dyn_state.ppm_table) {
614                                 amdgpu_free_extended_power_table(adev);
615                                 return -ENOMEM;
616                         }
617                         adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
618                         adev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
619                                 le16_to_cpu(ppm->usCpuCoreNumber);
620                         adev->pm.dpm.dyn_state.ppm_table->platform_tdp =
621                                 le32_to_cpu(ppm->ulPlatformTDP);
622                         adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
623                                 le32_to_cpu(ppm->ulSmallACPlatformTDP);
624                         adev->pm.dpm.dyn_state.ppm_table->platform_tdc =
625                                 le32_to_cpu(ppm->ulPlatformTDC);
626                         adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
627                                 le32_to_cpu(ppm->ulSmallACPlatformTDC);
628                         adev->pm.dpm.dyn_state.ppm_table->apu_tdp =
629                                 le32_to_cpu(ppm->ulApuTDP);
630                         adev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
631                                 le32_to_cpu(ppm->ulDGpuTDP);
632                         adev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
633                                 le32_to_cpu(ppm->ulDGpuUlvPower);
634                         adev->pm.dpm.dyn_state.ppm_table->tj_max =
635                                 le32_to_cpu(ppm->ulTjmax);
636                 }
637                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6) &&
638                         ext_hdr->usACPTableOffset) {
639                         ATOM_PPLIB_ACPClk_Voltage_Limit_Table *limits =
640                                 (ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
641                                 (mode_info->atom_context->bios + data_offset +
642                                  le16_to_cpu(ext_hdr->usACPTableOffset) + 1);
643                         ATOM_PPLIB_ACPClk_Voltage_Limit_Record *entry;
644                         u32 size = limits->numEntries *
645                                 sizeof(struct amdgpu_clock_voltage_dependency_entry);
646                         adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries =
647                                 kzalloc(size, GFP_KERNEL);
648                         if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) {
649                                 amdgpu_free_extended_power_table(adev);
650                                 return -ENOMEM;
651                         }
652                         adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count =
653                                 limits->numEntries;
654                         entry = &limits->entries[0];
655                         for (i = 0; i < limits->numEntries; i++) {
656                                 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].clk =
657                                         le16_to_cpu(entry->usACPClockLow) | (entry->ucACPClockHigh << 16);
658                                 adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].v =
659                                         le16_to_cpu(entry->usVoltage);
660                                 entry = (ATOM_PPLIB_ACPClk_Voltage_Limit_Record *)
661                                         ((u8 *)entry + sizeof(ATOM_PPLIB_ACPClk_Voltage_Limit_Record));
662                         }
663                 }
664                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) &&
665                         ext_hdr->usPowerTuneTableOffset) {
666                         u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset +
667                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
668                         ATOM_PowerTune_Table *pt;
669                         adev->pm.dpm.dyn_state.cac_tdp_table =
670                                 kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL);
671                         if (!adev->pm.dpm.dyn_state.cac_tdp_table) {
672                                 amdgpu_free_extended_power_table(adev);
673                                 return -ENOMEM;
674                         }
675                         if (rev > 0) {
676                                 ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *)
677                                         (mode_info->atom_context->bios + data_offset +
678                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
679                                 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
680                                         ppt->usMaximumPowerDeliveryLimit;
681                                 pt = &ppt->power_tune_table;
682                         } else {
683                                 ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
684                                         (mode_info->atom_context->bios + data_offset +
685                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
686                                 adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255;
687                                 pt = &ppt->power_tune_table;
688                         }
689                         adev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP);
690                         adev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp =
691                                 le16_to_cpu(pt->usConfigurableTDP);
692                         adev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC);
693                         adev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit =
694                                 le16_to_cpu(pt->usBatteryPowerLimit);
695                         adev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit =
696                                 le16_to_cpu(pt->usSmallPowerLimit);
697                         adev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage =
698                                 le16_to_cpu(pt->usLowCACLeakage);
699                         adev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage =
700                                 le16_to_cpu(pt->usHighCACLeakage);
701                 }
702                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8) &&
703                                 ext_hdr->usSclkVddgfxTableOffset) {
704                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
705                                 (mode_info->atom_context->bios + data_offset +
706                                  le16_to_cpu(ext_hdr->usSclkVddgfxTableOffset));
707                         ret = amdgpu_parse_clk_voltage_dep_table(
708                                         &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk,
709                                         dep_table);
710                         if (ret) {
711                                 kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries);
712                                 return ret;
713                         }
714                 }
715         }
716
717         return 0;
718 }
719
720 void amdgpu_free_extended_power_table(struct amdgpu_device *adev)
721 {
722         struct amdgpu_dpm_dynamic_state *dyn_state = &adev->pm.dpm.dyn_state;
723
724         kfree(dyn_state->vddc_dependency_on_sclk.entries);
725         kfree(dyn_state->vddci_dependency_on_mclk.entries);
726         kfree(dyn_state->vddc_dependency_on_mclk.entries);
727         kfree(dyn_state->mvdd_dependency_on_mclk.entries);
728         kfree(dyn_state->cac_leakage_table.entries);
729         kfree(dyn_state->phase_shedding_limits_table.entries);
730         kfree(dyn_state->ppm_table);
731         kfree(dyn_state->cac_tdp_table);
732         kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
733         kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
734         kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
735         kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
736         kfree(dyn_state->vddgfx_dependency_on_sclk.entries);
737 }
738
739 static const char *pp_lib_thermal_controller_names[] = {
740         "NONE",
741         "lm63",
742         "adm1032",
743         "adm1030",
744         "max6649",
745         "lm64",
746         "f75375",
747         "RV6xx",
748         "RV770",
749         "adt7473",
750         "NONE",
751         "External GPIO",
752         "Evergreen",
753         "emc2103",
754         "Sumo",
755         "Northern Islands",
756         "Southern Islands",
757         "lm96163",
758         "Sea Islands",
759         "Kaveri/Kabini",
760 };
761
762 void amdgpu_add_thermal_controller(struct amdgpu_device *adev)
763 {
764         struct amdgpu_mode_info *mode_info = &adev->mode_info;
765         ATOM_PPLIB_POWERPLAYTABLE *power_table;
766         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
767         ATOM_PPLIB_THERMALCONTROLLER *controller;
768         struct amdgpu_i2c_bus_rec i2c_bus;
769         u16 data_offset;
770         u8 frev, crev;
771
772         if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
773                                    &frev, &crev, &data_offset))
774                 return;
775         power_table = (ATOM_PPLIB_POWERPLAYTABLE *)
776                 (mode_info->atom_context->bios + data_offset);
777         controller = &power_table->sThermalController;
778
779         /* add the i2c bus for thermal/fan chip */
780         if (controller->ucType > 0) {
781                 if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
782                         adev->pm.no_fan = true;
783                 adev->pm.fan_pulses_per_revolution =
784                         controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
785                 if (adev->pm.fan_pulses_per_revolution) {
786                         adev->pm.fan_min_rpm = controller->ucFanMinRPM;
787                         adev->pm.fan_max_rpm = controller->ucFanMaxRPM;
788                 }
789                 if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
790                         DRM_INFO("Internal thermal controller %s fan control\n",
791                                  (controller->ucFanParameters &
792                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
793                         adev->pm.int_thermal_type = THERMAL_TYPE_RV6XX;
794                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
795                         DRM_INFO("Internal thermal controller %s fan control\n",
796                                  (controller->ucFanParameters &
797                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
798                         adev->pm.int_thermal_type = THERMAL_TYPE_RV770;
799                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
800                         DRM_INFO("Internal thermal controller %s fan control\n",
801                                  (controller->ucFanParameters &
802                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
803                         adev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN;
804                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
805                         DRM_INFO("Internal thermal controller %s fan control\n",
806                                  (controller->ucFanParameters &
807                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
808                         adev->pm.int_thermal_type = THERMAL_TYPE_SUMO;
809                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
810                         DRM_INFO("Internal thermal controller %s fan control\n",
811                                  (controller->ucFanParameters &
812                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
813                         adev->pm.int_thermal_type = THERMAL_TYPE_NI;
814                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
815                         DRM_INFO("Internal thermal controller %s fan control\n",
816                                  (controller->ucFanParameters &
817                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
818                         adev->pm.int_thermal_type = THERMAL_TYPE_SI;
819                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
820                         DRM_INFO("Internal thermal controller %s fan control\n",
821                                  (controller->ucFanParameters &
822                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
823                         adev->pm.int_thermal_type = THERMAL_TYPE_CI;
824                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
825                         DRM_INFO("Internal thermal controller %s fan control\n",
826                                  (controller->ucFanParameters &
827                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
828                         adev->pm.int_thermal_type = THERMAL_TYPE_KV;
829                 } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {
830                         DRM_INFO("External GPIO thermal controller %s fan control\n",
831                                  (controller->ucFanParameters &
832                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
833                         adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;
834                 } else if (controller->ucType ==
835                            ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {
836                         DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",
837                                  (controller->ucFanParameters &
838                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
839                         adev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;
840                 } else if (controller->ucType ==
841                            ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
842                         DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",
843                                  (controller->ucFanParameters &
844                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
845                         adev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;
846                 } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
847                         DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
848                                  pp_lib_thermal_controller_names[controller->ucType],
849                                  controller->ucI2cAddress >> 1,
850                                  (controller->ucFanParameters &
851                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
852                         adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;
853                         i2c_bus = amdgpu_atombios_lookup_i2c_gpio(adev, controller->ucI2cLine);
854                         adev->pm.i2c_bus = amdgpu_i2c_lookup(adev, &i2c_bus);
855                         if (adev->pm.i2c_bus) {
856                                 struct i2c_board_info info = { };
857                                 const char *name = pp_lib_thermal_controller_names[controller->ucType];
858                                 info.addr = controller->ucI2cAddress >> 1;
859                                 strlcpy(info.type, name, sizeof(info.type));
860                                 i2c_new_device(&adev->pm.i2c_bus->adapter, &info);
861                         }
862                 } else {
863                         DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
864                                  controller->ucType,
865                                  controller->ucI2cAddress >> 1,
866                                  (controller->ucFanParameters &
867                                   ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
868                 }
869         }
870 }
871
872 enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev,
873                                                  u32 sys_mask,
874                                                  enum amdgpu_pcie_gen asic_gen,
875                                                  enum amdgpu_pcie_gen default_gen)
876 {
877         switch (asic_gen) {
878         case AMDGPU_PCIE_GEN1:
879                 return AMDGPU_PCIE_GEN1;
880         case AMDGPU_PCIE_GEN2:
881                 return AMDGPU_PCIE_GEN2;
882         case AMDGPU_PCIE_GEN3:
883                 return AMDGPU_PCIE_GEN3;
884         default:
885                 if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&
886                     (default_gen == AMDGPU_PCIE_GEN3))
887                         return AMDGPU_PCIE_GEN3;
888                 else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&
889                          (default_gen == AMDGPU_PCIE_GEN2))
890                         return AMDGPU_PCIE_GEN2;
891                 else
892                         return AMDGPU_PCIE_GEN1;
893         }
894         return AMDGPU_PCIE_GEN1;
895 }
896
897 struct amd_vce_state*
898 amdgpu_get_vce_clock_state(void *handle, u32 idx)
899 {
900         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
901
902         if (idx < adev->pm.dpm.num_of_vce_states)
903                 return &adev->pm.dpm.vce_states[idx];
904
905         return NULL;
906 }
907
908 int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
909 {
910         if (is_support_sw_smu(adev))
911                 return smu_get_sclk(&adev->smu, low);
912         else
913                 return (adev)->powerplay.pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
914 }
915
916 int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
917 {
918         if (is_support_sw_smu(adev))
919                 return smu_get_mclk(&adev->smu, low);
920         else
921                 return (adev)->powerplay.pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
922 }