linux/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
<<
>>
Prefs
   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#include "amdgpu_display.h"
  32#include "hwmgr.h"
  33#include <linux/power_supply.h>
  34
  35#define WIDTH_4K 3840
  36
  37void amdgpu_dpm_print_class_info(u32 class, u32 class2)
  38{
  39        const char *s;
  40
  41        switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
  42        case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
  43        default:
  44                s = "none";
  45                break;
  46        case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
  47                s = "battery";
  48                break;
  49        case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
  50                s = "balanced";
  51                break;
  52        case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
  53                s = "performance";
  54                break;
  55        }
  56        printk("\tui class: %s\n", s);
  57        printk("\tinternal class:");
  58        if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
  59            (class2 == 0))
  60                pr_cont(" none");
  61        else {
  62                if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
  63                        pr_cont(" boot");
  64                if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
  65                        pr_cont(" thermal");
  66                if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
  67                        pr_cont(" limited_pwr");
  68                if (class & ATOM_PPLIB_CLASSIFICATION_REST)
  69                        pr_cont(" rest");
  70                if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
  71                        pr_cont(" forced");
  72                if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
  73                        pr_cont(" 3d_perf");
  74                if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
  75                        pr_cont(" ovrdrv");
  76                if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
  77                        pr_cont(" uvd");
  78                if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
  79                        pr_cont(" 3d_low");
  80                if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
  81                        pr_cont(" acpi");
  82                if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
  83                        pr_cont(" uvd_hd2");
  84                if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
  85                        pr_cont(" uvd_hd");
  86                if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
  87                        pr_cont(" uvd_sd");
  88                if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
  89                        pr_cont(" limited_pwr2");
  90                if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
  91                        pr_cont(" ulv");
  92                if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
  93                        pr_cont(" uvd_mvc");
  94        }
  95        pr_cont("\n");
  96}
  97
  98void amdgpu_dpm_print_cap_info(u32 caps)
  99{
 100        printk("\tcaps:");
 101        if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
 102                pr_cont(" single_disp");
 103        if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
 104                pr_cont(" video");
 105        if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
 106                pr_cont(" no_dc");
 107        pr_cont("\n");
 108}
 109
 110void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
 111                                struct amdgpu_ps *rps)
 112{
 113        printk("\tstatus:");
 114        if (rps == adev->pm.dpm.current_ps)
 115                pr_cont(" c");
 116        if (rps == adev->pm.dpm.requested_ps)
 117                pr_cont(" r");
 118        if (rps == adev->pm.dpm.boot_ps)
 119                pr_cont(" b");
 120        pr_cont("\n");
 121}
 122
 123void amdgpu_dpm_get_active_displays(struct amdgpu_device *adev)
 124{
 125        struct drm_device *ddev = adev_to_drm(adev);
 126        struct drm_crtc *crtc;
 127        struct amdgpu_crtc *amdgpu_crtc;
 128
 129        adev->pm.dpm.new_active_crtcs = 0;
 130        adev->pm.dpm.new_active_crtc_count = 0;
 131        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 132                list_for_each_entry(crtc,
 133                                    &ddev->mode_config.crtc_list, head) {
 134                        amdgpu_crtc = to_amdgpu_crtc(crtc);
 135                        if (amdgpu_crtc->enabled) {
 136                                adev->pm.dpm.new_active_crtcs |= (1 << amdgpu_crtc->crtc_id);
 137                                adev->pm.dpm.new_active_crtc_count++;
 138                        }
 139                }
 140        }
 141}
 142
 143
 144u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
 145{
 146        struct drm_device *dev = adev_to_drm(adev);
 147        struct drm_crtc *crtc;
 148        struct amdgpu_crtc *amdgpu_crtc;
 149        u32 vblank_in_pixels;
 150        u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 151
 152        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 153                list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 154                        amdgpu_crtc = to_amdgpu_crtc(crtc);
 155                        if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
 156                                vblank_in_pixels =
 157                                        amdgpu_crtc->hw_mode.crtc_htotal *
 158                                        (amdgpu_crtc->hw_mode.crtc_vblank_end -
 159                                        amdgpu_crtc->hw_mode.crtc_vdisplay +
 160                                        (amdgpu_crtc->v_border * 2));
 161
 162                                vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
 163                                break;
 164                        }
 165                }
 166        }
 167
 168        return vblank_time_us;
 169}
 170
 171u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
 172{
 173        struct drm_device *dev = adev_to_drm(adev);
 174        struct drm_crtc *crtc;
 175        struct amdgpu_crtc *amdgpu_crtc;
 176        u32 vrefresh = 0;
 177
 178        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 179                list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 180                        amdgpu_crtc = to_amdgpu_crtc(crtc);
 181                        if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
 182                                vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
 183                                break;
 184                        }
 185                }
 186        }
 187
 188        return vrefresh;
 189}
 190
 191bool amdgpu_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor)
 192{
 193        switch (sensor) {
 194        case THERMAL_TYPE_RV6XX:
 195        case THERMAL_TYPE_RV770:
 196        case THERMAL_TYPE_EVERGREEN:
 197        case THERMAL_TYPE_SUMO:
 198        case THERMAL_TYPE_NI:
 199        case THERMAL_TYPE_SI:
 200        case THERMAL_TYPE_CI:
 201        case THERMAL_TYPE_KV:
 202                return true;
 203        case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
 204        case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
 205                return false; /* need special handling */
 206        case THERMAL_TYPE_NONE:
 207        case THERMAL_TYPE_EXTERNAL:
 208        case THERMAL_TYPE_EXTERNAL_GPIO:
 209        default:
 210                return false;
 211        }
 212}
 213
 214union power_info {
 215        struct _ATOM_POWERPLAY_INFO info;
 216        struct _ATOM_POWERPLAY_INFO_V2 info_2;
 217        struct _ATOM_POWERPLAY_INFO_V3 info_3;
 218        struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
 219        struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
 220        struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
 221        struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
 222        struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
 223};
 224
 225union fan_info {
 226        struct _ATOM_PPLIB_FANTABLE fan;
 227        struct _ATOM_PPLIB_FANTABLE2 fan2;
 228        struct _ATOM_PPLIB_FANTABLE3 fan3;
 229};
 230
 231static int amdgpu_parse_clk_voltage_dep_table(struct amdgpu_clock_voltage_dependency_table *amdgpu_table,
 232                                              ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
 233{
 234        u32 size = atom_table->ucNumEntries *
 235                sizeof(struct amdgpu_clock_voltage_dependency_entry);
 236        int i;
 237        ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry;
 238
 239        amdgpu_table->entries = kzalloc(size, GFP_KERNEL);
 240        if (!amdgpu_table->entries)
 241                return -ENOMEM;
 242
 243        entry = &atom_table->entries[0];
 244        for (i = 0; i < atom_table->ucNumEntries; i++) {
 245                amdgpu_table->entries[i].clk = le16_to_cpu(entry->usClockLow) |
 246                        (entry->ucClockHigh << 16);
 247                amdgpu_table->entries[i].v = le16_to_cpu(entry->usVoltage);
 248                entry = (ATOM_PPLIB_Clock_Voltage_Dependency_Record *)
 249                        ((u8 *)entry + sizeof(ATOM_PPLIB_Clock_Voltage_Dependency_Record));
 250        }
 251        amdgpu_table->count = atom_table->ucNumEntries;
 252
 253        return 0;
 254}
 255
 256int amdgpu_get_platform_caps(struct amdgpu_device *adev)
 257{
 258        struct amdgpu_mode_info *mode_info = &adev->mode_info;
 259        union power_info *power_info;
 260        int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
 261        u16 data_offset;
 262        u8 frev, crev;
 263
 264        if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 265                                   &frev, &crev, &data_offset))
 266                return -EINVAL;
 267        power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
 268
 269        adev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
 270        adev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
 271        adev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
 272
 273        return 0;
 274}
 275
 276/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
 277#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
 278#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
 279#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
 280#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
 281#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
 282#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
 283#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8 24
 284#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V9 26
 285
 286int amdgpu_parse_extended_power_table(struct amdgpu_device *adev)
 287{
 288        struct amdgpu_mode_info *mode_info = &adev->mode_info;
 289        union power_info *power_info;
 290        union fan_info *fan_info;
 291        ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
 292        int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
 293        u16 data_offset;
 294        u8 frev, crev;
 295        int ret, i;
 296
 297        if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 298                                   &frev, &crev, &data_offset))
 299                return -EINVAL;
 300        power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
 301
 302        /* fan table */
 303        if (le16_to_cpu(power_info->pplib.usTableSize) >=
 304            sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
 305                if (power_info->pplib3.usFanTableOffset) {
 306                        fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
 307                                                      le16_to_cpu(power_info->pplib3.usFanTableOffset));
 308                        adev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
 309                        adev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
 310                        adev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
 311                        adev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
 312                        adev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
 313                        adev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
 314                        adev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
 315                        if (fan_info->fan.ucFanTableFormat >= 2)
 316                                adev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
 317                        else
 318                                adev->pm.dpm.fan.t_max = 10900;
 319                        adev->pm.dpm.fan.cycle_delay = 100000;
 320                        if (fan_info->fan.ucFanTableFormat >= 3) {
 321                                adev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
 322                                adev->pm.dpm.fan.default_max_fan_pwm =
 323                                        le16_to_cpu(fan_info->fan3.usFanPWMMax);
 324                                adev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
 325                                adev->pm.dpm.fan.fan_output_sensitivity =
 326                                        le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
 327                        }
 328                        adev->pm.dpm.fan.ucode_fan_control = true;
 329                }
 330        }
 331
 332        /* clock dependancy tables, shedding tables */
 333        if (le16_to_cpu(power_info->pplib.usTableSize) >=
 334            sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
 335                if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
 336                        dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 337                                (mode_info->atom_context->bios + data_offset +
 338                                 le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
 339                        ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
 340                                                                 dep_table);
 341                        if (ret) {
 342                                amdgpu_free_extended_power_table(adev);
 343                                return ret;
 344                        }
 345                }
 346                if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
 347                        dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 348                                (mode_info->atom_context->bios + data_offset +
 349                                 le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
 350                        ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
 351                                                                 dep_table);
 352                        if (ret) {
 353                                amdgpu_free_extended_power_table(adev);
 354                                return ret;
 355                        }
 356                }
 357                if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
 358                        dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 359                                (mode_info->atom_context->bios + data_offset +
 360                                 le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
 361                        ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
 362                                                                 dep_table);
 363                        if (ret) {
 364                                amdgpu_free_extended_power_table(adev);
 365                                return ret;
 366                        }
 367                }
 368                if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
 369                        dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 370                                (mode_info->atom_context->bios + data_offset +
 371                                 le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
 372                        ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
 373                                                                 dep_table);
 374                        if (ret) {
 375                                amdgpu_free_extended_power_table(adev);
 376                                return ret;
 377                        }
 378                }
 379                if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
 380                        ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
 381                                (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
 382                                (mode_info->atom_context->bios + data_offset +
 383                                 le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
 384                        if (clk_v->ucNumEntries) {
 385                                adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
 386                                        le16_to_cpu(clk_v->entries[0].usSclkLow) |
 387                                        (clk_v->entries[0].ucSclkHigh << 16);
 388                                adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
 389                                        le16_to_cpu(clk_v->entries[0].usMclkLow) |
 390                                        (clk_v->entries[0].ucMclkHigh << 16);
 391                                adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
 392                                        le16_to_cpu(clk_v->entries[0].usVddc);
 393                                adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
 394                                        le16_to_cpu(clk_v->entries[0].usVddci);
 395                        }
 396                }
 397                if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
 398                        ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
 399                                (ATOM_PPLIB_PhaseSheddingLimits_Table *)
 400                                (mode_info->atom_context->bios + data_offset +
 401                                 le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
 402                        ATOM_PPLIB_PhaseSheddingLimits_Record *entry;
 403
 404                        adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
 405                                kcalloc(psl->ucNumEntries,
 406                                        sizeof(struct amdgpu_phase_shedding_limits_entry),
 407                                        GFP_KERNEL);
 408                        if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
 409                                amdgpu_free_extended_power_table(adev);
 410                                return -ENOMEM;
 411                        }
 412
 413                        entry = &psl->entries[0];
 414                        for (i = 0; i < psl->ucNumEntries; i++) {
 415                                adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
 416                                        le16_to_cpu(entry->usSclkLow) | (entry->ucSclkHigh << 16);
 417                                adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
 418                                        le16_to_cpu(entry->usMclkLow) | (entry->ucMclkHigh << 16);
 419                                adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
 420                                        le16_to_cpu(entry->usVoltage);
 421                                entry = (ATOM_PPLIB_PhaseSheddingLimits_Record *)
 422                                        ((u8 *)entry + sizeof(ATOM_PPLIB_PhaseSheddingLimits_Record));
 423                        }
 424                        adev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
 425                                psl->ucNumEntries;
 426                }
 427        }
 428
 429        /* cac data */
 430        if (le16_to_cpu(power_info->pplib.usTableSize) >=
 431            sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
 432                adev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
 433                adev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
 434                adev->pm.dpm.near_tdp_limit_adjusted = adev->pm.dpm.near_tdp_limit;
 435                adev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
 436                if (adev->pm.dpm.tdp_od_limit)
 437                        adev->pm.dpm.power_control = true;
 438                else
 439                        adev->pm.dpm.power_control = false;
 440                adev->pm.dpm.tdp_adjustment = 0;
 441                adev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
 442                adev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
 443                adev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
 444                if (power_info->pplib5.usCACLeakageTableOffset) {
 445                        ATOM_PPLIB_CAC_Leakage_Table *cac_table =
 446                                (ATOM_PPLIB_CAC_Leakage_Table *)
 447                                (mode_info->atom_context->bios + data_offset +
 448                                 le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
 449                        ATOM_PPLIB_CAC_Leakage_Record *entry;
 450                        u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table);
 451                        adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
 452                        if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) {
 453                                amdgpu_free_extended_power_table(adev);
 454                                return -ENOMEM;
 455                        }
 456                        entry = &cac_table->entries[0];
 457                        for (i = 0; i < cac_table->ucNumEntries; i++) {
 458                                if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
 459                                        adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc1 =
 460                                                le16_to_cpu(entry->usVddc1);
 461                                        adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc2 =
 462                                                le16_to_cpu(entry->usVddc2);
 463                                        adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc3 =
 464                                                le16_to_cpu(entry->usVddc3);
 465                                } else {
 466                                        adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
 467                                                le16_to_cpu(entry->usVddc);
 468                                        adev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
 469                                                le32_to_cpu(entry->ulLeakageValue);
 470                                }
 471                                entry = (ATOM_PPLIB_CAC_Leakage_Record *)
 472                                        ((u8 *)entry + sizeof(ATOM_PPLIB_CAC_Leakage_Record));
 473                        }
 474                        adev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
 475                }
 476        }
 477
 478        /* ext tables */
 479        if (le16_to_cpu(power_info->pplib.usTableSize) >=
 480            sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
 481                ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
 482                        (mode_info->atom_context->bios + data_offset +
 483                         le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
 484                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2) &&
 485                        ext_hdr->usVCETableOffset) {
 486                        VCEClockInfoArray *array = (VCEClockInfoArray *)
 487                                (mode_info->atom_context->bios + data_offset +
 488                                 le16_to_cpu(ext_hdr->usVCETableOffset) + 1);
 489                        ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *limits =
 490                                (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
 491                                (mode_info->atom_context->bios + data_offset +
 492                                 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
 493                                 1 + array->ucNumEntries * sizeof(VCEClockInfo));
 494                        ATOM_PPLIB_VCE_State_Table *states =
 495                                (ATOM_PPLIB_VCE_State_Table *)
 496                                (mode_info->atom_context->bios + data_offset +
 497                                 le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
 498                                 1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
 499                                 1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
 500                        ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
 501                        ATOM_PPLIB_VCE_State_Record *state_entry;
 502                        VCEClockInfo *vce_clk;
 503                        u32 size = limits->numEntries *
 504                                sizeof(struct amdgpu_vce_clock_voltage_dependency_entry);
 505                        adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
 506                                kzalloc(size, GFP_KERNEL);
 507                        if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) {
 508                                amdgpu_free_extended_power_table(adev);
 509                                return -ENOMEM;
 510                        }
 511                        adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
 512                                limits->numEntries;
 513                        entry = &limits->entries[0];
 514                        state_entry = &states->entries[0];
 515                        for (i = 0; i < limits->numEntries; i++) {
 516                                vce_clk = (VCEClockInfo *)
 517                                        ((u8 *)&array->entries[0] +
 518                                         (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
 519                                adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
 520                                        le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
 521                                adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].ecclk =
 522                                        le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
 523                                adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].v =
 524                                        le16_to_cpu(entry->usVoltage);
 525                                entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
 526                                        ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
 527                        }
 528                        adev->pm.dpm.num_of_vce_states =
 529                                        states->numEntries > AMD_MAX_VCE_LEVELS ?
 530                                        AMD_MAX_VCE_LEVELS : states->numEntries;
 531                        for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
 532                                vce_clk = (VCEClockInfo *)
 533                                        ((u8 *)&array->entries[0] +
 534                                         (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
 535                                adev->pm.dpm.vce_states[i].evclk =
 536                                        le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
 537                                adev->pm.dpm.vce_states[i].ecclk =
 538                                        le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
 539                                adev->pm.dpm.vce_states[i].clk_idx =
 540                                        state_entry->ucClockInfoIndex & 0x3f;
 541                                adev->pm.dpm.vce_states[i].pstate =
 542                                        (state_entry->ucClockInfoIndex & 0xc0) >> 6;
 543                                state_entry = (ATOM_PPLIB_VCE_State_Record *)
 544                                        ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
 545                        }
 546                }
 547                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
 548                        ext_hdr->usUVDTableOffset) {
 549                        UVDClockInfoArray *array = (UVDClockInfoArray *)
 550                                (mode_info->atom_context->bios + data_offset +
 551                                 le16_to_cpu(ext_hdr->usUVDTableOffset) + 1);
 552                        ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *limits =
 553                                (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
 554                                (mode_info->atom_context->bios + data_offset +
 555                                 le16_to_cpu(ext_hdr->usUVDTableOffset) + 1 +
 556                                 1 + (array->ucNumEntries * sizeof (UVDClockInfo)));
 557                        ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *entry;
 558                        u32 size = limits->numEntries *
 559                                sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry);
 560                        adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries =
 561                                kzalloc(size, GFP_KERNEL);
 562                        if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) {
 563                                amdgpu_free_extended_power_table(adev);
 564                                return -ENOMEM;
 565                        }
 566                        adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count =
 567                                limits->numEntries;
 568                        entry = &limits->entries[0];
 569                        for (i = 0; i < limits->numEntries; i++) {
 570                                UVDClockInfo *uvd_clk = (UVDClockInfo *)
 571                                        ((u8 *)&array->entries[0] +
 572                                         (entry->ucUVDClockInfoIndex * sizeof(UVDClockInfo)));
 573                                adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].vclk =
 574                                        le16_to_cpu(uvd_clk->usVClkLow) | (uvd_clk->ucVClkHigh << 16);
 575                                adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk =
 576                                        le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16);
 577                                adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v =
 578                                        le16_to_cpu(entry->usVoltage);
 579                                entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *)
 580                                        ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record));
 581                        }
 582                }
 583                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4) &&
 584                        ext_hdr->usSAMUTableOffset) {
 585                        ATOM_PPLIB_SAMClk_Voltage_Limit_Table *limits =
 586                                (ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
 587                                (mode_info->atom_context->bios + data_offset +
 588                                 le16_to_cpu(ext_hdr->usSAMUTableOffset) + 1);
 589                        ATOM_PPLIB_SAMClk_Voltage_Limit_Record *entry;
 590                        u32 size = limits->numEntries *
 591                                sizeof(struct amdgpu_clock_voltage_dependency_entry);
 592                        adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries =
 593                                kzalloc(size, GFP_KERNEL);
 594                        if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) {
 595                                amdgpu_free_extended_power_table(adev);
 596                                return -ENOMEM;
 597                        }
 598                        adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count =
 599                                limits->numEntries;
 600                        entry = &limits->entries[0];
 601                        for (i = 0; i < limits->numEntries; i++) {
 602                                adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].clk =
 603                                        le16_to_cpu(entry->usSAMClockLow) | (entry->ucSAMClockHigh << 16);
 604                                adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].v =
 605                                        le16_to_cpu(entry->usVoltage);
 606                                entry = (ATOM_PPLIB_SAMClk_Voltage_Limit_Record *)
 607                                        ((u8 *)entry + sizeof(ATOM_PPLIB_SAMClk_Voltage_Limit_Record));
 608                        }
 609                }
 610                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
 611                    ext_hdr->usPPMTableOffset) {
 612                        ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
 613                                (mode_info->atom_context->bios + data_offset +
 614                                 le16_to_cpu(ext_hdr->usPPMTableOffset));
 615                        adev->pm.dpm.dyn_state.ppm_table =
 616                                kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL);
 617                        if (!adev->pm.dpm.dyn_state.ppm_table) {
 618                                amdgpu_free_extended_power_table(adev);
 619                                return -ENOMEM;
 620                        }
 621                        adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
 622                        adev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
 623                                le16_to_cpu(ppm->usCpuCoreNumber);
 624                        adev->pm.dpm.dyn_state.ppm_table->platform_tdp =
 625                                le32_to_cpu(ppm->ulPlatformTDP);
 626                        adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
 627                                le32_to_cpu(ppm->ulSmallACPlatformTDP);
 628                        adev->pm.dpm.dyn_state.ppm_table->platform_tdc =
 629                                le32_to_cpu(ppm->ulPlatformTDC);
 630                        adev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
 631                                le32_to_cpu(ppm->ulSmallACPlatformTDC);
 632                        adev->pm.dpm.dyn_state.ppm_table->apu_tdp =
 633                                le32_to_cpu(ppm->ulApuTDP);
 634                        adev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
 635                                le32_to_cpu(ppm->ulDGpuTDP);
 636                        adev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
 637                                le32_to_cpu(ppm->ulDGpuUlvPower);
 638                        adev->pm.dpm.dyn_state.ppm_table->tj_max =
 639                                le32_to_cpu(ppm->ulTjmax);
 640                }
 641                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6) &&
 642                        ext_hdr->usACPTableOffset) {
 643                        ATOM_PPLIB_ACPClk_Voltage_Limit_Table *limits =
 644                                (ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
 645                                (mode_info->atom_context->bios + data_offset +
 646                                 le16_to_cpu(ext_hdr->usACPTableOffset) + 1);
 647                        ATOM_PPLIB_ACPClk_Voltage_Limit_Record *entry;
 648                        u32 size = limits->numEntries *
 649                                sizeof(struct amdgpu_clock_voltage_dependency_entry);
 650                        adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries =
 651                                kzalloc(size, GFP_KERNEL);
 652                        if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) {
 653                                amdgpu_free_extended_power_table(adev);
 654                                return -ENOMEM;
 655                        }
 656                        adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count =
 657                                limits->numEntries;
 658                        entry = &limits->entries[0];
 659                        for (i = 0; i < limits->numEntries; i++) {
 660                                adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].clk =
 661                                        le16_to_cpu(entry->usACPClockLow) | (entry->ucACPClockHigh << 16);
 662                                adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].v =
 663                                        le16_to_cpu(entry->usVoltage);
 664                                entry = (ATOM_PPLIB_ACPClk_Voltage_Limit_Record *)
 665                                        ((u8 *)entry + sizeof(ATOM_PPLIB_ACPClk_Voltage_Limit_Record));
 666                        }
 667                }
 668                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) &&
 669                        ext_hdr->usPowerTuneTableOffset) {
 670                        u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset +
 671                                         le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
 672                        ATOM_PowerTune_Table *pt;
 673                        adev->pm.dpm.dyn_state.cac_tdp_table =
 674                                kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL);
 675                        if (!adev->pm.dpm.dyn_state.cac_tdp_table) {
 676                                amdgpu_free_extended_power_table(adev);
 677                                return -ENOMEM;
 678                        }
 679                        if (rev > 0) {
 680                                ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *)
 681                                        (mode_info->atom_context->bios + data_offset +
 682                                         le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
 683                                adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
 684                                        ppt->usMaximumPowerDeliveryLimit;
 685                                pt = &ppt->power_tune_table;
 686                        } else {
 687                                ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
 688                                        (mode_info->atom_context->bios + data_offset +
 689                                         le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
 690                                adev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255;
 691                                pt = &ppt->power_tune_table;
 692                        }
 693                        adev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP);
 694                        adev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp =
 695                                le16_to_cpu(pt->usConfigurableTDP);
 696                        adev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC);
 697                        adev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit =
 698                                le16_to_cpu(pt->usBatteryPowerLimit);
 699                        adev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit =
 700                                le16_to_cpu(pt->usSmallPowerLimit);
 701                        adev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage =
 702                                le16_to_cpu(pt->usLowCACLeakage);
 703                        adev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage =
 704                                le16_to_cpu(pt->usHighCACLeakage);
 705                }
 706                if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V8) &&
 707                                ext_hdr->usSclkVddgfxTableOffset) {
 708                        dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 709                                (mode_info->atom_context->bios + data_offset +
 710                                 le16_to_cpu(ext_hdr->usSclkVddgfxTableOffset));
 711                        ret = amdgpu_parse_clk_voltage_dep_table(
 712                                        &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk,
 713                                        dep_table);
 714                        if (ret) {
 715                                kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries);
 716                                return ret;
 717                        }
 718                }
 719        }
 720
 721        return 0;
 722}
 723
 724void amdgpu_free_extended_power_table(struct amdgpu_device *adev)
 725{
 726        struct amdgpu_dpm_dynamic_state *dyn_state = &adev->pm.dpm.dyn_state;
 727
 728        kfree(dyn_state->vddc_dependency_on_sclk.entries);
 729        kfree(dyn_state->vddci_dependency_on_mclk.entries);
 730        kfree(dyn_state->vddc_dependency_on_mclk.entries);
 731        kfree(dyn_state->mvdd_dependency_on_mclk.entries);
 732        kfree(dyn_state->cac_leakage_table.entries);
 733        kfree(dyn_state->phase_shedding_limits_table.entries);
 734        kfree(dyn_state->ppm_table);
 735        kfree(dyn_state->cac_tdp_table);
 736        kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
 737        kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
 738        kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
 739        kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
 740        kfree(dyn_state->vddgfx_dependency_on_sclk.entries);
 741}
 742
 743static const char *pp_lib_thermal_controller_names[] = {
 744        "NONE",
 745        "lm63",
 746        "adm1032",
 747        "adm1030",
 748        "max6649",
 749        "lm64",
 750        "f75375",
 751        "RV6xx",
 752        "RV770",
 753        "adt7473",
 754        "NONE",
 755        "External GPIO",
 756        "Evergreen",
 757        "emc2103",
 758        "Sumo",
 759        "Northern Islands",
 760        "Southern Islands",
 761        "lm96163",
 762        "Sea Islands",
 763        "Kaveri/Kabini",
 764};
 765
 766void amdgpu_add_thermal_controller(struct amdgpu_device *adev)
 767{
 768        struct amdgpu_mode_info *mode_info = &adev->mode_info;
 769        ATOM_PPLIB_POWERPLAYTABLE *power_table;
 770        int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
 771        ATOM_PPLIB_THERMALCONTROLLER *controller;
 772        struct amdgpu_i2c_bus_rec i2c_bus;
 773        u16 data_offset;
 774        u8 frev, crev;
 775
 776        if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
 777                                   &frev, &crev, &data_offset))
 778                return;
 779        power_table = (ATOM_PPLIB_POWERPLAYTABLE *)
 780                (mode_info->atom_context->bios + data_offset);
 781        controller = &power_table->sThermalController;
 782
 783        /* add the i2c bus for thermal/fan chip */
 784        if (controller->ucType > 0) {
 785                if (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN)
 786                        adev->pm.no_fan = true;
 787                adev->pm.fan_pulses_per_revolution =
 788                        controller->ucFanParameters & ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
 789                if (adev->pm.fan_pulses_per_revolution) {
 790                        adev->pm.fan_min_rpm = controller->ucFanMinRPM;
 791                        adev->pm.fan_max_rpm = controller->ucFanMaxRPM;
 792                }
 793                if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) {
 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_RV6XX;
 798                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) {
 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_RV770;
 803                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) {
 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_EVERGREEN;
 808                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) {
 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_SUMO;
 813                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_NISLANDS) {
 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_NI;
 818                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SISLANDS) {
 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_SI;
 823                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_CISLANDS) {
 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_CI;
 828                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_KAVERI) {
 829                        DRM_INFO("Internal thermal controller %s fan control\n",
 830                                 (controller->ucFanParameters &
 831                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 832                        adev->pm.int_thermal_type = THERMAL_TYPE_KV;
 833                } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) {
 834                        DRM_INFO("External GPIO thermal controller %s fan control\n",
 835                                 (controller->ucFanParameters &
 836                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 837                        adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL_GPIO;
 838                } else if (controller->ucType ==
 839                           ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) {
 840                        DRM_INFO("ADT7473 with internal thermal controller %s fan control\n",
 841                                 (controller->ucFanParameters &
 842                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 843                        adev->pm.int_thermal_type = THERMAL_TYPE_ADT7473_WITH_INTERNAL;
 844                } else if (controller->ucType ==
 845                           ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL) {
 846                        DRM_INFO("EMC2103 with internal thermal controller %s fan control\n",
 847                                 (controller->ucFanParameters &
 848                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 849                        adev->pm.int_thermal_type = THERMAL_TYPE_EMC2103_WITH_INTERNAL;
 850                } else if (controller->ucType < ARRAY_SIZE(pp_lib_thermal_controller_names)) {
 851                        DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n",
 852                                 pp_lib_thermal_controller_names[controller->ucType],
 853                                 controller->ucI2cAddress >> 1,
 854                                 (controller->ucFanParameters &
 855                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 856                        adev->pm.int_thermal_type = THERMAL_TYPE_EXTERNAL;
 857                        i2c_bus = amdgpu_atombios_lookup_i2c_gpio(adev, controller->ucI2cLine);
 858                        adev->pm.i2c_bus = amdgpu_i2c_lookup(adev, &i2c_bus);
 859                        if (adev->pm.i2c_bus) {
 860                                struct i2c_board_info info = { };
 861                                const char *name = pp_lib_thermal_controller_names[controller->ucType];
 862                                info.addr = controller->ucI2cAddress >> 1;
 863                                strlcpy(info.type, name, sizeof(info.type));
 864                                i2c_new_client_device(&adev->pm.i2c_bus->adapter, &info);
 865                        }
 866                } else {
 867                        DRM_INFO("Unknown thermal controller type %d at 0x%02x %s fan control\n",
 868                                 controller->ucType,
 869                                 controller->ucI2cAddress >> 1,
 870                                 (controller->ucFanParameters &
 871                                  ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with");
 872                }
 873        }
 874}
 875
 876enum amdgpu_pcie_gen amdgpu_get_pcie_gen_support(struct amdgpu_device *adev,
 877                                                 u32 sys_mask,
 878                                                 enum amdgpu_pcie_gen asic_gen,
 879                                                 enum amdgpu_pcie_gen default_gen)
 880{
 881        switch (asic_gen) {
 882        case AMDGPU_PCIE_GEN1:
 883                return AMDGPU_PCIE_GEN1;
 884        case AMDGPU_PCIE_GEN2:
 885                return AMDGPU_PCIE_GEN2;
 886        case AMDGPU_PCIE_GEN3:
 887                return AMDGPU_PCIE_GEN3;
 888        default:
 889                if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&
 890                    (default_gen == AMDGPU_PCIE_GEN3))
 891                        return AMDGPU_PCIE_GEN3;
 892                else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&
 893                         (default_gen == AMDGPU_PCIE_GEN2))
 894                        return AMDGPU_PCIE_GEN2;
 895                else
 896                        return AMDGPU_PCIE_GEN1;
 897        }
 898        return AMDGPU_PCIE_GEN1;
 899}
 900
 901struct amd_vce_state*
 902amdgpu_get_vce_clock_state(void *handle, u32 idx)
 903{
 904        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 905
 906        if (idx < adev->pm.dpm.num_of_vce_states)
 907                return &adev->pm.dpm.vce_states[idx];
 908
 909        return NULL;
 910}
 911
 912int amdgpu_dpm_get_sclk(struct amdgpu_device *adev, bool low)
 913{
 914        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 915
 916        return pp_funcs->get_sclk((adev)->powerplay.pp_handle, (low));
 917}
 918
 919int amdgpu_dpm_get_mclk(struct amdgpu_device *adev, bool low)
 920{
 921        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 922
 923        return pp_funcs->get_mclk((adev)->powerplay.pp_handle, (low));
 924}
 925
 926int amdgpu_dpm_set_powergating_by_smu(struct amdgpu_device *adev, uint32_t block_type, bool gate)
 927{
 928        int ret = 0;
 929        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 930
 931        switch (block_type) {
 932        case AMD_IP_BLOCK_TYPE_UVD:
 933        case AMD_IP_BLOCK_TYPE_VCE:
 934                if (pp_funcs && pp_funcs->set_powergating_by_smu) {
 935                        /*
 936                         * TODO: need a better lock mechanism
 937                         *
 938                         * Here adev->pm.mutex lock protection is enforced on
 939                         * UVD and VCE cases only. Since for other cases, there
 940                         * may be already lock protection in amdgpu_pm.c.
 941                         * This is a quick fix for the deadlock issue below.
 942                         *     NFO: task ocltst:2028 blocked for more than 120 seconds.
 943                         *     Tainted: G           OE     5.0.0-37-generic #40~18.04.1-Ubuntu
 944                         *     echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
 945                         *     cltst          D    0  2028   2026 0x00000000
 946                         *     all Trace:
 947                         *     __schedule+0x2c0/0x870
 948                         *     schedule+0x2c/0x70
 949                         *     schedule_preempt_disabled+0xe/0x10
 950                         *     __mutex_lock.isra.9+0x26d/0x4e0
 951                         *     __mutex_lock_slowpath+0x13/0x20
 952                         *     ? __mutex_lock_slowpath+0x13/0x20
 953                         *     mutex_lock+0x2f/0x40
 954                         *     amdgpu_dpm_set_powergating_by_smu+0x64/0xe0 [amdgpu]
 955                         *     gfx_v8_0_enable_gfx_static_mg_power_gating+0x3c/0x70 [amdgpu]
 956                         *     gfx_v8_0_set_powergating_state+0x66/0x260 [amdgpu]
 957                         *     amdgpu_device_ip_set_powergating_state+0x62/0xb0 [amdgpu]
 958                         *     pp_dpm_force_performance_level+0xe7/0x100 [amdgpu]
 959                         *     amdgpu_set_dpm_forced_performance_level+0x129/0x330 [amdgpu]
 960                         */
 961                        mutex_lock(&adev->pm.mutex);
 962                        ret = (pp_funcs->set_powergating_by_smu(
 963                                (adev)->powerplay.pp_handle, block_type, gate));
 964                        mutex_unlock(&adev->pm.mutex);
 965                }
 966                break;
 967        case AMD_IP_BLOCK_TYPE_GFX:
 968        case AMD_IP_BLOCK_TYPE_VCN:
 969        case AMD_IP_BLOCK_TYPE_SDMA:
 970        case AMD_IP_BLOCK_TYPE_JPEG:
 971        case AMD_IP_BLOCK_TYPE_GMC:
 972        case AMD_IP_BLOCK_TYPE_ACP:
 973                if (pp_funcs && pp_funcs->set_powergating_by_smu) {
 974                        ret = (pp_funcs->set_powergating_by_smu(
 975                                (adev)->powerplay.pp_handle, block_type, gate));
 976                }
 977                break;
 978        default:
 979                break;
 980        }
 981
 982        return ret;
 983}
 984
 985int amdgpu_dpm_baco_enter(struct amdgpu_device *adev)
 986{
 987        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
 988        void *pp_handle = adev->powerplay.pp_handle;
 989        int ret = 0;
 990
 991        if (!pp_funcs || !pp_funcs->set_asic_baco_state)
 992                return -ENOENT;
 993
 994        /* enter BACO state */
 995        ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
 996
 997        return ret;
 998}
 999
1000int amdgpu_dpm_baco_exit(struct amdgpu_device *adev)
1001{
1002        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1003        void *pp_handle = adev->powerplay.pp_handle;
1004        int ret = 0;
1005
1006        if (!pp_funcs || !pp_funcs->set_asic_baco_state)
1007                return -ENOENT;
1008
1009        /* exit BACO state */
1010        ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
1011
1012        return ret;
1013}
1014
1015int amdgpu_dpm_set_mp1_state(struct amdgpu_device *adev,
1016                             enum pp_mp1_state mp1_state)
1017{
1018        int ret = 0;
1019        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1020
1021        if (pp_funcs && pp_funcs->set_mp1_state) {
1022                ret = pp_funcs->set_mp1_state(
1023                                adev->powerplay.pp_handle,
1024                                mp1_state);
1025        }
1026
1027        return ret;
1028}
1029
1030bool amdgpu_dpm_is_baco_supported(struct amdgpu_device *adev)
1031{
1032        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1033        void *pp_handle = adev->powerplay.pp_handle;
1034        bool baco_cap;
1035
1036        if (!pp_funcs || !pp_funcs->get_asic_baco_capability)
1037                return false;
1038
1039        if (pp_funcs->get_asic_baco_capability(pp_handle, &baco_cap))
1040                return false;
1041
1042        return baco_cap;
1043}
1044
1045int amdgpu_dpm_mode2_reset(struct amdgpu_device *adev)
1046{
1047        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1048        void *pp_handle = adev->powerplay.pp_handle;
1049
1050        if (!pp_funcs || !pp_funcs->asic_reset_mode_2)
1051                return -ENOENT;
1052
1053        return pp_funcs->asic_reset_mode_2(pp_handle);
1054}
1055
1056int amdgpu_dpm_baco_reset(struct amdgpu_device *adev)
1057{
1058        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1059        void *pp_handle = adev->powerplay.pp_handle;
1060        int ret = 0;
1061
1062        if (!pp_funcs || !pp_funcs->set_asic_baco_state)
1063                return -ENOENT;
1064
1065        /* enter BACO state */
1066        ret = pp_funcs->set_asic_baco_state(pp_handle, 1);
1067        if (ret)
1068                return ret;
1069
1070        /* exit BACO state */
1071        ret = pp_funcs->set_asic_baco_state(pp_handle, 0);
1072        if (ret)
1073                return ret;
1074
1075        return 0;
1076}
1077
1078bool amdgpu_dpm_is_mode1_reset_supported(struct amdgpu_device *adev)
1079{
1080        struct smu_context *smu = &adev->smu;
1081
1082        if (is_support_sw_smu(adev))
1083                return smu_mode1_reset_is_support(smu);
1084
1085        return false;
1086}
1087
1088int amdgpu_dpm_mode1_reset(struct amdgpu_device *adev)
1089{
1090        struct smu_context *smu = &adev->smu;
1091
1092        if (is_support_sw_smu(adev))
1093                return smu_mode1_reset(smu);
1094
1095        return -EOPNOTSUPP;
1096}
1097
1098int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
1099                                    enum PP_SMC_POWER_PROFILE type,
1100                                    bool en)
1101{
1102        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1103        int ret = 0;
1104
1105        if (amdgpu_sriov_vf(adev))
1106                return 0;
1107
1108        if (pp_funcs && pp_funcs->switch_power_profile)
1109                ret = pp_funcs->switch_power_profile(
1110                        adev->powerplay.pp_handle, type, en);
1111
1112        return ret;
1113}
1114
1115int amdgpu_dpm_set_xgmi_pstate(struct amdgpu_device *adev,
1116                               uint32_t pstate)
1117{
1118        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1119        int ret = 0;
1120
1121        if (pp_funcs && pp_funcs->set_xgmi_pstate)
1122                ret = pp_funcs->set_xgmi_pstate(adev->powerplay.pp_handle,
1123                                                                pstate);
1124
1125        return ret;
1126}
1127
1128int amdgpu_dpm_set_df_cstate(struct amdgpu_device *adev,
1129                             uint32_t cstate)
1130{
1131        int ret = 0;
1132        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1133        void *pp_handle = adev->powerplay.pp_handle;
1134
1135        if (pp_funcs && pp_funcs->set_df_cstate)
1136                ret = pp_funcs->set_df_cstate(pp_handle, cstate);
1137
1138        return ret;
1139}
1140
1141int amdgpu_dpm_allow_xgmi_power_down(struct amdgpu_device *adev, bool en)
1142{
1143        struct smu_context *smu = &adev->smu;
1144
1145        if (is_support_sw_smu(adev))
1146                return smu_allow_xgmi_power_down(smu, en);
1147
1148        return 0;
1149}
1150
1151int amdgpu_dpm_enable_mgpu_fan_boost(struct amdgpu_device *adev)
1152{
1153        void *pp_handle = adev->powerplay.pp_handle;
1154        const struct amd_pm_funcs *pp_funcs =
1155                        adev->powerplay.pp_funcs;
1156        int ret = 0;
1157
1158        if (pp_funcs && pp_funcs->enable_mgpu_fan_boost)
1159                ret = pp_funcs->enable_mgpu_fan_boost(pp_handle);
1160
1161        return ret;
1162}
1163
1164int amdgpu_dpm_set_clockgating_by_smu(struct amdgpu_device *adev,
1165                                      uint32_t msg_id)
1166{
1167        void *pp_handle = adev->powerplay.pp_handle;
1168        const struct amd_pm_funcs *pp_funcs =
1169                        adev->powerplay.pp_funcs;
1170        int ret = 0;
1171
1172        if (pp_funcs && pp_funcs->set_clockgating_by_smu)
1173                ret = pp_funcs->set_clockgating_by_smu(pp_handle,
1174                                                       msg_id);
1175
1176        return ret;
1177}
1178
1179int amdgpu_dpm_smu_i2c_bus_access(struct amdgpu_device *adev,
1180                                  bool acquire)
1181{
1182        void *pp_handle = adev->powerplay.pp_handle;
1183        const struct amd_pm_funcs *pp_funcs =
1184                        adev->powerplay.pp_funcs;
1185        int ret = -EOPNOTSUPP;
1186
1187        if (pp_funcs && pp_funcs->smu_i2c_bus_access)
1188                ret = pp_funcs->smu_i2c_bus_access(pp_handle,
1189                                                   acquire);
1190
1191        return ret;
1192}
1193
1194void amdgpu_pm_acpi_event_handler(struct amdgpu_device *adev)
1195{
1196        if (adev->pm.dpm_enabled) {
1197                mutex_lock(&adev->pm.mutex);
1198                if (power_supply_is_system_supplied() > 0)
1199                        adev->pm.ac_power = true;
1200                else
1201                        adev->pm.ac_power = false;
1202                if (adev->powerplay.pp_funcs &&
1203                    adev->powerplay.pp_funcs->enable_bapm)
1204                        amdgpu_dpm_enable_bapm(adev, adev->pm.ac_power);
1205                mutex_unlock(&adev->pm.mutex);
1206
1207                if (is_support_sw_smu(adev))
1208                        smu_set_ac_dc(&adev->smu);
1209        }
1210}
1211
1212int amdgpu_dpm_read_sensor(struct amdgpu_device *adev, enum amd_pp_sensors sensor,
1213                           void *data, uint32_t *size)
1214{
1215        const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
1216        int ret = 0;
1217
1218        if (!data || !size)
1219                return -EINVAL;
1220
1221        if (pp_funcs && pp_funcs->read_sensor)
1222                ret = pp_funcs->read_sensor((adev)->powerplay.pp_handle,
1223                                                                    sensor, data, size);
1224        else
1225                ret = -EINVAL;
1226
1227        return ret;
1228}
1229
1230void amdgpu_dpm_thermal_work_handler(struct work_struct *work)
1231{
1232        struct amdgpu_device *adev =
1233                container_of(work, struct amdgpu_device,
1234                             pm.dpm.thermal.work);
1235        /* switch to the thermal state */
1236        enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
1237        int temp, size = sizeof(temp);
1238
1239        if (!adev->pm.dpm_enabled)
1240                return;
1241
1242        if (!amdgpu_dpm_read_sensor(adev, AMDGPU_PP_SENSOR_GPU_TEMP,
1243                                    (void *)&temp, &size)) {
1244                if (temp < adev->pm.dpm.thermal.min_temp)
1245                        /* switch back the user state */
1246                        dpm_state = adev->pm.dpm.user_state;
1247        } else {
1248                if (adev->pm.dpm.thermal.high_to_low)
1249                        /* switch back the user state */
1250                        dpm_state = adev->pm.dpm.user_state;
1251        }
1252        mutex_lock(&adev->pm.mutex);
1253        if (dpm_state == POWER_STATE_TYPE_INTERNAL_THERMAL)
1254                adev->pm.dpm.thermal_active = true;
1255        else
1256                adev->pm.dpm.thermal_active = false;
1257        adev->pm.dpm.state = dpm_state;
1258        mutex_unlock(&adev->pm.mutex);
1259
1260        amdgpu_pm_compute_clocks(adev);
1261}
1262
1263static struct amdgpu_ps *amdgpu_dpm_pick_power_state(struct amdgpu_device *adev,
1264                                                     enum amd_pm_state_type dpm_state)
1265{
1266        int i;
1267        struct amdgpu_ps *ps;
1268        u32 ui_class;
1269        bool single_display = (adev->pm.dpm.new_active_crtc_count < 2) ?
1270                true : false;
1271
1272        /* check if the vblank period is too short to adjust the mclk */
1273        if (single_display && adev->powerplay.pp_funcs->vblank_too_short) {
1274                if (amdgpu_dpm_vblank_too_short(adev))
1275                        single_display = false;
1276        }
1277
1278        /* certain older asics have a separare 3D performance state,
1279         * so try that first if the user selected performance
1280         */
1281        if (dpm_state == POWER_STATE_TYPE_PERFORMANCE)
1282                dpm_state = POWER_STATE_TYPE_INTERNAL_3DPERF;
1283        /* balanced states don't exist at the moment */
1284        if (dpm_state == POWER_STATE_TYPE_BALANCED)
1285                dpm_state = POWER_STATE_TYPE_PERFORMANCE;
1286
1287restart_search:
1288        /* Pick the best power state based on current conditions */
1289        for (i = 0; i < adev->pm.dpm.num_ps; i++) {
1290                ps = &adev->pm.dpm.ps[i];
1291                ui_class = ps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK;
1292                switch (dpm_state) {
1293                /* user states */
1294                case POWER_STATE_TYPE_BATTERY:
1295                        if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) {
1296                                if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
1297                                        if (single_display)
1298                                                return ps;
1299                                } else
1300                                        return ps;
1301                        }
1302                        break;
1303                case POWER_STATE_TYPE_BALANCED:
1304                        if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BALANCED) {
1305                                if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
1306                                        if (single_display)
1307                                                return ps;
1308                                } else
1309                                        return ps;
1310                        }
1311                        break;
1312                case POWER_STATE_TYPE_PERFORMANCE:
1313                        if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
1314                                if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
1315                                        if (single_display)
1316                                                return ps;
1317                                } else
1318                                        return ps;
1319                        }
1320                        break;
1321                /* internal states */
1322                case POWER_STATE_TYPE_INTERNAL_UVD:
1323                        if (adev->pm.dpm.uvd_ps)
1324                                return adev->pm.dpm.uvd_ps;
1325                        else
1326                                break;
1327                case POWER_STATE_TYPE_INTERNAL_UVD_SD:
1328                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
1329                                return ps;
1330                        break;
1331                case POWER_STATE_TYPE_INTERNAL_UVD_HD:
1332                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
1333                                return ps;
1334                        break;
1335                case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
1336                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
1337                                return ps;
1338                        break;
1339                case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
1340                        if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
1341                                return ps;
1342                        break;
1343                case POWER_STATE_TYPE_INTERNAL_BOOT:
1344                        return adev->pm.dpm.boot_ps;
1345                case POWER_STATE_TYPE_INTERNAL_THERMAL:
1346                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
1347                                return ps;
1348                        break;
1349                case POWER_STATE_TYPE_INTERNAL_ACPI:
1350                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_ACPI)
1351                                return ps;
1352                        break;
1353                case POWER_STATE_TYPE_INTERNAL_ULV:
1354                        if (ps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
1355                                return ps;
1356                        break;
1357                case POWER_STATE_TYPE_INTERNAL_3DPERF:
1358                        if (ps->class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
1359                                return ps;
1360                        break;
1361                default:
1362                        break;
1363                }
1364        }
1365        /* use a fallback state if we didn't match */
1366        switch (dpm_state) {
1367        case POWER_STATE_TYPE_INTERNAL_UVD_SD:
1368                dpm_state = POWER_STATE_TYPE_INTERNAL_UVD_HD;
1369                goto restart_search;
1370        case POWER_STATE_TYPE_INTERNAL_UVD_HD:
1371        case POWER_STATE_TYPE_INTERNAL_UVD_HD2:
1372        case POWER_STATE_TYPE_INTERNAL_UVD_MVC:
1373                if (adev->pm.dpm.uvd_ps) {
1374                        return adev->pm.dpm.uvd_ps;
1375                } else {
1376                        dpm_state = POWER_STATE_TYPE_PERFORMANCE;
1377                        goto restart_search;
1378                }
1379        case POWER_STATE_TYPE_INTERNAL_THERMAL:
1380                dpm_state = POWER_STATE_TYPE_INTERNAL_ACPI;
1381                goto restart_search;
1382        case POWER_STATE_TYPE_INTERNAL_ACPI:
1383                dpm_state = POWER_STATE_TYPE_BATTERY;
1384                goto restart_search;
1385        case POWER_STATE_TYPE_BATTERY:
1386        case POWER_STATE_TYPE_BALANCED:
1387        case POWER_STATE_TYPE_INTERNAL_3DPERF:
1388                dpm_state = POWER_STATE_TYPE_PERFORMANCE;
1389                goto restart_search;
1390        default:
1391                break;
1392        }
1393
1394        return NULL;
1395}
1396
1397static void amdgpu_dpm_change_power_state_locked(struct amdgpu_device *adev)
1398{
1399        struct amdgpu_ps *ps;
1400        enum amd_pm_state_type dpm_state;
1401        int ret;
1402        bool equal = false;
1403
1404        /* if dpm init failed */
1405        if (!adev->pm.dpm_enabled)
1406                return;
1407
1408        if (adev->pm.dpm.user_state != adev->pm.dpm.state) {
1409                /* add other state override checks here */
1410                if ((!adev->pm.dpm.thermal_active) &&
1411                    (!adev->pm.dpm.uvd_active))
1412                        adev->pm.dpm.state = adev->pm.dpm.user_state;
1413        }
1414        dpm_state = adev->pm.dpm.state;
1415
1416        ps = amdgpu_dpm_pick_power_state(adev, dpm_state);
1417        if (ps)
1418                adev->pm.dpm.requested_ps = ps;
1419        else
1420                return;
1421
1422        if (amdgpu_dpm == 1 && adev->powerplay.pp_funcs->print_power_state) {
1423                printk("switching from power state:\n");
1424                amdgpu_dpm_print_power_state(adev, adev->pm.dpm.current_ps);
1425                printk("switching to power state:\n");
1426                amdgpu_dpm_print_power_state(adev, adev->pm.dpm.requested_ps);
1427        }
1428
1429        /* update whether vce is active */
1430        ps->vce_active = adev->pm.dpm.vce_active;
1431        if (adev->powerplay.pp_funcs->display_configuration_changed)
1432                amdgpu_dpm_display_configuration_changed(adev);
1433
1434        ret = amdgpu_dpm_pre_set_power_state(adev);
1435        if (ret)
1436                return;
1437
1438        if (adev->powerplay.pp_funcs->check_state_equal) {
1439                if (0 != amdgpu_dpm_check_state_equal(adev, adev->pm.dpm.current_ps, adev->pm.dpm.requested_ps, &equal))
1440                        equal = false;
1441        }
1442
1443        if (equal)
1444                return;
1445
1446        amdgpu_dpm_set_power_state(adev);
1447        amdgpu_dpm_post_set_power_state(adev);
1448
1449        adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
1450        adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
1451
1452        if (adev->powerplay.pp_funcs->force_performance_level) {
1453                if (adev->pm.dpm.thermal_active) {
1454                        enum amd_dpm_forced_level level = adev->pm.dpm.forced_level;
1455                        /* force low perf level for thermal */
1456                        amdgpu_dpm_force_performance_level(adev, AMD_DPM_FORCED_LEVEL_LOW);
1457                        /* save the user's level */
1458                        adev->pm.dpm.forced_level = level;
1459                } else {
1460                        /* otherwise, user selected level */
1461                        amdgpu_dpm_force_performance_level(adev, adev->pm.dpm.forced_level);
1462                }
1463        }
1464}
1465
1466void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
1467{
1468        int i = 0;
1469
1470        if (!adev->pm.dpm_enabled)
1471                return;
1472
1473        if (adev->mode_info.num_crtc)
1474                amdgpu_display_bandwidth_update(adev);
1475
1476        for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
1477                struct amdgpu_ring *ring = adev->rings[i];
1478                if (ring && ring->sched.ready)
1479                        amdgpu_fence_wait_empty(ring);
1480        }
1481
1482        if (adev->powerplay.pp_funcs->dispatch_tasks) {
1483                if (!amdgpu_device_has_dc_support(adev)) {
1484                        mutex_lock(&adev->pm.mutex);
1485                        amdgpu_dpm_get_active_displays(adev);
1486                        adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;
1487                        adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
1488                        adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
1489                        /* we have issues with mclk switching with
1490                         * refresh rates over 120 hz on the non-DC code.
1491                         */
1492                        if (adev->pm.pm_display_cfg.vrefresh > 120)
1493                                adev->pm.pm_display_cfg.min_vblank_time = 0;
1494                        if (adev->powerplay.pp_funcs->display_configuration_change)
1495                                adev->powerplay.pp_funcs->display_configuration_change(
1496                                                        adev->powerplay.pp_handle,
1497                                                        &adev->pm.pm_display_cfg);
1498                        mutex_unlock(&adev->pm.mutex);
1499                }
1500                amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_DISPLAY_CONFIG_CHANGE, NULL);
1501        } else {
1502                mutex_lock(&adev->pm.mutex);
1503                amdgpu_dpm_get_active_displays(adev);
1504                amdgpu_dpm_change_power_state_locked(adev);
1505                mutex_unlock(&adev->pm.mutex);
1506        }
1507}
1508
1509void amdgpu_dpm_enable_uvd(struct amdgpu_device *adev, bool enable)
1510{
1511        int ret = 0;
1512
1513        if (adev->family == AMDGPU_FAMILY_SI) {
1514                mutex_lock(&adev->pm.mutex);
1515                if (enable) {
1516                        adev->pm.dpm.uvd_active = true;
1517                        adev->pm.dpm.state = POWER_STATE_TYPE_INTERNAL_UVD;
1518                } else {
1519                        adev->pm.dpm.uvd_active = false;
1520                }
1521                mutex_unlock(&adev->pm.mutex);
1522
1523                amdgpu_pm_compute_clocks(adev);
1524        } else {
1525                ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_UVD, !enable);
1526                if (ret)
1527                        DRM_ERROR("Dpm %s uvd failed, ret = %d. \n",
1528                                  enable ? "enable" : "disable", ret);
1529
1530                /* enable/disable Low Memory PState for UVD (4k videos) */
1531                if (adev->asic_type == CHIP_STONEY &&
1532                        adev->uvd.decode_image_width >= WIDTH_4K) {
1533                        struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle;
1534
1535                        if (hwmgr && hwmgr->hwmgr_func &&
1536                            hwmgr->hwmgr_func->update_nbdpm_pstate)
1537                                hwmgr->hwmgr_func->update_nbdpm_pstate(hwmgr,
1538                                                                       !enable,
1539                                                                       true);
1540                }
1541        }
1542}
1543
1544void amdgpu_dpm_enable_vce(struct amdgpu_device *adev, bool enable)
1545{
1546        int ret = 0;
1547
1548        if (adev->family == AMDGPU_FAMILY_SI) {
1549                mutex_lock(&adev->pm.mutex);
1550                if (enable) {
1551                        adev->pm.dpm.vce_active = true;
1552                        /* XXX select vce level based on ring/task */
1553                        adev->pm.dpm.vce_level = AMD_VCE_LEVEL_AC_ALL;
1554                } else {
1555                        adev->pm.dpm.vce_active = false;
1556                }
1557                mutex_unlock(&adev->pm.mutex);
1558
1559                amdgpu_pm_compute_clocks(adev);
1560        } else {
1561                ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_VCE, !enable);
1562                if (ret)
1563                        DRM_ERROR("Dpm %s vce failed, ret = %d. \n",
1564                                  enable ? "enable" : "disable", ret);
1565        }
1566}
1567
1568void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
1569{
1570        int i;
1571
1572        if (adev->powerplay.pp_funcs->print_power_state == NULL)
1573                return;
1574
1575        for (i = 0; i < adev->pm.dpm.num_ps; i++)
1576                amdgpu_dpm_print_power_state(adev, &adev->pm.dpm.ps[i]);
1577
1578}
1579
1580void amdgpu_dpm_enable_jpeg(struct amdgpu_device *adev, bool enable)
1581{
1582        int ret = 0;
1583
1584        ret = amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_JPEG, !enable);
1585        if (ret)
1586                DRM_ERROR("Dpm %s jpeg failed, ret = %d. \n",
1587                          enable ? "enable" : "disable", ret);
1588}
1589
1590int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
1591{
1592        int r;
1593
1594        if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
1595                r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
1596                if (r) {
1597                        pr_err("smu firmware loading failed\n");
1598                        return r;
1599                }
1600
1601                if (smu_version)
1602                        *smu_version = adev->pm.fw_version;
1603        }
1604
1605        return 0;
1606}
1607