root/drivers/gpu/drm/radeon/r600_dpm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. r600_dpm_print_class_info
  2. r600_dpm_print_cap_info
  3. r600_dpm_print_ps_status
  4. r600_dpm_get_vblank_time
  5. r600_dpm_get_vrefresh
  6. r600_calculate_u_and_p
  7. r600_calculate_at
  8. r600_gfx_clockgating_enable
  9. r600_dynamicpm_enable
  10. r600_enable_thermal_protection
  11. r600_enable_acpi_pm
  12. r600_enable_dynamic_pcie_gen2
  13. r600_dynamicpm_enabled
  14. r600_enable_sclk_control
  15. r600_enable_mclk_control
  16. r600_enable_spll_bypass
  17. r600_wait_for_spll_change
  18. r600_set_bsp
  19. r600_set_at
  20. r600_set_tc
  21. r600_select_td
  22. r600_set_vrc
  23. r600_set_tpu
  24. r600_set_tpc
  25. r600_set_sstu
  26. r600_set_sst
  27. r600_set_git
  28. r600_set_fctu
  29. r600_set_fct
  30. r600_set_ctxcgtt3d_rphc
  31. r600_set_ctxcgtt3d_rsdc
  32. r600_set_vddc3d_oorsu
  33. r600_set_vddc3d_oorphc
  34. r600_set_vddc3d_oorsdc
  35. r600_set_mpll_lock_time
  36. r600_set_mpll_reset_time
  37. r600_engine_clock_entry_enable
  38. r600_engine_clock_entry_enable_pulse_skipping
  39. r600_engine_clock_entry_enable_post_divider
  40. r600_engine_clock_entry_set_post_divider
  41. r600_engine_clock_entry_set_reference_divider
  42. r600_engine_clock_entry_set_feedback_divider
  43. r600_engine_clock_entry_set_step_time
  44. r600_vid_rt_set_ssu
  45. r600_vid_rt_set_vru
  46. r600_vid_rt_set_vrt
  47. r600_voltage_control_enable_pins
  48. r600_voltage_control_program_voltages
  49. r600_voltage_control_deactivate_static_control
  50. r600_power_level_enable
  51. r600_power_level_set_voltage_index
  52. r600_power_level_set_mem_clock_index
  53. r600_power_level_set_eng_clock_index
  54. r600_power_level_set_watermark_id
  55. r600_power_level_set_pcie_gen2
  56. r600_power_level_get_current_index
  57. r600_power_level_get_target_index
  58. r600_power_level_set_enter_index
  59. r600_wait_for_power_level_unequal
  60. r600_wait_for_power_level
  61. r600_start_dpm
  62. r600_stop_dpm
  63. r600_dpm_pre_set_power_state
  64. r600_dpm_post_set_power_state
  65. r600_is_uvd_state
  66. r600_set_thermal_temperature_range
  67. r600_is_internal_thermal_sensor
  68. r600_dpm_late_enable
  69. r600_parse_clk_voltage_dep_table
  70. r600_get_platform_caps
  71. r600_parse_extended_power_table
  72. r600_free_extended_power_table
  73. r600_get_pcie_gen_support
  74. r600_get_pcie_lane_support
  75. r600_encode_pci_lane_width

   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 "radeon.h"
  26 #include "radeon_asic.h"
  27 #include "r600d.h"
  28 #include "r600_dpm.h"
  29 #include "atom.h"
  30 
  31 const u32 r600_utc[R600_PM_NUMBER_OF_TC] =
  32 {
  33         R600_UTC_DFLT_00,
  34         R600_UTC_DFLT_01,
  35         R600_UTC_DFLT_02,
  36         R600_UTC_DFLT_03,
  37         R600_UTC_DFLT_04,
  38         R600_UTC_DFLT_05,
  39         R600_UTC_DFLT_06,
  40         R600_UTC_DFLT_07,
  41         R600_UTC_DFLT_08,
  42         R600_UTC_DFLT_09,
  43         R600_UTC_DFLT_10,
  44         R600_UTC_DFLT_11,
  45         R600_UTC_DFLT_12,
  46         R600_UTC_DFLT_13,
  47         R600_UTC_DFLT_14,
  48 };
  49 
  50 const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =
  51 {
  52         R600_DTC_DFLT_00,
  53         R600_DTC_DFLT_01,
  54         R600_DTC_DFLT_02,
  55         R600_DTC_DFLT_03,
  56         R600_DTC_DFLT_04,
  57         R600_DTC_DFLT_05,
  58         R600_DTC_DFLT_06,
  59         R600_DTC_DFLT_07,
  60         R600_DTC_DFLT_08,
  61         R600_DTC_DFLT_09,
  62         R600_DTC_DFLT_10,
  63         R600_DTC_DFLT_11,
  64         R600_DTC_DFLT_12,
  65         R600_DTC_DFLT_13,
  66         R600_DTC_DFLT_14,
  67 };
  68 
  69 void r600_dpm_print_class_info(u32 class, u32 class2)
  70 {
  71         const char *s;
  72 
  73         switch (class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) {
  74         case ATOM_PPLIB_CLASSIFICATION_UI_NONE:
  75         default:
  76                 s = "none";
  77                 break;
  78         case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY:
  79                 s = "battery";
  80                 break;
  81         case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED:
  82                 s = "balanced";
  83                 break;
  84         case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE:
  85                 s = "performance";
  86                 break;
  87         }
  88         printk("\tui class: %s\n", s);
  89 
  90         printk("\tinternal class:");
  91         if (((class & ~ATOM_PPLIB_CLASSIFICATION_UI_MASK) == 0) &&
  92             (class2 == 0))
  93                 pr_cont(" none");
  94         else {
  95                 if (class & ATOM_PPLIB_CLASSIFICATION_BOOT)
  96                         pr_cont(" boot");
  97                 if (class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
  98                         pr_cont(" thermal");
  99                 if (class & ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE)
 100                         pr_cont(" limited_pwr");
 101                 if (class & ATOM_PPLIB_CLASSIFICATION_REST)
 102                         pr_cont(" rest");
 103                 if (class & ATOM_PPLIB_CLASSIFICATION_FORCED)
 104                         pr_cont(" forced");
 105                 if (class & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE)
 106                         pr_cont(" 3d_perf");
 107                 if (class & ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE)
 108                         pr_cont(" ovrdrv");
 109                 if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
 110                         pr_cont(" uvd");
 111                 if (class & ATOM_PPLIB_CLASSIFICATION_3DLOW)
 112                         pr_cont(" 3d_low");
 113                 if (class & ATOM_PPLIB_CLASSIFICATION_ACPI)
 114                         pr_cont(" acpi");
 115                 if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
 116                         pr_cont(" uvd_hd2");
 117                 if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
 118                         pr_cont(" uvd_hd");
 119                 if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
 120                         pr_cont(" uvd_sd");
 121                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2)
 122                         pr_cont(" limited_pwr2");
 123                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_ULV)
 124                         pr_cont(" ulv");
 125                 if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
 126                         pr_cont(" uvd_mvc");
 127         }
 128         pr_cont("\n");
 129 }
 130 
 131 void r600_dpm_print_cap_info(u32 caps)
 132 {
 133         printk("\tcaps:");
 134         if (caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY)
 135                 pr_cont(" single_disp");
 136         if (caps & ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK)
 137                 pr_cont(" video");
 138         if (caps & ATOM_PPLIB_DISALLOW_ON_DC)
 139                 pr_cont(" no_dc");
 140         pr_cont("\n");
 141 }
 142 
 143 void r600_dpm_print_ps_status(struct radeon_device *rdev,
 144                               struct radeon_ps *rps)
 145 {
 146         printk("\tstatus:");
 147         if (rps == rdev->pm.dpm.current_ps)
 148                 pr_cont(" c");
 149         if (rps == rdev->pm.dpm.requested_ps)
 150                 pr_cont(" r");
 151         if (rps == rdev->pm.dpm.boot_ps)
 152                 pr_cont(" b");
 153         pr_cont("\n");
 154 }
 155 
 156 u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
 157 {
 158         struct drm_device *dev = rdev->ddev;
 159         struct drm_crtc *crtc;
 160         struct radeon_crtc *radeon_crtc;
 161         u32 vblank_in_pixels;
 162         u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 163 
 164         if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
 165                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 166                         radeon_crtc = to_radeon_crtc(crtc);
 167                         if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
 168                                 vblank_in_pixels =
 169                                         radeon_crtc->hw_mode.crtc_htotal *
 170                                         (radeon_crtc->hw_mode.crtc_vblank_end -
 171                                          radeon_crtc->hw_mode.crtc_vdisplay +
 172                                          (radeon_crtc->v_border * 2));
 173 
 174                                 vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
 175                                 break;
 176                         }
 177                 }
 178         }
 179 
 180         return vblank_time_us;
 181 }
 182 
 183 u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
 184 {
 185         struct drm_device *dev = rdev->ddev;
 186         struct drm_crtc *crtc;
 187         struct radeon_crtc *radeon_crtc;
 188         u32 vrefresh = 0;
 189 
 190         if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
 191                 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 192                         radeon_crtc = to_radeon_crtc(crtc);
 193                         if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
 194                                 vrefresh = drm_mode_vrefresh(&radeon_crtc->hw_mode);
 195                                 break;
 196                         }
 197                 }
 198         }
 199         return vrefresh;
 200 }
 201 
 202 void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
 203                             u32 *p, u32 *u)
 204 {
 205         u32 b_c = 0;
 206         u32 i_c;
 207         u32 tmp;
 208 
 209         i_c = (i * r_c) / 100;
 210         tmp = i_c >> p_b;
 211 
 212         while (tmp) {
 213                 b_c++;
 214                 tmp >>= 1;
 215         }
 216 
 217         *u = (b_c + 1) / 2;
 218         *p = i_c / (1 << (2 * (*u)));
 219 }
 220 
 221 int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
 222 {
 223         u32 k, a, ah, al;
 224         u32 t1;
 225 
 226         if ((fl == 0) || (fh == 0) || (fl > fh))
 227                 return -EINVAL;
 228 
 229         k = (100 * fh) / fl;
 230         t1 = (t * (k - 100));
 231         a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
 232         a = (a + 5) / 10;
 233         ah = ((a * t) + 5000) / 10000;
 234         al = a - ah;
 235 
 236         *th = t - ah;
 237         *tl = t + al;
 238 
 239         return 0;
 240 }
 241 
 242 void r600_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
 243 {
 244         int i;
 245 
 246         if (enable) {
 247                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
 248         } else {
 249                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
 250 
 251                 WREG32(CG_RLC_REQ_AND_RSP, 0x2);
 252 
 253                 for (i = 0; i < rdev->usec_timeout; i++) {
 254                         if (((RREG32(CG_RLC_REQ_AND_RSP) & CG_RLC_RSP_TYPE_MASK) >> CG_RLC_RSP_TYPE_SHIFT) == 1)
 255                                 break;
 256                         udelay(1);
 257                 }
 258 
 259                 WREG32(CG_RLC_REQ_AND_RSP, 0x0);
 260 
 261                 WREG32(GRBM_PWR_CNTL, 0x1);
 262                 RREG32(GRBM_PWR_CNTL);
 263         }
 264 }
 265 
 266 void r600_dynamicpm_enable(struct radeon_device *rdev, bool enable)
 267 {
 268         if (enable)
 269                 WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
 270         else
 271                 WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
 272 }
 273 
 274 void r600_enable_thermal_protection(struct radeon_device *rdev, bool enable)
 275 {
 276         if (enable)
 277                 WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
 278         else
 279                 WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
 280 }
 281 
 282 void r600_enable_acpi_pm(struct radeon_device *rdev)
 283 {
 284         WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
 285 }
 286 
 287 void r600_enable_dynamic_pcie_gen2(struct radeon_device *rdev, bool enable)
 288 {
 289         if (enable)
 290                 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
 291         else
 292                 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
 293 }
 294 
 295 bool r600_dynamicpm_enabled(struct radeon_device *rdev)
 296 {
 297         if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
 298                 return true;
 299         else
 300                 return false;
 301 }
 302 
 303 void r600_enable_sclk_control(struct radeon_device *rdev, bool enable)
 304 {
 305         if (enable)
 306                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
 307         else
 308                 WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
 309 }
 310 
 311 void r600_enable_mclk_control(struct radeon_device *rdev, bool enable)
 312 {
 313         if (enable)
 314                 WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
 315         else
 316                 WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
 317 }
 318 
 319 void r600_enable_spll_bypass(struct radeon_device *rdev, bool enable)
 320 {
 321         if (enable)
 322                 WREG32_P(CG_SPLL_FUNC_CNTL, SPLL_BYPASS_EN, ~SPLL_BYPASS_EN);
 323         else
 324                 WREG32_P(CG_SPLL_FUNC_CNTL, 0, ~SPLL_BYPASS_EN);
 325 }
 326 
 327 void r600_wait_for_spll_change(struct radeon_device *rdev)
 328 {
 329         int i;
 330 
 331         for (i = 0; i < rdev->usec_timeout; i++) {
 332                 if (RREG32(CG_SPLL_FUNC_CNTL) & SPLL_CHG_STATUS)
 333                         break;
 334                 udelay(1);
 335         }
 336 }
 337 
 338 void r600_set_bsp(struct radeon_device *rdev, u32 u, u32 p)
 339 {
 340         WREG32(CG_BSP, BSP(p) | BSU(u));
 341 }
 342 
 343 void r600_set_at(struct radeon_device *rdev,
 344                  u32 l_to_m, u32 m_to_h,
 345                  u32 h_to_m, u32 m_to_l)
 346 {
 347         WREG32(CG_RT, FLS(l_to_m) | FMS(m_to_h));
 348         WREG32(CG_LT, FHS(h_to_m) | FMS(m_to_l));
 349 }
 350 
 351 void r600_set_tc(struct radeon_device *rdev,
 352                  u32 index, u32 u_t, u32 d_t)
 353 {
 354         WREG32(CG_FFCT_0 + (index * 4), UTC_0(u_t) | DTC_0(d_t));
 355 }
 356 
 357 void r600_select_td(struct radeon_device *rdev,
 358                     enum r600_td td)
 359 {
 360         if (td == R600_TD_AUTO)
 361                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
 362         else
 363                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
 364         if (td == R600_TD_UP)
 365                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
 366         if (td == R600_TD_DOWN)
 367                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
 368 }
 369 
 370 void r600_set_vrc(struct radeon_device *rdev, u32 vrv)
 371 {
 372         WREG32(CG_FTV, vrv);
 373 }
 374 
 375 void r600_set_tpu(struct radeon_device *rdev, u32 u)
 376 {
 377         WREG32_P(CG_TPC, TPU(u), ~TPU_MASK);
 378 }
 379 
 380 void r600_set_tpc(struct radeon_device *rdev, u32 c)
 381 {
 382         WREG32_P(CG_TPC, TPCC(c), ~TPCC_MASK);
 383 }
 384 
 385 void r600_set_sstu(struct radeon_device *rdev, u32 u)
 386 {
 387         WREG32_P(CG_SSP, CG_SSTU(u), ~CG_SSTU_MASK);
 388 }
 389 
 390 void r600_set_sst(struct radeon_device *rdev, u32 t)
 391 {
 392         WREG32_P(CG_SSP, CG_SST(t), ~CG_SST_MASK);
 393 }
 394 
 395 void r600_set_git(struct radeon_device *rdev, u32 t)
 396 {
 397         WREG32_P(CG_GIT, CG_GICST(t), ~CG_GICST_MASK);
 398 }
 399 
 400 void r600_set_fctu(struct radeon_device *rdev, u32 u)
 401 {
 402         WREG32_P(CG_FC_T, FC_TU(u), ~FC_TU_MASK);
 403 }
 404 
 405 void r600_set_fct(struct radeon_device *rdev, u32 t)
 406 {
 407         WREG32_P(CG_FC_T, FC_T(t), ~FC_T_MASK);
 408 }
 409 
 410 void r600_set_ctxcgtt3d_rphc(struct radeon_device *rdev, u32 p)
 411 {
 412         WREG32_P(CG_CTX_CGTT3D_R, PHC(p), ~PHC_MASK);
 413 }
 414 
 415 void r600_set_ctxcgtt3d_rsdc(struct radeon_device *rdev, u32 s)
 416 {
 417         WREG32_P(CG_CTX_CGTT3D_R, SDC(s), ~SDC_MASK);
 418 }
 419 
 420 void r600_set_vddc3d_oorsu(struct radeon_device *rdev, u32 u)
 421 {
 422         WREG32_P(CG_VDDC3D_OOR, SU(u), ~SU_MASK);
 423 }
 424 
 425 void r600_set_vddc3d_oorphc(struct radeon_device *rdev, u32 p)
 426 {
 427         WREG32_P(CG_VDDC3D_OOR, PHC(p), ~PHC_MASK);
 428 }
 429 
 430 void r600_set_vddc3d_oorsdc(struct radeon_device *rdev, u32 s)
 431 {
 432         WREG32_P(CG_VDDC3D_OOR, SDC(s), ~SDC_MASK);
 433 }
 434 
 435 void r600_set_mpll_lock_time(struct radeon_device *rdev, u32 lock_time)
 436 {
 437         WREG32_P(MPLL_TIME, MPLL_LOCK_TIME(lock_time), ~MPLL_LOCK_TIME_MASK);
 438 }
 439 
 440 void r600_set_mpll_reset_time(struct radeon_device *rdev, u32 reset_time)
 441 {
 442         WREG32_P(MPLL_TIME, MPLL_RESET_TIME(reset_time), ~MPLL_RESET_TIME_MASK);
 443 }
 444 
 445 void r600_engine_clock_entry_enable(struct radeon_device *rdev,
 446                                     u32 index, bool enable)
 447 {
 448         if (enable)
 449                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 450                          STEP_0_SPLL_ENTRY_VALID, ~STEP_0_SPLL_ENTRY_VALID);
 451         else
 452                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 453                          0, ~STEP_0_SPLL_ENTRY_VALID);
 454 }
 455 
 456 void r600_engine_clock_entry_enable_pulse_skipping(struct radeon_device *rdev,
 457                                                    u32 index, bool enable)
 458 {
 459         if (enable)
 460                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 461                          STEP_0_SPLL_STEP_ENABLE, ~STEP_0_SPLL_STEP_ENABLE);
 462         else
 463                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 464                          0, ~STEP_0_SPLL_STEP_ENABLE);
 465 }
 466 
 467 void r600_engine_clock_entry_enable_post_divider(struct radeon_device *rdev,
 468                                                  u32 index, bool enable)
 469 {
 470         if (enable)
 471                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 472                          STEP_0_POST_DIV_EN, ~STEP_0_POST_DIV_EN);
 473         else
 474                 WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART2 + (index * 4 * 2),
 475                          0, ~STEP_0_POST_DIV_EN);
 476 }
 477 
 478 void r600_engine_clock_entry_set_post_divider(struct radeon_device *rdev,
 479                                               u32 index, u32 divider)
 480 {
 481         WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
 482                  STEP_0_SPLL_POST_DIV(divider), ~STEP_0_SPLL_POST_DIV_MASK);
 483 }
 484 
 485 void r600_engine_clock_entry_set_reference_divider(struct radeon_device *rdev,
 486                                                    u32 index, u32 divider)
 487 {
 488         WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
 489                  STEP_0_SPLL_REF_DIV(divider), ~STEP_0_SPLL_REF_DIV_MASK);
 490 }
 491 
 492 void r600_engine_clock_entry_set_feedback_divider(struct radeon_device *rdev,
 493                                                   u32 index, u32 divider)
 494 {
 495         WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
 496                  STEP_0_SPLL_FB_DIV(divider), ~STEP_0_SPLL_FB_DIV_MASK);
 497 }
 498 
 499 void r600_engine_clock_entry_set_step_time(struct radeon_device *rdev,
 500                                            u32 index, u32 step_time)
 501 {
 502         WREG32_P(SCLK_FREQ_SETTING_STEP_0_PART1 + (index * 4 * 2),
 503                  STEP_0_SPLL_STEP_TIME(step_time), ~STEP_0_SPLL_STEP_TIME_MASK);
 504 }
 505 
 506 void r600_vid_rt_set_ssu(struct radeon_device *rdev, u32 u)
 507 {
 508         WREG32_P(VID_RT, SSTU(u), ~SSTU_MASK);
 509 }
 510 
 511 void r600_vid_rt_set_vru(struct radeon_device *rdev, u32 u)
 512 {
 513         WREG32_P(VID_RT, VID_CRTU(u), ~VID_CRTU_MASK);
 514 }
 515 
 516 void r600_vid_rt_set_vrt(struct radeon_device *rdev, u32 rt)
 517 {
 518         WREG32_P(VID_RT, VID_CRT(rt), ~VID_CRT_MASK);
 519 }
 520 
 521 void r600_voltage_control_enable_pins(struct radeon_device *rdev,
 522                                       u64 mask)
 523 {
 524         WREG32(LOWER_GPIO_ENABLE, mask & 0xffffffff);
 525         WREG32(UPPER_GPIO_ENABLE, upper_32_bits(mask));
 526 }
 527 
 528 
 529 void r600_voltage_control_program_voltages(struct radeon_device *rdev,
 530                                            enum r600_power_level index, u64 pins)
 531 {
 532         u32 tmp, mask;
 533         u32 ix = 3 - (3 & index);
 534 
 535         WREG32(CTXSW_VID_LOWER_GPIO_CNTL + (ix * 4), pins & 0xffffffff);
 536 
 537         mask = 7 << (3 * ix);
 538         tmp = RREG32(VID_UPPER_GPIO_CNTL);
 539         tmp = (tmp & ~mask) | ((pins >> (32 - (3 * ix))) & mask);
 540         WREG32(VID_UPPER_GPIO_CNTL, tmp);
 541 }
 542 
 543 void r600_voltage_control_deactivate_static_control(struct radeon_device *rdev,
 544                                                     u64 mask)
 545 {
 546         u32 gpio;
 547 
 548         gpio = RREG32(GPIOPAD_MASK);
 549         gpio &= ~mask;
 550         WREG32(GPIOPAD_MASK, gpio);
 551 
 552         gpio = RREG32(GPIOPAD_EN);
 553         gpio &= ~mask;
 554         WREG32(GPIOPAD_EN, gpio);
 555 
 556         gpio = RREG32(GPIOPAD_A);
 557         gpio &= ~mask;
 558         WREG32(GPIOPAD_A, gpio);
 559 }
 560 
 561 void r600_power_level_enable(struct radeon_device *rdev,
 562                              enum r600_power_level index, bool enable)
 563 {
 564         u32 ix = 3 - (3 & index);
 565 
 566         if (enable)
 567                 WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), CTXSW_FREQ_STATE_ENABLE,
 568                          ~CTXSW_FREQ_STATE_ENABLE);
 569         else
 570                 WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), 0,
 571                          ~CTXSW_FREQ_STATE_ENABLE);
 572 }
 573 
 574 void r600_power_level_set_voltage_index(struct radeon_device *rdev,
 575                                         enum r600_power_level index, u32 voltage_index)
 576 {
 577         u32 ix = 3 - (3 & index);
 578 
 579         WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
 580                  CTXSW_FREQ_VIDS_CFG_INDEX(voltage_index), ~CTXSW_FREQ_VIDS_CFG_INDEX_MASK);
 581 }
 582 
 583 void r600_power_level_set_mem_clock_index(struct radeon_device *rdev,
 584                                           enum r600_power_level index, u32 mem_clock_index)
 585 {
 586         u32 ix = 3 - (3 & index);
 587 
 588         WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
 589                  CTXSW_FREQ_MCLK_CFG_INDEX(mem_clock_index), ~CTXSW_FREQ_MCLK_CFG_INDEX_MASK);
 590 }
 591 
 592 void r600_power_level_set_eng_clock_index(struct radeon_device *rdev,
 593                                           enum r600_power_level index, u32 eng_clock_index)
 594 {
 595         u32 ix = 3 - (3 & index);
 596 
 597         WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4),
 598                  CTXSW_FREQ_SCLK_CFG_INDEX(eng_clock_index), ~CTXSW_FREQ_SCLK_CFG_INDEX_MASK);
 599 }
 600 
 601 void r600_power_level_set_watermark_id(struct radeon_device *rdev,
 602                                        enum r600_power_level index,
 603                                        enum r600_display_watermark watermark_id)
 604 {
 605         u32 ix = 3 - (3 & index);
 606         u32 tmp = 0;
 607 
 608         if (watermark_id == R600_DISPLAY_WATERMARK_HIGH)
 609                 tmp = CTXSW_FREQ_DISPLAY_WATERMARK;
 610         WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_DISPLAY_WATERMARK);
 611 }
 612 
 613 void r600_power_level_set_pcie_gen2(struct radeon_device *rdev,
 614                                     enum r600_power_level index, bool compatible)
 615 {
 616         u32 ix = 3 - (3 & index);
 617         u32 tmp = 0;
 618 
 619         if (compatible)
 620                 tmp = CTXSW_FREQ_GEN2PCIE_VOLT;
 621         WREG32_P(CTXSW_PROFILE_INDEX + (ix * 4), tmp, ~CTXSW_FREQ_GEN2PCIE_VOLT);
 622 }
 623 
 624 enum r600_power_level r600_power_level_get_current_index(struct radeon_device *rdev)
 625 {
 626         u32 tmp;
 627 
 628         tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK;
 629         tmp >>= CURRENT_PROFILE_INDEX_SHIFT;
 630         return tmp;
 631 }
 632 
 633 enum r600_power_level r600_power_level_get_target_index(struct radeon_device *rdev)
 634 {
 635         u32 tmp;
 636 
 637         tmp = RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_PROFILE_INDEX_MASK;
 638         tmp >>= TARGET_PROFILE_INDEX_SHIFT;
 639         return tmp;
 640 }
 641 
 642 void r600_power_level_set_enter_index(struct radeon_device *rdev,
 643                                       enum r600_power_level index)
 644 {
 645         WREG32_P(TARGET_AND_CURRENT_PROFILE_INDEX, DYN_PWR_ENTER_INDEX(index),
 646                  ~DYN_PWR_ENTER_INDEX_MASK);
 647 }
 648 
 649 void r600_wait_for_power_level_unequal(struct radeon_device *rdev,
 650                                        enum r600_power_level index)
 651 {
 652         int i;
 653 
 654         for (i = 0; i < rdev->usec_timeout; i++) {
 655                 if (r600_power_level_get_target_index(rdev) != index)
 656                         break;
 657                 udelay(1);
 658         }
 659 
 660         for (i = 0; i < rdev->usec_timeout; i++) {
 661                 if (r600_power_level_get_current_index(rdev) != index)
 662                         break;
 663                 udelay(1);
 664         }
 665 }
 666 
 667 void r600_wait_for_power_level(struct radeon_device *rdev,
 668                                enum r600_power_level index)
 669 {
 670         int i;
 671 
 672         for (i = 0; i < rdev->usec_timeout; i++) {
 673                 if (r600_power_level_get_target_index(rdev) == index)
 674                         break;
 675                 udelay(1);
 676         }
 677 
 678         for (i = 0; i < rdev->usec_timeout; i++) {
 679                 if (r600_power_level_get_current_index(rdev) == index)
 680                         break;
 681                 udelay(1);
 682         }
 683 }
 684 
 685 void r600_start_dpm(struct radeon_device *rdev)
 686 {
 687         r600_enable_sclk_control(rdev, false);
 688         r600_enable_mclk_control(rdev, false);
 689 
 690         r600_dynamicpm_enable(rdev, true);
 691 
 692         radeon_wait_for_vblank(rdev, 0);
 693         radeon_wait_for_vblank(rdev, 1);
 694 
 695         r600_enable_spll_bypass(rdev, true);
 696         r600_wait_for_spll_change(rdev);
 697         r600_enable_spll_bypass(rdev, false);
 698         r600_wait_for_spll_change(rdev);
 699 
 700         r600_enable_spll_bypass(rdev, true);
 701         r600_wait_for_spll_change(rdev);
 702         r600_enable_spll_bypass(rdev, false);
 703         r600_wait_for_spll_change(rdev);
 704 
 705         r600_enable_sclk_control(rdev, true);
 706         r600_enable_mclk_control(rdev, true);
 707 }
 708 
 709 void r600_stop_dpm(struct radeon_device *rdev)
 710 {
 711         r600_dynamicpm_enable(rdev, false);
 712 }
 713 
 714 int r600_dpm_pre_set_power_state(struct radeon_device *rdev)
 715 {
 716         return 0;
 717 }
 718 
 719 void r600_dpm_post_set_power_state(struct radeon_device *rdev)
 720 {
 721 
 722 }
 723 
 724 bool r600_is_uvd_state(u32 class, u32 class2)
 725 {
 726         if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
 727                 return true;
 728         if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
 729                 return true;
 730         if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
 731                 return true;
 732         if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
 733                 return true;
 734         if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
 735                 return true;
 736         return false;
 737 }
 738 
 739 static int r600_set_thermal_temperature_range(struct radeon_device *rdev,
 740                                               int min_temp, int max_temp)
 741 {
 742         int low_temp = 0 * 1000;
 743         int high_temp = 255 * 1000;
 744 
 745         if (low_temp < min_temp)
 746                 low_temp = min_temp;
 747         if (high_temp > max_temp)
 748                 high_temp = max_temp;
 749         if (high_temp < low_temp) {
 750                 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
 751                 return -EINVAL;
 752         }
 753 
 754         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
 755         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
 756         WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
 757 
 758         rdev->pm.dpm.thermal.min_temp = low_temp;
 759         rdev->pm.dpm.thermal.max_temp = high_temp;
 760 
 761         return 0;
 762 }
 763 
 764 bool r600_is_internal_thermal_sensor(enum radeon_int_thermal_type sensor)
 765 {
 766         switch (sensor) {
 767         case THERMAL_TYPE_RV6XX:
 768         case THERMAL_TYPE_RV770:
 769         case THERMAL_TYPE_EVERGREEN:
 770         case THERMAL_TYPE_SUMO:
 771         case THERMAL_TYPE_NI:
 772         case THERMAL_TYPE_SI:
 773         case THERMAL_TYPE_CI:
 774         case THERMAL_TYPE_KV:
 775                 return true;
 776         case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
 777         case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
 778                 return false; /* need special handling */
 779         case THERMAL_TYPE_NONE:
 780         case THERMAL_TYPE_EXTERNAL:
 781         case THERMAL_TYPE_EXTERNAL_GPIO:
 782         default:
 783                 return false;
 784         }
 785 }
 786 
 787 int r600_dpm_late_enable(struct radeon_device *rdev)
 788 {
 789         int ret;
 790 
 791         if (rdev->irq.installed &&
 792             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
 793                 ret = r600_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
 794                 if (ret)
 795                         return ret;
 796                 rdev->irq.dpm_thermal = true;
 797                 radeon_irq_set(rdev);
 798         }
 799 
 800         return 0;
 801 }
 802 
 803 union power_info {
 804         struct _ATOM_POWERPLAY_INFO info;
 805         struct _ATOM_POWERPLAY_INFO_V2 info_2;
 806         struct _ATOM_POWERPLAY_INFO_V3 info_3;
 807         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
 808         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
 809         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
 810         struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
 811         struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
 812 };
 813 
 814 union fan_info {
 815         struct _ATOM_PPLIB_FANTABLE fan;
 816         struct _ATOM_PPLIB_FANTABLE2 fan2;
 817         struct _ATOM_PPLIB_FANTABLE3 fan3;
 818 };
 819 
 820 static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependency_table *radeon_table,
 821                                             ATOM_PPLIB_Clock_Voltage_Dependency_Table *atom_table)
 822 {
 823         u32 size = atom_table->ucNumEntries *
 824                 sizeof(struct radeon_clock_voltage_dependency_entry);
 825         int i;
 826         ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry;
 827 
 828         radeon_table->entries = kzalloc(size, GFP_KERNEL);
 829         if (!radeon_table->entries)
 830                 return -ENOMEM;
 831 
 832         entry = &atom_table->entries[0];
 833         for (i = 0; i < atom_table->ucNumEntries; i++) {
 834                 radeon_table->entries[i].clk = le16_to_cpu(entry->usClockLow) |
 835                         (entry->ucClockHigh << 16);
 836                 radeon_table->entries[i].v = le16_to_cpu(entry->usVoltage);
 837                 entry = (ATOM_PPLIB_Clock_Voltage_Dependency_Record *)
 838                         ((u8 *)entry + sizeof(ATOM_PPLIB_Clock_Voltage_Dependency_Record));
 839         }
 840         radeon_table->count = atom_table->ucNumEntries;
 841 
 842         return 0;
 843 }
 844 
 845 int r600_get_platform_caps(struct radeon_device *rdev)
 846 {
 847         struct radeon_mode_info *mode_info = &rdev->mode_info;
 848         union power_info *power_info;
 849         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
 850         u16 data_offset;
 851         u8 frev, crev;
 852 
 853         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
 854                                    &frev, &crev, &data_offset))
 855                 return -EINVAL;
 856         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
 857 
 858         rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
 859         rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
 860         rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
 861 
 862         return 0;
 863 }
 864 
 865 /* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
 866 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
 867 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
 868 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
 869 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
 870 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
 871 #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
 872 
 873 int r600_parse_extended_power_table(struct radeon_device *rdev)
 874 {
 875         struct radeon_mode_info *mode_info = &rdev->mode_info;
 876         union power_info *power_info;
 877         union fan_info *fan_info;
 878         ATOM_PPLIB_Clock_Voltage_Dependency_Table *dep_table;
 879         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
 880         u16 data_offset;
 881         u8 frev, crev;
 882         int ret, i;
 883 
 884         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
 885                                    &frev, &crev, &data_offset))
 886                 return -EINVAL;
 887         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
 888 
 889         /* fan table */
 890         if (le16_to_cpu(power_info->pplib.usTableSize) >=
 891             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
 892                 if (power_info->pplib3.usFanTableOffset) {
 893                         fan_info = (union fan_info *)(mode_info->atom_context->bios + data_offset +
 894                                                       le16_to_cpu(power_info->pplib3.usFanTableOffset));
 895                         rdev->pm.dpm.fan.t_hyst = fan_info->fan.ucTHyst;
 896                         rdev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
 897                         rdev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
 898                         rdev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
 899                         rdev->pm.dpm.fan.pwm_min = le16_to_cpu(fan_info->fan.usPWMMin);
 900                         rdev->pm.dpm.fan.pwm_med = le16_to_cpu(fan_info->fan.usPWMMed);
 901                         rdev->pm.dpm.fan.pwm_high = le16_to_cpu(fan_info->fan.usPWMHigh);
 902                         if (fan_info->fan.ucFanTableFormat >= 2)
 903                                 rdev->pm.dpm.fan.t_max = le16_to_cpu(fan_info->fan2.usTMax);
 904                         else
 905                                 rdev->pm.dpm.fan.t_max = 10900;
 906                         rdev->pm.dpm.fan.cycle_delay = 100000;
 907                         if (fan_info->fan.ucFanTableFormat >= 3) {
 908                                 rdev->pm.dpm.fan.control_mode = fan_info->fan3.ucFanControlMode;
 909                                 rdev->pm.dpm.fan.default_max_fan_pwm =
 910                                         le16_to_cpu(fan_info->fan3.usFanPWMMax);
 911                                 rdev->pm.dpm.fan.default_fan_output_sensitivity = 4836;
 912                                 rdev->pm.dpm.fan.fan_output_sensitivity =
 913                                         le16_to_cpu(fan_info->fan3.usFanOutputSensitivity);
 914                         }
 915                         rdev->pm.dpm.fan.ucode_fan_control = true;
 916                 }
 917         }
 918 
 919         /* clock dependancy tables, shedding tables */
 920         if (le16_to_cpu(power_info->pplib.usTableSize) >=
 921             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE4)) {
 922                 if (power_info->pplib4.usVddcDependencyOnSCLKOffset) {
 923                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 924                                 (mode_info->atom_context->bios + data_offset +
 925                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset));
 926                         ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
 927                                                                dep_table);
 928                         if (ret)
 929                                 return ret;
 930                 }
 931                 if (power_info->pplib4.usVddciDependencyOnMCLKOffset) {
 932                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 933                                 (mode_info->atom_context->bios + data_offset +
 934                                  le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset));
 935                         ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
 936                                                                dep_table);
 937                         if (ret) {
 938                                 kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
 939                                 return ret;
 940                         }
 941                 }
 942                 if (power_info->pplib4.usVddcDependencyOnMCLKOffset) {
 943                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 944                                 (mode_info->atom_context->bios + data_offset +
 945                                  le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset));
 946                         ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
 947                                                                dep_table);
 948                         if (ret) {
 949                                 kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
 950                                 kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
 951                                 return ret;
 952                         }
 953                 }
 954                 if (power_info->pplib4.usMvddDependencyOnMCLKOffset) {
 955                         dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *)
 956                                 (mode_info->atom_context->bios + data_offset +
 957                                  le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset));
 958                         ret = r600_parse_clk_voltage_dep_table(&rdev->pm.dpm.dyn_state.mvdd_dependency_on_mclk,
 959                                                                dep_table);
 960                         if (ret) {
 961                                 kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries);
 962                                 kfree(rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk.entries);
 963                                 kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk.entries);
 964                                 return ret;
 965                         }
 966                 }
 967                 if (power_info->pplib4.usMaxClockVoltageOnDCOffset) {
 968                         ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v =
 969                                 (ATOM_PPLIB_Clock_Voltage_Limit_Table *)
 970                                 (mode_info->atom_context->bios + data_offset +
 971                                  le16_to_cpu(power_info->pplib4.usMaxClockVoltageOnDCOffset));
 972                         if (clk_v->ucNumEntries) {
 973                                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk =
 974                                         le16_to_cpu(clk_v->entries[0].usSclkLow) |
 975                                         (clk_v->entries[0].ucSclkHigh << 16);
 976                                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk =
 977                                         le16_to_cpu(clk_v->entries[0].usMclkLow) |
 978                                         (clk_v->entries[0].ucMclkHigh << 16);
 979                                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc =
 980                                         le16_to_cpu(clk_v->entries[0].usVddc);
 981                                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddci =
 982                                         le16_to_cpu(clk_v->entries[0].usVddci);
 983                         }
 984                 }
 985                 if (power_info->pplib4.usVddcPhaseShedLimitsTableOffset) {
 986                         ATOM_PPLIB_PhaseSheddingLimits_Table *psl =
 987                                 (ATOM_PPLIB_PhaseSheddingLimits_Table *)
 988                                 (mode_info->atom_context->bios + data_offset +
 989                                  le16_to_cpu(power_info->pplib4.usVddcPhaseShedLimitsTableOffset));
 990                         ATOM_PPLIB_PhaseSheddingLimits_Record *entry;
 991 
 992                         rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries =
 993                                 kcalloc(psl->ucNumEntries,
 994                                         sizeof(struct radeon_phase_shedding_limits_entry),
 995                                         GFP_KERNEL);
 996                         if (!rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) {
 997                                 r600_free_extended_power_table(rdev);
 998                                 return -ENOMEM;
 999                         }
1000 
1001                         entry = &psl->entries[0];
1002                         for (i = 0; i < psl->ucNumEntries; i++) {
1003                                 rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].sclk =
1004                                         le16_to_cpu(entry->usSclkLow) | (entry->ucSclkHigh << 16);
1005                                 rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].mclk =
1006                                         le16_to_cpu(entry->usMclkLow) | (entry->ucMclkHigh << 16);
1007                                 rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries[i].voltage =
1008                                         le16_to_cpu(entry->usVoltage);
1009                                 entry = (ATOM_PPLIB_PhaseSheddingLimits_Record *)
1010                                         ((u8 *)entry + sizeof(ATOM_PPLIB_PhaseSheddingLimits_Record));
1011                         }
1012                         rdev->pm.dpm.dyn_state.phase_shedding_limits_table.count =
1013                                 psl->ucNumEntries;
1014                 }
1015         }
1016 
1017         /* cac data */
1018         if (le16_to_cpu(power_info->pplib.usTableSize) >=
1019             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE5)) {
1020                 rdev->pm.dpm.tdp_limit = le32_to_cpu(power_info->pplib5.ulTDPLimit);
1021                 rdev->pm.dpm.near_tdp_limit = le32_to_cpu(power_info->pplib5.ulNearTDPLimit);
1022                 rdev->pm.dpm.near_tdp_limit_adjusted = rdev->pm.dpm.near_tdp_limit;
1023                 rdev->pm.dpm.tdp_od_limit = le16_to_cpu(power_info->pplib5.usTDPODLimit);
1024                 if (rdev->pm.dpm.tdp_od_limit)
1025                         rdev->pm.dpm.power_control = true;
1026                 else
1027                         rdev->pm.dpm.power_control = false;
1028                 rdev->pm.dpm.tdp_adjustment = 0;
1029                 rdev->pm.dpm.sq_ramping_threshold = le32_to_cpu(power_info->pplib5.ulSQRampingThreshold);
1030                 rdev->pm.dpm.cac_leakage = le32_to_cpu(power_info->pplib5.ulCACLeakage);
1031                 rdev->pm.dpm.load_line_slope = le16_to_cpu(power_info->pplib5.usLoadLineSlope);
1032                 if (power_info->pplib5.usCACLeakageTableOffset) {
1033                         ATOM_PPLIB_CAC_Leakage_Table *cac_table =
1034                                 (ATOM_PPLIB_CAC_Leakage_Table *)
1035                                 (mode_info->atom_context->bios + data_offset +
1036                                  le16_to_cpu(power_info->pplib5.usCACLeakageTableOffset));
1037                         ATOM_PPLIB_CAC_Leakage_Record *entry;
1038                         u32 size = cac_table->ucNumEntries * sizeof(struct radeon_cac_leakage_table);
1039                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL);
1040                         if (!rdev->pm.dpm.dyn_state.cac_leakage_table.entries) {
1041                                 r600_free_extended_power_table(rdev);
1042                                 return -ENOMEM;
1043                         }
1044                         entry = &cac_table->entries[0];
1045                         for (i = 0; i < cac_table->ucNumEntries; i++) {
1046                                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) {
1047                                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc1 =
1048                                                 le16_to_cpu(entry->usVddc1);
1049                                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc2 =
1050                                                 le16_to_cpu(entry->usVddc2);
1051                                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc3 =
1052                                                 le16_to_cpu(entry->usVddc3);
1053                                 } else {
1054                                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].vddc =
1055                                                 le16_to_cpu(entry->usVddc);
1056                                         rdev->pm.dpm.dyn_state.cac_leakage_table.entries[i].leakage =
1057                                                 le32_to_cpu(entry->ulLeakageValue);
1058                                 }
1059                                 entry = (ATOM_PPLIB_CAC_Leakage_Record *)
1060                                         ((u8 *)entry + sizeof(ATOM_PPLIB_CAC_Leakage_Record));
1061                         }
1062                         rdev->pm.dpm.dyn_state.cac_leakage_table.count = cac_table->ucNumEntries;
1063                 }
1064         }
1065 
1066         /* ext tables */
1067         if (le16_to_cpu(power_info->pplib.usTableSize) >=
1068             sizeof(struct _ATOM_PPLIB_POWERPLAYTABLE3)) {
1069                 ATOM_PPLIB_EXTENDEDHEADER *ext_hdr = (ATOM_PPLIB_EXTENDEDHEADER *)
1070                         (mode_info->atom_context->bios + data_offset +
1071                          le16_to_cpu(power_info->pplib3.usExtendendedHeaderOffset));
1072                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2) &&
1073                         ext_hdr->usVCETableOffset) {
1074                         VCEClockInfoArray *array = (VCEClockInfoArray *)
1075                                 (mode_info->atom_context->bios + data_offset +
1076                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1);
1077                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *limits =
1078                                 (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table *)
1079                                 (mode_info->atom_context->bios + data_offset +
1080                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1081                                  1 + array->ucNumEntries * sizeof(VCEClockInfo));
1082                         ATOM_PPLIB_VCE_State_Table *states =
1083                                 (ATOM_PPLIB_VCE_State_Table *)
1084                                 (mode_info->atom_context->bios + data_offset +
1085                                  le16_to_cpu(ext_hdr->usVCETableOffset) + 1 +
1086                                  1 + (array->ucNumEntries * sizeof (VCEClockInfo)) +
1087                                  1 + (limits->numEntries * sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record)));
1088                         ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *entry;
1089                         ATOM_PPLIB_VCE_State_Record *state_entry;
1090                         VCEClockInfo *vce_clk;
1091                         u32 size = limits->numEntries *
1092                                 sizeof(struct radeon_vce_clock_voltage_dependency_entry);
1093                         rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries =
1094                                 kzalloc(size, GFP_KERNEL);
1095                         if (!rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) {
1096                                 r600_free_extended_power_table(rdev);
1097                                 return -ENOMEM;
1098                         }
1099                         rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count =
1100                                 limits->numEntries;
1101                         entry = &limits->entries[0];
1102                         state_entry = &states->entries[0];
1103                         for (i = 0; i < limits->numEntries; i++) {
1104                                 vce_clk = (VCEClockInfo *)
1105                                         ((u8 *)&array->entries[0] +
1106                                          (entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
1107                                 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].evclk =
1108                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
1109                                 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].ecclk =
1110                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
1111                                 rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries[i].v =
1112                                         le16_to_cpu(entry->usVoltage);
1113                                 entry = (ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record *)
1114                                         ((u8 *)entry + sizeof(ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record));
1115                         }
1116                         for (i = 0; i < states->numEntries; i++) {
1117                                 if (i >= RADEON_MAX_VCE_LEVELS)
1118                                         break;
1119                                 vce_clk = (VCEClockInfo *)
1120                                         ((u8 *)&array->entries[0] +
1121                                          (state_entry->ucVCEClockInfoIndex * sizeof(VCEClockInfo)));
1122                                 rdev->pm.dpm.vce_states[i].evclk =
1123                                         le16_to_cpu(vce_clk->usEVClkLow) | (vce_clk->ucEVClkHigh << 16);
1124                                 rdev->pm.dpm.vce_states[i].ecclk =
1125                                         le16_to_cpu(vce_clk->usECClkLow) | (vce_clk->ucECClkHigh << 16);
1126                                 rdev->pm.dpm.vce_states[i].clk_idx =
1127                                         state_entry->ucClockInfoIndex & 0x3f;
1128                                 rdev->pm.dpm.vce_states[i].pstate =
1129                                         (state_entry->ucClockInfoIndex & 0xc0) >> 6;
1130                                 state_entry = (ATOM_PPLIB_VCE_State_Record *)
1131                                         ((u8 *)state_entry + sizeof(ATOM_PPLIB_VCE_State_Record));
1132                         }
1133                 }
1134                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3) &&
1135                         ext_hdr->usUVDTableOffset) {
1136                         UVDClockInfoArray *array = (UVDClockInfoArray *)
1137                                 (mode_info->atom_context->bios + data_offset +
1138                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1);
1139                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *limits =
1140                                 (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table *)
1141                                 (mode_info->atom_context->bios + data_offset +
1142                                  le16_to_cpu(ext_hdr->usUVDTableOffset) + 1 +
1143                                  1 + (array->ucNumEntries * sizeof (UVDClockInfo)));
1144                         ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *entry;
1145                         u32 size = limits->numEntries *
1146                                 sizeof(struct radeon_uvd_clock_voltage_dependency_entry);
1147                         rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries =
1148                                 kzalloc(size, GFP_KERNEL);
1149                         if (!rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) {
1150                                 r600_free_extended_power_table(rdev);
1151                                 return -ENOMEM;
1152                         }
1153                         rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count =
1154                                 limits->numEntries;
1155                         entry = &limits->entries[0];
1156                         for (i = 0; i < limits->numEntries; i++) {
1157                                 UVDClockInfo *uvd_clk = (UVDClockInfo *)
1158                                         ((u8 *)&array->entries[0] +
1159                                          (entry->ucUVDClockInfoIndex * sizeof(UVDClockInfo)));
1160                                 rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].vclk =
1161                                         le16_to_cpu(uvd_clk->usVClkLow) | (uvd_clk->ucVClkHigh << 16);
1162                                 rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].dclk =
1163                                         le16_to_cpu(uvd_clk->usDClkLow) | (uvd_clk->ucDClkHigh << 16);
1164                                 rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries[i].v =
1165                                         le16_to_cpu(entry->usVoltage);
1166                                 entry = (ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record *)
1167                                         ((u8 *)entry + sizeof(ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record));
1168                         }
1169                 }
1170                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4) &&
1171                         ext_hdr->usSAMUTableOffset) {
1172                         ATOM_PPLIB_SAMClk_Voltage_Limit_Table *limits =
1173                                 (ATOM_PPLIB_SAMClk_Voltage_Limit_Table *)
1174                                 (mode_info->atom_context->bios + data_offset +
1175                                  le16_to_cpu(ext_hdr->usSAMUTableOffset) + 1);
1176                         ATOM_PPLIB_SAMClk_Voltage_Limit_Record *entry;
1177                         u32 size = limits->numEntries *
1178                                 sizeof(struct radeon_clock_voltage_dependency_entry);
1179                         rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries =
1180                                 kzalloc(size, GFP_KERNEL);
1181                         if (!rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) {
1182                                 r600_free_extended_power_table(rdev);
1183                                 return -ENOMEM;
1184                         }
1185                         rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count =
1186                                 limits->numEntries;
1187                         entry = &limits->entries[0];
1188                         for (i = 0; i < limits->numEntries; i++) {
1189                                 rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].clk =
1190                                         le16_to_cpu(entry->usSAMClockLow) | (entry->ucSAMClockHigh << 16);
1191                                 rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries[i].v =
1192                                         le16_to_cpu(entry->usVoltage);
1193                                 entry = (ATOM_PPLIB_SAMClk_Voltage_Limit_Record *)
1194                                         ((u8 *)entry + sizeof(ATOM_PPLIB_SAMClk_Voltage_Limit_Record));
1195                         }
1196                 }
1197                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5) &&
1198                     ext_hdr->usPPMTableOffset) {
1199                         ATOM_PPLIB_PPM_Table *ppm = (ATOM_PPLIB_PPM_Table *)
1200                                 (mode_info->atom_context->bios + data_offset +
1201                                  le16_to_cpu(ext_hdr->usPPMTableOffset));
1202                         rdev->pm.dpm.dyn_state.ppm_table =
1203                                 kzalloc(sizeof(struct radeon_ppm_table), GFP_KERNEL);
1204                         if (!rdev->pm.dpm.dyn_state.ppm_table) {
1205                                 r600_free_extended_power_table(rdev);
1206                                 return -ENOMEM;
1207                         }
1208                         rdev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign;
1209                         rdev->pm.dpm.dyn_state.ppm_table->cpu_core_number =
1210                                 le16_to_cpu(ppm->usCpuCoreNumber);
1211                         rdev->pm.dpm.dyn_state.ppm_table->platform_tdp =
1212                                 le32_to_cpu(ppm->ulPlatformTDP);
1213                         rdev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdp =
1214                                 le32_to_cpu(ppm->ulSmallACPlatformTDP);
1215                         rdev->pm.dpm.dyn_state.ppm_table->platform_tdc =
1216                                 le32_to_cpu(ppm->ulPlatformTDC);
1217                         rdev->pm.dpm.dyn_state.ppm_table->small_ac_platform_tdc =
1218                                 le32_to_cpu(ppm->ulSmallACPlatformTDC);
1219                         rdev->pm.dpm.dyn_state.ppm_table->apu_tdp =
1220                                 le32_to_cpu(ppm->ulApuTDP);
1221                         rdev->pm.dpm.dyn_state.ppm_table->dgpu_tdp =
1222                                 le32_to_cpu(ppm->ulDGpuTDP);
1223                         rdev->pm.dpm.dyn_state.ppm_table->dgpu_ulv_power =
1224                                 le32_to_cpu(ppm->ulDGpuUlvPower);
1225                         rdev->pm.dpm.dyn_state.ppm_table->tj_max =
1226                                 le32_to_cpu(ppm->ulTjmax);
1227                 }
1228                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6) &&
1229                         ext_hdr->usACPTableOffset) {
1230                         ATOM_PPLIB_ACPClk_Voltage_Limit_Table *limits =
1231                                 (ATOM_PPLIB_ACPClk_Voltage_Limit_Table *)
1232                                 (mode_info->atom_context->bios + data_offset +
1233                                  le16_to_cpu(ext_hdr->usACPTableOffset) + 1);
1234                         ATOM_PPLIB_ACPClk_Voltage_Limit_Record *entry;
1235                         u32 size = limits->numEntries *
1236                                 sizeof(struct radeon_clock_voltage_dependency_entry);
1237                         rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries =
1238                                 kzalloc(size, GFP_KERNEL);
1239                         if (!rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) {
1240                                 r600_free_extended_power_table(rdev);
1241                                 return -ENOMEM;
1242                         }
1243                         rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count =
1244                                 limits->numEntries;
1245                         entry = &limits->entries[0];
1246                         for (i = 0; i < limits->numEntries; i++) {
1247                                 rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].clk =
1248                                         le16_to_cpu(entry->usACPClockLow) | (entry->ucACPClockHigh << 16);
1249                                 rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries[i].v =
1250                                         le16_to_cpu(entry->usVoltage);
1251                                 entry = (ATOM_PPLIB_ACPClk_Voltage_Limit_Record *)
1252                                         ((u8 *)entry + sizeof(ATOM_PPLIB_ACPClk_Voltage_Limit_Record));
1253                         }
1254                 }
1255                 if ((le16_to_cpu(ext_hdr->usSize) >= SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7) &&
1256                         ext_hdr->usPowerTuneTableOffset) {
1257                         u8 rev = *(u8 *)(mode_info->atom_context->bios + data_offset +
1258                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
1259                         ATOM_PowerTune_Table *pt;
1260                         rdev->pm.dpm.dyn_state.cac_tdp_table =
1261                                 kzalloc(sizeof(struct radeon_cac_tdp_table), GFP_KERNEL);
1262                         if (!rdev->pm.dpm.dyn_state.cac_tdp_table) {
1263                                 r600_free_extended_power_table(rdev);
1264                                 return -ENOMEM;
1265                         }
1266                         if (rev > 0) {
1267                                 ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *)
1268                                         (mode_info->atom_context->bios + data_offset +
1269                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
1270                                 rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit =
1271                                         le16_to_cpu(ppt->usMaximumPowerDeliveryLimit);
1272                                 pt = &ppt->power_tune_table;
1273                         } else {
1274                                 ATOM_PPLIB_POWERTUNE_Table *ppt = (ATOM_PPLIB_POWERTUNE_Table *)
1275                                         (mode_info->atom_context->bios + data_offset +
1276                                          le16_to_cpu(ext_hdr->usPowerTuneTableOffset));
1277                                 rdev->pm.dpm.dyn_state.cac_tdp_table->maximum_power_delivery_limit = 255;
1278                                 pt = &ppt->power_tune_table;
1279                         }
1280                         rdev->pm.dpm.dyn_state.cac_tdp_table->tdp = le16_to_cpu(pt->usTDP);
1281                         rdev->pm.dpm.dyn_state.cac_tdp_table->configurable_tdp =
1282                                 le16_to_cpu(pt->usConfigurableTDP);
1283                         rdev->pm.dpm.dyn_state.cac_tdp_table->tdc = le16_to_cpu(pt->usTDC);
1284                         rdev->pm.dpm.dyn_state.cac_tdp_table->battery_power_limit =
1285                                 le16_to_cpu(pt->usBatteryPowerLimit);
1286                         rdev->pm.dpm.dyn_state.cac_tdp_table->small_power_limit =
1287                                 le16_to_cpu(pt->usSmallPowerLimit);
1288                         rdev->pm.dpm.dyn_state.cac_tdp_table->low_cac_leakage =
1289                                 le16_to_cpu(pt->usLowCACLeakage);
1290                         rdev->pm.dpm.dyn_state.cac_tdp_table->high_cac_leakage =
1291                                 le16_to_cpu(pt->usHighCACLeakage);
1292                 }
1293         }
1294 
1295         return 0;
1296 }
1297 
1298 void r600_free_extended_power_table(struct radeon_device *rdev)
1299 {
1300         struct radeon_dpm_dynamic_state *dyn_state = &rdev->pm.dpm.dyn_state;
1301 
1302         kfree(dyn_state->vddc_dependency_on_sclk.entries);
1303         kfree(dyn_state->vddci_dependency_on_mclk.entries);
1304         kfree(dyn_state->vddc_dependency_on_mclk.entries);
1305         kfree(dyn_state->mvdd_dependency_on_mclk.entries);
1306         kfree(dyn_state->cac_leakage_table.entries);
1307         kfree(dyn_state->phase_shedding_limits_table.entries);
1308         kfree(dyn_state->ppm_table);
1309         kfree(dyn_state->cac_tdp_table);
1310         kfree(dyn_state->vce_clock_voltage_dependency_table.entries);
1311         kfree(dyn_state->uvd_clock_voltage_dependency_table.entries);
1312         kfree(dyn_state->samu_clock_voltage_dependency_table.entries);
1313         kfree(dyn_state->acp_clock_voltage_dependency_table.entries);
1314 }
1315 
1316 enum radeon_pcie_gen r600_get_pcie_gen_support(struct radeon_device *rdev,
1317                                                u32 sys_mask,
1318                                                enum radeon_pcie_gen asic_gen,
1319                                                enum radeon_pcie_gen default_gen)
1320 {
1321         switch (asic_gen) {
1322         case RADEON_PCIE_GEN1:
1323                 return RADEON_PCIE_GEN1;
1324         case RADEON_PCIE_GEN2:
1325                 return RADEON_PCIE_GEN2;
1326         case RADEON_PCIE_GEN3:
1327                 return RADEON_PCIE_GEN3;
1328         default:
1329                 if ((sys_mask & RADEON_PCIE_SPEED_80) && (default_gen == RADEON_PCIE_GEN3))
1330                         return RADEON_PCIE_GEN3;
1331                 else if ((sys_mask & RADEON_PCIE_SPEED_50) && (default_gen == RADEON_PCIE_GEN2))
1332                         return RADEON_PCIE_GEN2;
1333                 else
1334                         return RADEON_PCIE_GEN1;
1335         }
1336         return RADEON_PCIE_GEN1;
1337 }
1338 
1339 u16 r600_get_pcie_lane_support(struct radeon_device *rdev,
1340                                u16 asic_lanes,
1341                                u16 default_lanes)
1342 {
1343         switch (asic_lanes) {
1344         case 0:
1345         default:
1346                 return default_lanes;
1347         case 1:
1348                 return 1;
1349         case 2:
1350                 return 2;
1351         case 4:
1352                 return 4;
1353         case 8:
1354                 return 8;
1355         case 12:
1356                 return 12;
1357         case 16:
1358                 return 16;
1359         }
1360 }
1361 
1362 u8 r600_encode_pci_lane_width(u32 lanes)
1363 {
1364         u8 encoded_lanes[] = { 0, 1, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6 };
1365 
1366         if (lanes > 16)
1367                 return 0;
1368 
1369         return encoded_lanes[lanes];
1370 }

/* [<][>][^][v][top][bottom][index][help] */