LCOV - code coverage report
Current view: top level - dev/pci/drm/radeon - rv770_dpm.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1470 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 103 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <dev/pci/drm/drmP.h>
      26             : #include "radeon.h"
      27             : #include "radeon_asic.h"
      28             : #include "rv770d.h"
      29             : #include "r600_dpm.h"
      30             : #include "rv770_dpm.h"
      31             : #include "cypress_dpm.h"
      32             : #include "atom.h"
      33             : 
      34             : #define MC_CG_ARB_FREQ_F0           0x0a
      35             : #define MC_CG_ARB_FREQ_F1           0x0b
      36             : #define MC_CG_ARB_FREQ_F2           0x0c
      37             : #define MC_CG_ARB_FREQ_F3           0x0d
      38             : 
      39             : #define MC_CG_SEQ_DRAMCONF_S0       0x05
      40             : #define MC_CG_SEQ_DRAMCONF_S1       0x06
      41             : 
      42             : #define PCIE_BUS_CLK                10000
      43             : #define TCLK                        (PCIE_BUS_CLK / 10)
      44             : 
      45             : #define SMC_RAM_END 0xC000
      46             : 
      47           0 : struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps)
      48             : {
      49           0 :         struct rv7xx_ps *ps = rps->ps_priv;
      50             : 
      51           0 :         return ps;
      52             : }
      53             : 
      54           0 : struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev)
      55             : {
      56           0 :         struct rv7xx_power_info *pi = rdev->pm.dpm.priv;
      57             : 
      58           0 :         return pi;
      59             : }
      60             : 
      61           0 : struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev)
      62             : {
      63           0 :         struct evergreen_power_info *pi = rdev->pm.dpm.priv;
      64             : 
      65           0 :         return pi;
      66             : }
      67             : 
      68           0 : static void rv770_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
      69             :                                                bool enable)
      70             : {
      71           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
      72             :         u32 tmp;
      73             : 
      74           0 :         tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
      75           0 :         if (enable) {
      76           0 :                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
      77           0 :                 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
      78           0 :                 tmp |= LC_GEN2_EN_STRAP;
      79           0 :         } else {
      80           0 :                 if (!pi->boot_in_gen2) {
      81           0 :                         tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
      82           0 :                         tmp &= ~LC_GEN2_EN_STRAP;
      83           0 :                 }
      84             :         }
      85           0 :         if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
      86           0 :             (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
      87           0 :                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
      88             : 
      89           0 : }
      90             : 
      91           0 : static void rv770_enable_l0s(struct radeon_device *rdev)
      92             : {
      93             :         u32 tmp;
      94             : 
      95           0 :         tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L0S_INACTIVITY_MASK;
      96           0 :         tmp |= LC_L0S_INACTIVITY(3);
      97           0 :         WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
      98           0 : }
      99             : 
     100           0 : static void rv770_enable_l1(struct radeon_device *rdev)
     101             : {
     102             :         u32 tmp;
     103             : 
     104           0 :         tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL);
     105           0 :         tmp &= ~LC_L1_INACTIVITY_MASK;
     106           0 :         tmp |= LC_L1_INACTIVITY(4);
     107           0 :         tmp &= ~LC_PMI_TO_L1_DIS;
     108           0 :         tmp &= ~LC_ASPM_TO_L1_DIS;
     109           0 :         WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
     110           0 : }
     111             : 
     112           0 : static void rv770_enable_pll_sleep_in_l1(struct radeon_device *rdev)
     113             : {
     114             :         u32 tmp;
     115             : 
     116           0 :         tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL) & ~LC_L1_INACTIVITY_MASK;
     117           0 :         tmp |= LC_L1_INACTIVITY(8);
     118           0 :         WREG32_PCIE_PORT(PCIE_LC_CNTL, tmp);
     119             : 
     120             :         /* NOTE, this is a PCIE indirect reg, not PCIE PORT */
     121           0 :         tmp = RREG32_PCIE(PCIE_P_CNTL);
     122           0 :         tmp |= P_PLL_PWRDN_IN_L1L23;
     123           0 :         tmp &= ~P_PLL_BUF_PDNB;
     124           0 :         tmp &= ~P_PLL_PDNB;
     125           0 :         tmp |= P_ALLOW_PRX_FRONTEND_SHUTOFF;
     126           0 :         WREG32_PCIE(PCIE_P_CNTL, tmp);
     127           0 : }
     128             : 
     129           0 : static void rv770_gfx_clock_gating_enable(struct radeon_device *rdev,
     130             :                                           bool enable)
     131             : {
     132           0 :         if (enable)
     133           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
     134             :         else {
     135           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
     136           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
     137           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
     138           0 :                 RREG32(GB_TILING_CONFIG);
     139             :         }
     140           0 : }
     141             : 
     142           0 : static void rv770_mg_clock_gating_enable(struct radeon_device *rdev,
     143             :                                          bool enable)
     144             : {
     145           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     146             : 
     147           0 :         if (enable) {
     148             :                 u32 mgcg_cgtt_local0;
     149             : 
     150           0 :                 if (rdev->family == CHIP_RV770)
     151           0 :                         mgcg_cgtt_local0 = RV770_MGCGTTLOCAL0_DFLT;
     152             :                 else
     153             :                         mgcg_cgtt_local0 = RV7XX_MGCGTTLOCAL0_DFLT;
     154             : 
     155           0 :                 WREG32(CG_CGTT_LOCAL_0, mgcg_cgtt_local0);
     156           0 :                 WREG32(CG_CGTT_LOCAL_1, (RV770_MGCGTTLOCAL1_DFLT & 0xFFFFCFFF));
     157             : 
     158           0 :                 if (pi->mgcgtssm)
     159           0 :                         WREG32(CGTS_SM_CTRL_REG, RV770_MGCGCGTSSMCTRL_DFLT);
     160           0 :         } else {
     161           0 :                 WREG32(CG_CGTT_LOCAL_0, 0xFFFFFFFF);
     162           0 :                 WREG32(CG_CGTT_LOCAL_1, 0xFFFFCFFF);
     163             :         }
     164           0 : }
     165             : 
     166           0 : void rv770_restore_cgcg(struct radeon_device *rdev)
     167             : {
     168             :         bool dpm_en = false, cg_en = false;
     169             : 
     170           0 :         if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
     171           0 :                 dpm_en = true;
     172           0 :         if (RREG32(SCLK_PWRMGT_CNTL) & DYN_GFX_CLK_OFF_EN)
     173           0 :                 cg_en = true;
     174             : 
     175           0 :         if (dpm_en && !cg_en)
     176           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
     177           0 : }
     178             : 
     179           0 : static void rv770_start_dpm(struct radeon_device *rdev)
     180             : {
     181           0 :         WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
     182             : 
     183           0 :         WREG32_P(MCLK_PWRMGT_CNTL, 0, ~MPLL_PWRMGT_OFF);
     184             : 
     185           0 :         WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
     186           0 : }
     187             : 
     188           0 : void rv770_stop_dpm(struct radeon_device *rdev)
     189             : {
     190             :         PPSMC_Result result;
     191             : 
     192           0 :         result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_TwoLevelsDisabled);
     193             : 
     194           0 :         if (result != PPSMC_Result_OK)
     195             :                 DRM_DEBUG("Could not force DPM to low.\n");
     196             : 
     197           0 :         WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
     198             : 
     199           0 :         WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
     200             : 
     201           0 :         WREG32_P(MCLK_PWRMGT_CNTL, MPLL_PWRMGT_OFF, ~MPLL_PWRMGT_OFF);
     202           0 : }
     203             : 
     204           0 : bool rv770_dpm_enabled(struct radeon_device *rdev)
     205             : {
     206           0 :         if (RREG32(GENERAL_PWRMGT) & GLOBAL_PWRMGT_EN)
     207           0 :                 return true;
     208             :         else
     209           0 :                 return false;
     210           0 : }
     211             : 
     212           0 : void rv770_enable_thermal_protection(struct radeon_device *rdev,
     213             :                                      bool enable)
     214             : {
     215           0 :         if (enable)
     216           0 :                 WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
     217             :         else
     218           0 :                 WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
     219           0 : }
     220             : 
     221           0 : void rv770_enable_acpi_pm(struct radeon_device *rdev)
     222             : {
     223           0 :         WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
     224           0 : }
     225             : 
     226           0 : u8 rv770_get_seq_value(struct radeon_device *rdev,
     227             :                        struct rv7xx_pl *pl)
     228             : {
     229           0 :         return (pl->flags & ATOM_PPLIB_R600_FLAGS_LOWPOWER) ?
     230             :                 MC_CG_SEQ_DRAMCONF_S0 : MC_CG_SEQ_DRAMCONF_S1;
     231             : }
     232             : 
     233             : #if 0
     234             : int rv770_read_smc_soft_register(struct radeon_device *rdev,
     235             :                                  u16 reg_offset, u32 *value)
     236             : {
     237             :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     238             : 
     239             :         return rv770_read_smc_sram_dword(rdev,
     240             :                                          pi->soft_regs_start + reg_offset,
     241             :                                          value, pi->sram_end);
     242             : }
     243             : #endif
     244             : 
     245           0 : int rv770_write_smc_soft_register(struct radeon_device *rdev,
     246             :                                   u16 reg_offset, u32 value)
     247             : {
     248           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     249             : 
     250           0 :         return rv770_write_smc_sram_dword(rdev,
     251           0 :                                           pi->soft_regs_start + reg_offset,
     252           0 :                                           value, pi->sram_end);
     253             : }
     254             : 
     255           0 : int rv770_populate_smc_t(struct radeon_device *rdev,
     256             :                          struct radeon_ps *radeon_state,
     257             :                          RV770_SMC_SWSTATE *smc_state)
     258             : {
     259           0 :         struct rv7xx_ps *state = rv770_get_ps(radeon_state);
     260           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     261             :         int i;
     262             :         int a_n;
     263             :         int a_d;
     264           0 :         u8 l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
     265           0 :         u8 r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
     266             :         u32 a_t;
     267             : 
     268           0 :         l[0] = 0;
     269           0 :         r[2] = 100;
     270             : 
     271           0 :         a_n = (int)state->medium.sclk * pi->lmp +
     272           0 :                 (int)state->low.sclk * (R600_AH_DFLT - pi->rlp);
     273           0 :         a_d = (int)state->low.sclk * (100 - (int)pi->rlp) +
     274             :                 (int)state->medium.sclk * pi->lmp;
     275             : 
     276           0 :         l[1] = (u8)(pi->lmp - (int)pi->lmp * a_n / a_d);
     277           0 :         r[0] = (u8)(pi->rlp + (100 - (int)pi->rlp) * a_n / a_d);
     278             : 
     279           0 :         a_n = (int)state->high.sclk * pi->lhp + (int)state->medium.sclk *
     280           0 :                 (R600_AH_DFLT - pi->rmp);
     281           0 :         a_d = (int)state->medium.sclk * (100 - (int)pi->rmp) +
     282             :                 (int)state->high.sclk * pi->lhp;
     283             : 
     284           0 :         l[2] = (u8)(pi->lhp - (int)pi->lhp * a_n / a_d);
     285           0 :         r[1] = (u8)(pi->rmp + (100 - (int)pi->rmp) * a_n / a_d);
     286             : 
     287           0 :         for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++) {
     288           0 :                 a_t = CG_R(r[i] * pi->bsp / 200) | CG_L(l[i] * pi->bsp / 200);
     289           0 :                 smc_state->levels[i].aT = cpu_to_be32(a_t);
     290             :         }
     291             : 
     292           0 :         a_t = CG_R(r[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200) |
     293           0 :                 CG_L(l[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1] * pi->pbsp / 200);
     294             : 
     295           0 :         smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].aT =
     296           0 :                 cpu_to_be32(a_t);
     297             : 
     298           0 :         return 0;
     299           0 : }
     300             : 
     301           0 : int rv770_populate_smc_sp(struct radeon_device *rdev,
     302             :                           struct radeon_ps *radeon_state,
     303             :                           RV770_SMC_SWSTATE *smc_state)
     304             : {
     305           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     306             :         int i;
     307             : 
     308           0 :         for (i = 0; i < (RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1); i++)
     309           0 :                 smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
     310             : 
     311           0 :         smc_state->levels[RV770_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1].bSP =
     312           0 :                 cpu_to_be32(pi->psp);
     313             : 
     314           0 :         return 0;
     315             : }
     316             : 
     317           0 : static void rv770_calculate_fractional_mpll_feedback_divider(u32 memory_clock,
     318             :                                                              u32 reference_clock,
     319             :                                                              bool gddr5,
     320             :                                                              struct atom_clock_dividers *dividers,
     321             :                                                              u32 *clkf,
     322             :                                                              u32 *clkfrac)
     323             : {
     324             :         u32 post_divider, reference_divider, feedback_divider8;
     325             :         u32 fyclk;
     326             : 
     327           0 :         if (gddr5)
     328           0 :                 fyclk = (memory_clock * 8) / 2;
     329             :         else
     330           0 :                 fyclk = (memory_clock * 4) / 2;
     331             : 
     332           0 :         post_divider = dividers->post_div;
     333           0 :         reference_divider = dividers->ref_div;
     334             : 
     335             :         feedback_divider8 =
     336           0 :                 (8 * fyclk * reference_divider * post_divider) / reference_clock;
     337             : 
     338           0 :         *clkf = feedback_divider8 / 8;
     339           0 :         *clkfrac = feedback_divider8 % 8;
     340           0 : }
     341             : 
     342           0 : static int rv770_encode_yclk_post_div(u32 postdiv, u32 *encoded_postdiv)
     343             : {
     344             :         int ret = 0;
     345             : 
     346           0 :         switch (postdiv) {
     347             :         case 1:
     348           0 :                 *encoded_postdiv = 0;
     349           0 :                 break;
     350             :         case 2:
     351           0 :                 *encoded_postdiv = 1;
     352           0 :                 break;
     353             :         case 4:
     354           0 :                 *encoded_postdiv = 2;
     355           0 :                 break;
     356             :         case 8:
     357           0 :                 *encoded_postdiv = 3;
     358           0 :                 break;
     359             :         case 16:
     360           0 :                 *encoded_postdiv = 4;
     361           0 :                 break;
     362             :         default:
     363             :                 ret = -EINVAL;
     364           0 :                 break;
     365             :         }
     366             : 
     367           0 :     return ret;
     368             : }
     369             : 
     370           0 : u32 rv770_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
     371             : {
     372           0 :         if (clkf <= 0x10)
     373           0 :                 return 0x4B;
     374           0 :         if (clkf <= 0x19)
     375           0 :                 return 0x5B;
     376           0 :         if (clkf <= 0x21)
     377           0 :                 return 0x2B;
     378           0 :         if (clkf <= 0x27)
     379           0 :                 return 0x6C;
     380           0 :         if (clkf <= 0x31)
     381           0 :                 return 0x9D;
     382           0 :         return 0xC6;
     383           0 : }
     384             : 
     385           0 : static int rv770_populate_mclk_value(struct radeon_device *rdev,
     386             :                                      u32 engine_clock, u32 memory_clock,
     387             :                                      RV7XX_SMC_MCLK_VALUE *mclk)
     388             : {
     389           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     390           0 :         u8 encoded_reference_dividers[] = { 0, 16, 17, 20, 21 };
     391             :         u32 mpll_ad_func_cntl =
     392           0 :                 pi->clk_regs.rv770.mpll_ad_func_cntl;
     393             :         u32 mpll_ad_func_cntl_2 =
     394           0 :                 pi->clk_regs.rv770.mpll_ad_func_cntl_2;
     395             :         u32 mpll_dq_func_cntl =
     396           0 :                 pi->clk_regs.rv770.mpll_dq_func_cntl;
     397             :         u32 mpll_dq_func_cntl_2 =
     398           0 :                 pi->clk_regs.rv770.mpll_dq_func_cntl_2;
     399             :         u32 mclk_pwrmgt_cntl =
     400           0 :                 pi->clk_regs.rv770.mclk_pwrmgt_cntl;
     401           0 :         u32 dll_cntl = pi->clk_regs.rv770.dll_cntl;
     402           0 :         struct atom_clock_dividers dividers;
     403           0 :         u32 reference_clock = rdev->clock.mpll.reference_freq;
     404           0 :         u32 clkf, clkfrac;
     405           0 :         u32 postdiv_yclk;
     406             :         u32 ibias;
     407             :         int ret;
     408             : 
     409           0 :         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
     410             :                                              memory_clock, false, &dividers);
     411           0 :         if (ret)
     412           0 :                 return ret;
     413             : 
     414           0 :         if ((dividers.ref_div < 1) || (dividers.ref_div > 5))
     415           0 :                 return -EINVAL;
     416             : 
     417           0 :         rv770_calculate_fractional_mpll_feedback_divider(memory_clock, reference_clock,
     418           0 :                                                          pi->mem_gddr5,
     419             :                                                          &dividers, &clkf, &clkfrac);
     420             : 
     421           0 :         ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
     422           0 :         if (ret)
     423           0 :                 return ret;
     424             : 
     425           0 :         ibias = rv770_map_clkf_to_ibias(rdev, clkf);
     426             : 
     427           0 :         mpll_ad_func_cntl &= ~(CLKR_MASK |
     428             :                                YCLK_POST_DIV_MASK |
     429             :                                CLKF_MASK |
     430             :                                CLKFRAC_MASK |
     431             :                                IBIAS_MASK);
     432           0 :         mpll_ad_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
     433           0 :         mpll_ad_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
     434           0 :         mpll_ad_func_cntl |= CLKF(clkf);
     435           0 :         mpll_ad_func_cntl |= CLKFRAC(clkfrac);
     436           0 :         mpll_ad_func_cntl |= IBIAS(ibias);
     437             : 
     438           0 :         if (dividers.vco_mode)
     439           0 :                 mpll_ad_func_cntl_2 |= VCO_MODE;
     440             :         else
     441           0 :                 mpll_ad_func_cntl_2 &= ~VCO_MODE;
     442             : 
     443           0 :         if (pi->mem_gddr5) {
     444           0 :                 rv770_calculate_fractional_mpll_feedback_divider(memory_clock,
     445             :                                                                  reference_clock,
     446             :                                                                  pi->mem_gddr5,
     447             :                                                                  &dividers, &clkf, &clkfrac);
     448             : 
     449           0 :                 ibias = rv770_map_clkf_to_ibias(rdev, clkf);
     450             : 
     451           0 :                 ret = rv770_encode_yclk_post_div(dividers.post_div, &postdiv_yclk);
     452           0 :                 if (ret)
     453           0 :                         return ret;
     454             : 
     455           0 :                 mpll_dq_func_cntl &= ~(CLKR_MASK |
     456             :                                        YCLK_POST_DIV_MASK |
     457             :                                        CLKF_MASK |
     458             :                                        CLKFRAC_MASK |
     459             :                                        IBIAS_MASK);
     460           0 :                 mpll_dq_func_cntl |= CLKR(encoded_reference_dividers[dividers.ref_div - 1]);
     461           0 :                 mpll_dq_func_cntl |= YCLK_POST_DIV(postdiv_yclk);
     462           0 :                 mpll_dq_func_cntl |= CLKF(clkf);
     463           0 :                 mpll_dq_func_cntl |= CLKFRAC(clkfrac);
     464           0 :                 mpll_dq_func_cntl |= IBIAS(ibias);
     465             : 
     466           0 :                 if (dividers.vco_mode)
     467           0 :                         mpll_dq_func_cntl_2 |= VCO_MODE;
     468             :                 else
     469           0 :                         mpll_dq_func_cntl_2 &= ~VCO_MODE;
     470             :         }
     471             : 
     472           0 :         mclk->mclk770.mclk_value = cpu_to_be32(memory_clock);
     473           0 :         mclk->mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
     474           0 :         mclk->mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
     475           0 :         mclk->mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
     476           0 :         mclk->mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
     477           0 :         mclk->mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
     478           0 :         mclk->mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
     479             : 
     480           0 :         return 0;
     481           0 : }
     482             : 
     483           0 : static int rv770_populate_sclk_value(struct radeon_device *rdev,
     484             :                                      u32 engine_clock,
     485             :                                      RV770_SMC_SCLK_VALUE *sclk)
     486             : {
     487           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     488           0 :         struct atom_clock_dividers dividers;
     489             :         u32 spll_func_cntl =
     490           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl;
     491             :         u32 spll_func_cntl_2 =
     492           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl_2;
     493             :         u32 spll_func_cntl_3 =
     494           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl_3;
     495             :         u32 cg_spll_spread_spectrum =
     496           0 :                 pi->clk_regs.rv770.cg_spll_spread_spectrum;
     497             :         u32 cg_spll_spread_spectrum_2 =
     498           0 :                 pi->clk_regs.rv770.cg_spll_spread_spectrum_2;
     499             :         u64 tmp;
     500           0 :         u32 reference_clock = rdev->clock.spll.reference_freq;
     501             :         u32 reference_divider, post_divider;
     502             :         u32 fbdiv;
     503             :         int ret;
     504             : 
     505           0 :         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
     506             :                                              engine_clock, false, &dividers);
     507           0 :         if (ret)
     508           0 :                 return ret;
     509             : 
     510           0 :         reference_divider = 1 + dividers.ref_div;
     511             : 
     512           0 :         if (dividers.enable_post_div)
     513           0 :                 post_divider = (0x0f & (dividers.post_div >> 4)) + (0x0f & dividers.post_div) + 2;
     514             :         else
     515             :                 post_divider = 1;
     516             : 
     517           0 :         tmp = (u64) engine_clock * reference_divider * post_divider * 16384;
     518           0 :         do_div(tmp, reference_clock);
     519           0 :         fbdiv = (u32) tmp;
     520             : 
     521           0 :         if (dividers.enable_post_div)
     522           0 :                 spll_func_cntl |= SPLL_DIVEN;
     523             :         else
     524           0 :                 spll_func_cntl &= ~SPLL_DIVEN;
     525           0 :         spll_func_cntl &= ~(SPLL_HILEN_MASK | SPLL_LOLEN_MASK | SPLL_REF_DIV_MASK);
     526           0 :         spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
     527           0 :         spll_func_cntl |= SPLL_HILEN((dividers.post_div >> 4) & 0xf);
     528           0 :         spll_func_cntl |= SPLL_LOLEN(dividers.post_div & 0xf);
     529             : 
     530           0 :         spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
     531           0 :         spll_func_cntl_2 |= SCLK_MUX_SEL(2);
     532             : 
     533           0 :         spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
     534           0 :         spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
     535           0 :         spll_func_cntl_3 |= SPLL_DITHEN;
     536             : 
     537           0 :         if (pi->sclk_ss) {
     538           0 :                 struct radeon_atom_ss ss;
     539           0 :                 u32 vco_freq = engine_clock * post_divider;
     540             : 
     541           0 :                 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
     542             :                                                      ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
     543           0 :                         u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
     544           0 :                         u32 clk_v = ss.percentage * fbdiv / (clk_s * 10000);
     545             : 
     546           0 :                         cg_spll_spread_spectrum &= ~CLKS_MASK;
     547           0 :                         cg_spll_spread_spectrum |= CLKS(clk_s);
     548           0 :                         cg_spll_spread_spectrum |= SSEN;
     549             : 
     550           0 :                         cg_spll_spread_spectrum_2 &= ~CLKV_MASK;
     551           0 :                         cg_spll_spread_spectrum_2 |= CLKV(clk_v);
     552           0 :                 }
     553           0 :         }
     554             : 
     555           0 :         sclk->sclk_value = cpu_to_be32(engine_clock);
     556           0 :         sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
     557           0 :         sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
     558           0 :         sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
     559           0 :         sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(cg_spll_spread_spectrum);
     560           0 :         sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(cg_spll_spread_spectrum_2);
     561             : 
     562           0 :         return 0;
     563           0 : }
     564             : 
     565           0 : int rv770_populate_vddc_value(struct radeon_device *rdev, u16 vddc,
     566             :                               RV770_SMC_VOLTAGE_VALUE *voltage)
     567             : {
     568           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     569             :         int i;
     570             : 
     571           0 :         if (!pi->voltage_control) {
     572           0 :                 voltage->index = 0;
     573           0 :                 voltage->value = 0;
     574           0 :                 return 0;
     575             :         }
     576             : 
     577           0 :         for (i = 0; i < pi->valid_vddc_entries; i++) {
     578           0 :                 if (vddc <= pi->vddc_table[i].vddc) {
     579           0 :                         voltage->index = pi->vddc_table[i].vddc_index;
     580           0 :                         voltage->value = cpu_to_be16(vddc);
     581           0 :                         break;
     582             :                 }
     583             :         }
     584             : 
     585           0 :         if (i == pi->valid_vddc_entries)
     586           0 :                 return -EINVAL;
     587             : 
     588           0 :         return 0;
     589           0 : }
     590             : 
     591           0 : int rv770_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
     592             :                               RV770_SMC_VOLTAGE_VALUE *voltage)
     593             : {
     594           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     595             : 
     596           0 :         if (!pi->mvdd_control) {
     597           0 :                 voltage->index = MVDD_HIGH_INDEX;
     598           0 :                 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
     599           0 :                 return 0;
     600             :         }
     601             : 
     602           0 :         if (mclk <= pi->mvdd_split_frequency) {
     603           0 :                 voltage->index = MVDD_LOW_INDEX;
     604           0 :                 voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
     605           0 :         } else {
     606           0 :                 voltage->index = MVDD_HIGH_INDEX;
     607           0 :                 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
     608             :         }
     609             : 
     610           0 :         return 0;
     611           0 : }
     612             : 
     613           0 : static int rv770_convert_power_level_to_smc(struct radeon_device *rdev,
     614             :                                             struct rv7xx_pl *pl,
     615             :                                             RV770_SMC_HW_PERFORMANCE_LEVEL *level,
     616             :                                             u8 watermark_level)
     617             : {
     618           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     619             :         int ret;
     620             : 
     621           0 :         level->gen2PCIE = pi->pcie_gen2 ?
     622           0 :                 ((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
     623           0 :         level->gen2XSP  = (pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0;
     624           0 :         level->backbias = (pl->flags & ATOM_PPLIB_R600_FLAGS_BACKBIASENABLE) ? 1 : 0;
     625           0 :         level->displayWatermark = watermark_level;
     626             : 
     627           0 :         if (rdev->family == CHIP_RV740)
     628           0 :                 ret = rv740_populate_sclk_value(rdev, pl->sclk,
     629           0 :                                                 &level->sclk);
     630           0 :         else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
     631           0 :                 ret = rv730_populate_sclk_value(rdev, pl->sclk,
     632           0 :                                                 &level->sclk);
     633             :         else
     634           0 :                 ret = rv770_populate_sclk_value(rdev, pl->sclk,
     635           0 :                                                 &level->sclk);
     636           0 :         if (ret)
     637           0 :                 return ret;
     638             : 
     639           0 :         if (rdev->family == CHIP_RV740) {
     640           0 :                 if (pi->mem_gddr5) {
     641           0 :                         if (pl->mclk <= pi->mclk_strobe_mode_threshold)
     642           0 :                                 level->strobeMode =
     643           0 :                                         rv740_get_mclk_frequency_ratio(pl->mclk) | 0x10;
     644             :                         else
     645           0 :                                 level->strobeMode = 0;
     646             : 
     647           0 :                         if (pl->mclk > pi->mclk_edc_enable_threshold)
     648           0 :                                 level->mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
     649             :                         else
     650           0 :                                 level->mcFlags =  0;
     651             :                 }
     652           0 :                 ret = rv740_populate_mclk_value(rdev, pl->sclk,
     653           0 :                                                 pl->mclk, &level->mclk);
     654           0 :         } else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
     655           0 :                 ret = rv730_populate_mclk_value(rdev, pl->sclk,
     656           0 :                                                 pl->mclk, &level->mclk);
     657             :         else
     658           0 :                 ret = rv770_populate_mclk_value(rdev, pl->sclk,
     659           0 :                                                 pl->mclk, &level->mclk);
     660           0 :         if (ret)
     661           0 :                 return ret;
     662             : 
     663           0 :         ret = rv770_populate_vddc_value(rdev, pl->vddc,
     664           0 :                                         &level->vddc);
     665           0 :         if (ret)
     666           0 :                 return ret;
     667             : 
     668           0 :         ret = rv770_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
     669             : 
     670           0 :         return ret;
     671           0 : }
     672             : 
     673           0 : static int rv770_convert_power_state_to_smc(struct radeon_device *rdev,
     674             :                                             struct radeon_ps *radeon_state,
     675             :                                             RV770_SMC_SWSTATE *smc_state)
     676             : {
     677           0 :         struct rv7xx_ps *state = rv770_get_ps(radeon_state);
     678             :         int ret;
     679             : 
     680           0 :         if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
     681           0 :                 smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
     682             : 
     683           0 :         ret = rv770_convert_power_level_to_smc(rdev,
     684           0 :                                                &state->low,
     685           0 :                                                &smc_state->levels[0],
     686             :                                                PPSMC_DISPLAY_WATERMARK_LOW);
     687           0 :         if (ret)
     688           0 :                 return ret;
     689             : 
     690           0 :         ret = rv770_convert_power_level_to_smc(rdev,
     691           0 :                                                &state->medium,
     692           0 :                                                &smc_state->levels[1],
     693             :                                                PPSMC_DISPLAY_WATERMARK_LOW);
     694           0 :         if (ret)
     695           0 :                 return ret;
     696             : 
     697           0 :         ret = rv770_convert_power_level_to_smc(rdev,
     698           0 :                                                &state->high,
     699           0 :                                                &smc_state->levels[2],
     700             :                                                PPSMC_DISPLAY_WATERMARK_HIGH);
     701           0 :         if (ret)
     702           0 :                 return ret;
     703             : 
     704           0 :         smc_state->levels[0].arbValue = MC_CG_ARB_FREQ_F1;
     705           0 :         smc_state->levels[1].arbValue = MC_CG_ARB_FREQ_F2;
     706           0 :         smc_state->levels[2].arbValue = MC_CG_ARB_FREQ_F3;
     707             : 
     708           0 :         smc_state->levels[0].seqValue = rv770_get_seq_value(rdev,
     709             :                                                             &state->low);
     710           0 :         smc_state->levels[1].seqValue = rv770_get_seq_value(rdev,
     711             :                                                             &state->medium);
     712           0 :         smc_state->levels[2].seqValue = rv770_get_seq_value(rdev,
     713             :                                                             &state->high);
     714             : 
     715           0 :         rv770_populate_smc_sp(rdev, radeon_state, smc_state);
     716             : 
     717           0 :         return rv770_populate_smc_t(rdev, radeon_state, smc_state);
     718             : 
     719           0 : }
     720             : 
     721           0 : u32 rv770_calculate_memory_refresh_rate(struct radeon_device *rdev,
     722             :                                         u32 engine_clock)
     723             : {
     724             :         u32 dram_rows;
     725             :         u32 dram_refresh_rate;
     726             :         u32 mc_arb_rfsh_rate;
     727             :         u32 tmp;
     728             : 
     729           0 :         tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
     730           0 :         dram_rows = 1 << (tmp + 10);
     731           0 :         tmp = RREG32(MC_SEQ_MISC0) & 3;
     732           0 :         dram_refresh_rate = 1 << (tmp + 3);
     733           0 :         mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
     734             : 
     735           0 :         return mc_arb_rfsh_rate;
     736             : }
     737             : 
     738           0 : static void rv770_program_memory_timing_parameters(struct radeon_device *rdev,
     739             :                                                    struct radeon_ps *radeon_state)
     740             : {
     741           0 :         struct rv7xx_ps *state = rv770_get_ps(radeon_state);
     742           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     743             :         u32 sqm_ratio;
     744             :         u32 arb_refresh_rate;
     745             :         u32 high_clock;
     746             : 
     747           0 :         if (state->high.sclk < (state->low.sclk * 0xFF / 0x40))
     748           0 :                 high_clock = state->high.sclk;
     749             :         else
     750             :                 high_clock = (state->low.sclk * 0xFF / 0x40);
     751             : 
     752           0 :         radeon_atom_set_engine_dram_timings(rdev, high_clock,
     753           0 :                                             state->high.mclk);
     754             : 
     755             :         sqm_ratio =
     756           0 :                 STATE0(64 * high_clock / pi->boot_sclk) |
     757           0 :                 STATE1(64 * high_clock / state->low.sclk) |
     758           0 :                 STATE2(64 * high_clock / state->medium.sclk) |
     759           0 :                 STATE3(64 * high_clock / state->high.sclk);
     760           0 :         WREG32(MC_ARB_SQM_RATIO, sqm_ratio);
     761             : 
     762             :         arb_refresh_rate =
     763           0 :                 POWERMODE0(rv770_calculate_memory_refresh_rate(rdev, pi->boot_sclk)) |
     764           0 :                 POWERMODE1(rv770_calculate_memory_refresh_rate(rdev, state->low.sclk)) |
     765           0 :                 POWERMODE2(rv770_calculate_memory_refresh_rate(rdev, state->medium.sclk)) |
     766           0 :                 POWERMODE3(rv770_calculate_memory_refresh_rate(rdev, state->high.sclk));
     767           0 :         WREG32(MC_ARB_RFSH_RATE, arb_refresh_rate);
     768           0 : }
     769             : 
     770           0 : void rv770_enable_backbias(struct radeon_device *rdev,
     771             :                            bool enable)
     772             : {
     773           0 :         if (enable)
     774           0 :                 WREG32_P(GENERAL_PWRMGT, BACKBIAS_PAD_EN, ~BACKBIAS_PAD_EN);
     775             :         else
     776           0 :                 WREG32_P(GENERAL_PWRMGT, 0, ~(BACKBIAS_VALUE | BACKBIAS_PAD_EN));
     777           0 : }
     778             : 
     779           0 : static void rv770_enable_spread_spectrum(struct radeon_device *rdev,
     780             :                                          bool enable)
     781             : {
     782           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     783             : 
     784           0 :         if (enable) {
     785           0 :                 if (pi->sclk_ss)
     786           0 :                         WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
     787             : 
     788           0 :                 if (pi->mclk_ss) {
     789           0 :                         if (rdev->family == CHIP_RV740)
     790           0 :                                 rv740_enable_mclk_spread_spectrum(rdev, true);
     791             :                 }
     792             :         } else {
     793           0 :                 WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
     794             : 
     795           0 :                 WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
     796             : 
     797           0 :                 WREG32_P(CG_MPLL_SPREAD_SPECTRUM, 0, ~SSEN);
     798             : 
     799           0 :                 if (rdev->family == CHIP_RV740)
     800           0 :                         rv740_enable_mclk_spread_spectrum(rdev, false);
     801             :         }
     802           0 : }
     803             : 
     804           0 : static void rv770_program_mpll_timing_parameters(struct radeon_device *rdev)
     805             : {
     806           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     807             : 
     808           0 :         if ((rdev->family == CHIP_RV770) && !pi->mem_gddr5) {
     809           0 :                 WREG32(MPLL_TIME,
     810             :                        (MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) |
     811             :                         MPLL_RESET_TIME(R600_MPLLRESETTIME_DFLT)));
     812           0 :         }
     813           0 : }
     814             : 
     815           0 : void rv770_setup_bsp(struct radeon_device *rdev)
     816             : {
     817           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     818           0 :         u32 xclk = radeon_get_xclk(rdev);
     819             : 
     820           0 :         r600_calculate_u_and_p(pi->asi,
     821             :                                xclk,
     822             :                                16,
     823           0 :                                &pi->bsp,
     824           0 :                                &pi->bsu);
     825             : 
     826           0 :         r600_calculate_u_and_p(pi->pasi,
     827             :                                xclk,
     828             :                                16,
     829           0 :                                &pi->pbsp,
     830           0 :                                &pi->pbsu);
     831             : 
     832           0 :         pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
     833           0 :         pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
     834             : 
     835           0 :         WREG32(CG_BSP, pi->dsp);
     836             : 
     837           0 : }
     838             : 
     839           0 : void rv770_program_git(struct radeon_device *rdev)
     840             : {
     841           0 :         WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
     842           0 : }
     843             : 
     844           0 : void rv770_program_tp(struct radeon_device *rdev)
     845             : {
     846             :         int i;
     847             :         enum r600_td td = R600_TD_DFLT;
     848             : 
     849           0 :         for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
     850           0 :                 WREG32(CG_FFCT_0 + (i * 4), (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
     851             : 
     852           0 :         if (td == R600_TD_AUTO)
     853           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
     854             :         else
     855           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
     856           0 :         if (td == R600_TD_UP)
     857           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
     858           0 :         if (td == R600_TD_DOWN)
     859           0 :                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
     860           0 : }
     861             : 
     862           0 : void rv770_program_tpp(struct radeon_device *rdev)
     863             : {
     864           0 :         WREG32(CG_TPC, R600_TPC_DFLT);
     865           0 : }
     866             : 
     867           0 : void rv770_program_sstp(struct radeon_device *rdev)
     868             : {
     869           0 :         WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
     870           0 : }
     871             : 
     872           0 : void rv770_program_engine_speed_parameters(struct radeon_device *rdev)
     873             : {
     874           0 :         WREG32_P(SPLL_CNTL_MODE, SPLL_DIV_SYNC, ~SPLL_DIV_SYNC);
     875           0 : }
     876             : 
     877           0 : static void rv770_enable_display_gap(struct radeon_device *rdev)
     878             : {
     879           0 :         u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
     880             : 
     881           0 :         tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
     882           0 :         tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE) |
     883             :                 DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
     884           0 :         WREG32(CG_DISPLAY_GAP_CNTL, tmp);
     885           0 : }
     886             : 
     887           0 : void rv770_program_vc(struct radeon_device *rdev)
     888             : {
     889           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     890             : 
     891           0 :         WREG32(CG_FTV, pi->vrc);
     892           0 : }
     893             : 
     894           0 : void rv770_clear_vc(struct radeon_device *rdev)
     895             : {
     896           0 :         WREG32(CG_FTV, 0);
     897           0 : }
     898             : 
     899           0 : int rv770_upload_firmware(struct radeon_device *rdev)
     900             : {
     901           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     902             :         int ret;
     903             : 
     904           0 :         rv770_reset_smc(rdev);
     905           0 :         rv770_stop_smc_clock(rdev);
     906             : 
     907           0 :         ret = rv770_load_smc_ucode(rdev, pi->sram_end);
     908           0 :         if (ret)
     909           0 :                 return ret;
     910             : 
     911           0 :         return 0;
     912           0 : }
     913             : 
     914           0 : static int rv770_populate_smc_acpi_state(struct radeon_device *rdev,
     915             :                                          RV770_SMC_STATETABLE *table)
     916             : {
     917           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
     918             : 
     919             :         u32 mpll_ad_func_cntl =
     920           0 :                 pi->clk_regs.rv770.mpll_ad_func_cntl;
     921             :         u32 mpll_ad_func_cntl_2 =
     922           0 :                 pi->clk_regs.rv770.mpll_ad_func_cntl_2;
     923             :         u32 mpll_dq_func_cntl =
     924           0 :                 pi->clk_regs.rv770.mpll_dq_func_cntl;
     925             :         u32 mpll_dq_func_cntl_2 =
     926           0 :                 pi->clk_regs.rv770.mpll_dq_func_cntl_2;
     927             :         u32 spll_func_cntl =
     928           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl;
     929             :         u32 spll_func_cntl_2 =
     930           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl_2;
     931             :         u32 spll_func_cntl_3 =
     932           0 :                 pi->clk_regs.rv770.cg_spll_func_cntl_3;
     933             :         u32 mclk_pwrmgt_cntl;
     934             :         u32 dll_cntl;
     935             : 
     936           0 :         table->ACPIState = table->initialState;
     937             : 
     938           0 :         table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
     939             : 
     940           0 :         if (pi->acpi_vddc) {
     941           0 :                 rv770_populate_vddc_value(rdev, pi->acpi_vddc,
     942           0 :                                           &table->ACPIState.levels[0].vddc);
     943           0 :                 if (pi->pcie_gen2) {
     944           0 :                         if (pi->acpi_pcie_gen2)
     945           0 :                                 table->ACPIState.levels[0].gen2PCIE = 1;
     946             :                         else
     947           0 :                                 table->ACPIState.levels[0].gen2PCIE = 0;
     948             :                 } else
     949           0 :                         table->ACPIState.levels[0].gen2PCIE = 0;
     950           0 :                 if (pi->acpi_pcie_gen2)
     951           0 :                         table->ACPIState.levels[0].gen2XSP = 1;
     952             :                 else
     953           0 :                         table->ACPIState.levels[0].gen2XSP = 0;
     954             :         } else {
     955           0 :                 rv770_populate_vddc_value(rdev, pi->min_vddc_in_table,
     956           0 :                                           &table->ACPIState.levels[0].vddc);
     957           0 :                 table->ACPIState.levels[0].gen2PCIE = 0;
     958             :         }
     959             : 
     960             : 
     961           0 :         mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
     962             : 
     963           0 :         mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
     964             : 
     965             :         mclk_pwrmgt_cntl = (MRDCKA0_RESET |
     966             :                             MRDCKA1_RESET |
     967             :                             MRDCKB0_RESET |
     968             :                             MRDCKB1_RESET |
     969             :                             MRDCKC0_RESET |
     970             :                             MRDCKC1_RESET |
     971             :                             MRDCKD0_RESET |
     972             :                             MRDCKD1_RESET);
     973             : 
     974             :         dll_cntl = 0xff000000;
     975             : 
     976           0 :         spll_func_cntl |= SPLL_RESET | SPLL_SLEEP | SPLL_BYPASS_EN;
     977             : 
     978           0 :         spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
     979           0 :         spll_func_cntl_2 |= SCLK_MUX_SEL(4);
     980             : 
     981           0 :         table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
     982           0 :         table->ACPIState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
     983           0 :         table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
     984           0 :         table->ACPIState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
     985             : 
     986           0 :         table->ACPIState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
     987           0 :         table->ACPIState.levels[0].mclk.mclk770.vDLL_CNTL = cpu_to_be32(dll_cntl);
     988             : 
     989           0 :         table->ACPIState.levels[0].mclk.mclk770.mclk_value = 0;
     990             : 
     991           0 :         table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
     992           0 :         table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
     993           0 :         table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
     994             : 
     995           0 :         table->ACPIState.levels[0].sclk.sclk_value = 0;
     996             : 
     997           0 :         rv770_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
     998             : 
     999           0 :         table->ACPIState.levels[1] = table->ACPIState.levels[0];
    1000           0 :         table->ACPIState.levels[2] = table->ACPIState.levels[0];
    1001             : 
    1002           0 :         return 0;
    1003             : }
    1004             : 
    1005           0 : int rv770_populate_initial_mvdd_value(struct radeon_device *rdev,
    1006             :                                       RV770_SMC_VOLTAGE_VALUE *voltage)
    1007             : {
    1008           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1009             : 
    1010           0 :         if ((pi->s0_vid_lower_smio_cntl & pi->mvdd_mask_low) ==
    1011           0 :              (pi->mvdd_low_smio[MVDD_LOW_INDEX] & pi->mvdd_mask_low) ) {
    1012           0 :                 voltage->index = MVDD_LOW_INDEX;
    1013           0 :                 voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
    1014           0 :         } else {
    1015           0 :                 voltage->index = MVDD_HIGH_INDEX;
    1016           0 :                 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
    1017             :         }
    1018             : 
    1019           0 :         return 0;
    1020             : }
    1021             : 
    1022           0 : static int rv770_populate_smc_initial_state(struct radeon_device *rdev,
    1023             :                                             struct radeon_ps *radeon_state,
    1024             :                                             RV770_SMC_STATETABLE *table)
    1025             : {
    1026           0 :         struct rv7xx_ps *initial_state = rv770_get_ps(radeon_state);
    1027           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1028             :         u32 a_t;
    1029             : 
    1030           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL =
    1031           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl);
    1032           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_AD_FUNC_CNTL_2 =
    1033           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_ad_func_cntl_2);
    1034           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL =
    1035           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl);
    1036           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_DQ_FUNC_CNTL_2 =
    1037           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_dq_func_cntl_2);
    1038           0 :         table->initialState.levels[0].mclk.mclk770.vMCLK_PWRMGT_CNTL =
    1039           0 :                 cpu_to_be32(pi->clk_regs.rv770.mclk_pwrmgt_cntl);
    1040           0 :         table->initialState.levels[0].mclk.mclk770.vDLL_CNTL =
    1041           0 :                 cpu_to_be32(pi->clk_regs.rv770.dll_cntl);
    1042             : 
    1043           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_SS =
    1044           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_ss1);
    1045           0 :         table->initialState.levels[0].mclk.mclk770.vMPLL_SS2 =
    1046           0 :                 cpu_to_be32(pi->clk_regs.rv770.mpll_ss2);
    1047             : 
    1048           0 :         table->initialState.levels[0].mclk.mclk770.mclk_value =
    1049           0 :                 cpu_to_be32(initial_state->low.mclk);
    1050             : 
    1051           0 :         table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
    1052           0 :                 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl);
    1053           0 :         table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
    1054           0 :                 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_2);
    1055           0 :         table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
    1056           0 :                 cpu_to_be32(pi->clk_regs.rv770.cg_spll_func_cntl_3);
    1057           0 :         table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
    1058           0 :                 cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum);
    1059           0 :         table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
    1060           0 :                 cpu_to_be32(pi->clk_regs.rv770.cg_spll_spread_spectrum_2);
    1061             : 
    1062           0 :         table->initialState.levels[0].sclk.sclk_value =
    1063           0 :                 cpu_to_be32(initial_state->low.sclk);
    1064             : 
    1065           0 :         table->initialState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
    1066             : 
    1067           0 :         table->initialState.levels[0].seqValue =
    1068           0 :                 rv770_get_seq_value(rdev, &initial_state->low);
    1069             : 
    1070           0 :         rv770_populate_vddc_value(rdev,
    1071           0 :                                   initial_state->low.vddc,
    1072           0 :                                   &table->initialState.levels[0].vddc);
    1073           0 :         rv770_populate_initial_mvdd_value(rdev,
    1074           0 :                                           &table->initialState.levels[0].mvdd);
    1075             : 
    1076             :         a_t = CG_R(0xffff) | CG_L(0);
    1077           0 :         table->initialState.levels[0].aT = cpu_to_be32(a_t);
    1078             : 
    1079           0 :         table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
    1080             : 
    1081           0 :         if (pi->boot_in_gen2)
    1082           0 :                 table->initialState.levels[0].gen2PCIE = 1;
    1083             :         else
    1084           0 :                 table->initialState.levels[0].gen2PCIE = 0;
    1085           0 :         if (initial_state->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
    1086           0 :                 table->initialState.levels[0].gen2XSP = 1;
    1087             :         else
    1088           0 :                 table->initialState.levels[0].gen2XSP = 0;
    1089             : 
    1090           0 :         if (rdev->family == CHIP_RV740) {
    1091           0 :                 if (pi->mem_gddr5) {
    1092           0 :                         if (initial_state->low.mclk <= pi->mclk_strobe_mode_threshold)
    1093           0 :                                 table->initialState.levels[0].strobeMode =
    1094           0 :                                         rv740_get_mclk_frequency_ratio(initial_state->low.mclk) | 0x10;
    1095             :                         else
    1096           0 :                                 table->initialState.levels[0].strobeMode = 0;
    1097             : 
    1098           0 :                         if (initial_state->low.mclk >= pi->mclk_edc_enable_threshold)
    1099           0 :                                 table->initialState.levels[0].mcFlags = SMC_MC_EDC_RD_FLAG | SMC_MC_EDC_WR_FLAG;
    1100             :                         else
    1101           0 :                                 table->initialState.levels[0].mcFlags =  0;
    1102             :                 }
    1103             :         }
    1104             : 
    1105           0 :         table->initialState.levels[1] = table->initialState.levels[0];
    1106           0 :         table->initialState.levels[2] = table->initialState.levels[0];
    1107             : 
    1108           0 :         table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
    1109             : 
    1110           0 :         return 0;
    1111             : }
    1112             : 
    1113           0 : static int rv770_populate_smc_vddc_table(struct radeon_device *rdev,
    1114             :                                          RV770_SMC_STATETABLE *table)
    1115             : {
    1116           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1117             :         int i;
    1118             : 
    1119           0 :         for (i = 0; i < pi->valid_vddc_entries; i++) {
    1120           0 :                 table->highSMIO[pi->vddc_table[i].vddc_index] =
    1121           0 :                         pi->vddc_table[i].high_smio;
    1122           0 :                 table->lowSMIO[pi->vddc_table[i].vddc_index] =
    1123           0 :                         cpu_to_be32(pi->vddc_table[i].low_smio);
    1124             :         }
    1125             : 
    1126           0 :         table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_VDDC] = 0;
    1127           0 :         table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_VDDC] =
    1128           0 :                 cpu_to_be32(pi->vddc_mask_low);
    1129             : 
    1130           0 :         for (i = 0;
    1131           0 :              ((i < pi->valid_vddc_entries) &&
    1132           0 :               (pi->max_vddc_in_table >
    1133           0 :                pi->vddc_table[i].vddc));
    1134           0 :              i++);
    1135             : 
    1136           0 :         table->maxVDDCIndexInPPTable =
    1137           0 :                 pi->vddc_table[i].vddc_index;
    1138             : 
    1139           0 :         return 0;
    1140             : }
    1141             : 
    1142           0 : static int rv770_populate_smc_mvdd_table(struct radeon_device *rdev,
    1143             :                                          RV770_SMC_STATETABLE *table)
    1144             : {
    1145           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1146             : 
    1147           0 :         if (pi->mvdd_control) {
    1148           0 :                 table->lowSMIO[MVDD_HIGH_INDEX] |=
    1149           0 :                         cpu_to_be32(pi->mvdd_low_smio[MVDD_HIGH_INDEX]);
    1150           0 :                 table->lowSMIO[MVDD_LOW_INDEX] |=
    1151           0 :                         cpu_to_be32(pi->mvdd_low_smio[MVDD_LOW_INDEX]);
    1152             : 
    1153           0 :                 table->voltageMaskTable.highMask[RV770_SMC_VOLTAGEMASK_MVDD] = 0;
    1154           0 :                 table->voltageMaskTable.lowMask[RV770_SMC_VOLTAGEMASK_MVDD] =
    1155           0 :                         cpu_to_be32(pi->mvdd_mask_low);
    1156           0 :         }
    1157             : 
    1158           0 :         return 0;
    1159             : }
    1160             : 
    1161           0 : static int rv770_init_smc_table(struct radeon_device *rdev,
    1162             :                                 struct radeon_ps *radeon_boot_state)
    1163             : {
    1164           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1165           0 :         struct rv7xx_ps *boot_state = rv770_get_ps(radeon_boot_state);
    1166           0 :         RV770_SMC_STATETABLE *table = &pi->smc_statetable;
    1167             :         int ret;
    1168             : 
    1169           0 :         memset(table, 0, sizeof(RV770_SMC_STATETABLE));
    1170             : 
    1171           0 :         pi->boot_sclk = boot_state->low.sclk;
    1172             : 
    1173           0 :         rv770_populate_smc_vddc_table(rdev, table);
    1174           0 :         rv770_populate_smc_mvdd_table(rdev, table);
    1175             : 
    1176           0 :         switch (rdev->pm.int_thermal_type) {
    1177             :         case THERMAL_TYPE_RV770:
    1178             :         case THERMAL_TYPE_ADT7473_WITH_INTERNAL:
    1179           0 :                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
    1180           0 :                 break;
    1181             :         case THERMAL_TYPE_NONE:
    1182           0 :                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
    1183           0 :                 break;
    1184             :         case THERMAL_TYPE_EXTERNAL_GPIO:
    1185             :         default:
    1186           0 :                 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
    1187           0 :                 break;
    1188             :         }
    1189             : 
    1190           0 :         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC) {
    1191           0 :                 table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
    1192             : 
    1193           0 :                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT)
    1194           0 :                         table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_DONT_WAIT_FOR_VBLANK;
    1195             : 
    1196           0 :                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT)
    1197           0 :                         table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_ACTION_GOTOINITIALSTATE;
    1198             :         }
    1199             : 
    1200           0 :         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
    1201           0 :                 table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
    1202             : 
    1203           0 :         if (pi->mem_gddr5)
    1204           0 :                 table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
    1205             : 
    1206           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1207           0 :                 ret = rv730_populate_smc_initial_state(rdev, radeon_boot_state, table);
    1208             :         else
    1209           0 :                 ret = rv770_populate_smc_initial_state(rdev, radeon_boot_state, table);
    1210           0 :         if (ret)
    1211           0 :                 return ret;
    1212             : 
    1213           0 :         if (rdev->family == CHIP_RV740)
    1214           0 :                 ret = rv740_populate_smc_acpi_state(rdev, table);
    1215           0 :         else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1216           0 :                 ret = rv730_populate_smc_acpi_state(rdev, table);
    1217             :         else
    1218           0 :                 ret = rv770_populate_smc_acpi_state(rdev, table);
    1219           0 :         if (ret)
    1220           0 :                 return ret;
    1221             : 
    1222           0 :         table->driverState = table->initialState;
    1223             : 
    1224           0 :         return rv770_copy_bytes_to_smc(rdev,
    1225           0 :                                        pi->state_table_start,
    1226             :                                        (const u8 *)table,
    1227             :                                        sizeof(RV770_SMC_STATETABLE),
    1228           0 :                                        pi->sram_end);
    1229           0 : }
    1230             : 
    1231           0 : static int rv770_construct_vddc_table(struct radeon_device *rdev)
    1232             : {
    1233           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1234           0 :         u16 min, max, step;
    1235             :         u32 steps = 0;
    1236             :         u8 vddc_index = 0;
    1237             :         u32 i;
    1238             : 
    1239           0 :         radeon_atom_get_min_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &min);
    1240           0 :         radeon_atom_get_max_voltage(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &max);
    1241           0 :         radeon_atom_get_voltage_step(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, &step);
    1242             : 
    1243           0 :         steps = (max - min) / step + 1;
    1244             : 
    1245           0 :         if (steps > MAX_NO_VREG_STEPS)
    1246           0 :                 return -EINVAL;
    1247             : 
    1248           0 :         for (i = 0; i < steps; i++) {
    1249           0 :                 u32 gpio_pins, gpio_mask;
    1250             : 
    1251           0 :                 pi->vddc_table[i].vddc = (u16)(min + i * step);
    1252           0 :                 radeon_atom_get_voltage_gpio_settings(rdev,
    1253             :                                                       pi->vddc_table[i].vddc,
    1254             :                                                       SET_VOLTAGE_TYPE_ASIC_VDDC,
    1255             :                                                       &gpio_pins, &gpio_mask);
    1256           0 :                 pi->vddc_table[i].low_smio = gpio_pins & gpio_mask;
    1257           0 :                 pi->vddc_table[i].high_smio = 0;
    1258           0 :                 pi->vddc_mask_low = gpio_mask;
    1259           0 :                 if (i > 0) {
    1260           0 :                         if ((pi->vddc_table[i].low_smio !=
    1261           0 :                              pi->vddc_table[i - 1].low_smio ) ||
    1262           0 :                              (pi->vddc_table[i].high_smio !=
    1263           0 :                               pi->vddc_table[i - 1].high_smio))
    1264           0 :                                 vddc_index++;
    1265             :                 }
    1266           0 :                 pi->vddc_table[i].vddc_index = vddc_index;
    1267           0 :         }
    1268             : 
    1269           0 :         pi->valid_vddc_entries = (u8)steps;
    1270             : 
    1271           0 :         return 0;
    1272           0 : }
    1273             : 
    1274           0 : static u32 rv770_get_mclk_split_point(struct atom_memory_info *memory_info)
    1275             : {
    1276           0 :         if (memory_info->mem_type == MEM_TYPE_GDDR3)
    1277           0 :                 return 30000;
    1278             : 
    1279           0 :         return 0;
    1280           0 : }
    1281             : 
    1282           0 : static int rv770_get_mvdd_pin_configuration(struct radeon_device *rdev)
    1283             : {
    1284           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1285           0 :         u32 gpio_pins, gpio_mask;
    1286             : 
    1287           0 :         radeon_atom_get_voltage_gpio_settings(rdev,
    1288             :                                               MVDD_HIGH_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
    1289             :                                               &gpio_pins, &gpio_mask);
    1290           0 :         pi->mvdd_mask_low = gpio_mask;
    1291           0 :         pi->mvdd_low_smio[MVDD_HIGH_INDEX] =
    1292           0 :                 gpio_pins & gpio_mask;
    1293             : 
    1294           0 :         radeon_atom_get_voltage_gpio_settings(rdev,
    1295             :                                               MVDD_LOW_VALUE, SET_VOLTAGE_TYPE_ASIC_MVDDC,
    1296             :                                               &gpio_pins, &gpio_mask);
    1297           0 :         pi->mvdd_low_smio[MVDD_LOW_INDEX] =
    1298           0 :                 gpio_pins & gpio_mask;
    1299             : 
    1300           0 :         return 0;
    1301           0 : }
    1302             : 
    1303           0 : u8 rv770_get_memory_module_index(struct radeon_device *rdev)
    1304             : {
    1305           0 :         return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);
    1306             : }
    1307             : 
    1308           0 : static int rv770_get_mvdd_configuration(struct radeon_device *rdev)
    1309             : {
    1310           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1311             :         u8 memory_module_index;
    1312           0 :         struct atom_memory_info memory_info;
    1313             : 
    1314           0 :         memory_module_index = rv770_get_memory_module_index(rdev);
    1315             : 
    1316           0 :         if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info)) {
    1317           0 :                 pi->mvdd_control = false;
    1318           0 :                 return 0;
    1319             :         }
    1320             : 
    1321           0 :         pi->mvdd_split_frequency =
    1322           0 :                 rv770_get_mclk_split_point(&memory_info);
    1323             : 
    1324           0 :         if (pi->mvdd_split_frequency == 0) {
    1325           0 :                 pi->mvdd_control = false;
    1326           0 :                 return 0;
    1327             :         }
    1328             : 
    1329           0 :         return rv770_get_mvdd_pin_configuration(rdev);
    1330           0 : }
    1331             : 
    1332           0 : void rv770_enable_voltage_control(struct radeon_device *rdev,
    1333             :                                   bool enable)
    1334             : {
    1335           0 :         if (enable)
    1336           0 :                 WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
    1337             :         else
    1338           0 :                 WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
    1339           0 : }
    1340             : 
    1341           0 : static void rv770_program_display_gap(struct radeon_device *rdev)
    1342             : {
    1343           0 :         u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
    1344             : 
    1345           0 :         tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
    1346           0 :         if (rdev->pm.dpm.new_active_crtcs & 1) {
    1347           0 :                 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
    1348           0 :                 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
    1349           0 :         } else if (rdev->pm.dpm.new_active_crtcs & 2) {
    1350             :                 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
    1351           0 :                 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
    1352           0 :         } else {
    1353             :                 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
    1354           0 :                 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
    1355             :         }
    1356           0 :         WREG32(CG_DISPLAY_GAP_CNTL, tmp);
    1357           0 : }
    1358             : 
    1359           0 : static void rv770_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
    1360             :                                            bool enable)
    1361             : {
    1362           0 :         rv770_enable_bif_dynamic_pcie_gen2(rdev, enable);
    1363             : 
    1364           0 :         if (enable)
    1365           0 :                 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
    1366             :         else
    1367           0 :                 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
    1368           0 : }
    1369             : 
    1370           0 : static void r7xx_program_memory_timing_parameters(struct radeon_device *rdev,
    1371             :                                                   struct radeon_ps *radeon_new_state)
    1372             : {
    1373           0 :         if ((rdev->family == CHIP_RV730) ||
    1374           0 :             (rdev->family == CHIP_RV710) ||
    1375           0 :             (rdev->family == CHIP_RV740))
    1376           0 :                 rv730_program_memory_timing_parameters(rdev, radeon_new_state);
    1377             :         else
    1378           0 :                 rv770_program_memory_timing_parameters(rdev, radeon_new_state);
    1379           0 : }
    1380             : 
    1381           0 : static int rv770_upload_sw_state(struct radeon_device *rdev,
    1382             :                                  struct radeon_ps *radeon_new_state)
    1383             : {
    1384           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1385           0 :         u16 address = pi->state_table_start +
    1386             :                 offsetof(RV770_SMC_STATETABLE, driverState);
    1387           0 :         RV770_SMC_SWSTATE state = { 0 };
    1388             :         int ret;
    1389             : 
    1390           0 :         ret = rv770_convert_power_state_to_smc(rdev, radeon_new_state, &state);
    1391           0 :         if (ret)
    1392           0 :                 return ret;
    1393             : 
    1394           0 :         return rv770_copy_bytes_to_smc(rdev, address, (const u8 *)&state,
    1395             :                                        sizeof(RV770_SMC_SWSTATE),
    1396           0 :                                        pi->sram_end);
    1397           0 : }
    1398             : 
    1399           0 : int rv770_halt_smc(struct radeon_device *rdev)
    1400             : {
    1401           0 :         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
    1402           0 :                 return -EINVAL;
    1403             : 
    1404           0 :         if (rv770_wait_for_smc_inactive(rdev) != PPSMC_Result_OK)
    1405           0 :                 return -EINVAL;
    1406             : 
    1407           0 :         return 0;
    1408           0 : }
    1409             : 
    1410           0 : int rv770_resume_smc(struct radeon_device *rdev)
    1411             : {
    1412           0 :         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_Resume) != PPSMC_Result_OK)
    1413           0 :                 return -EINVAL;
    1414           0 :         return 0;
    1415           0 : }
    1416             : 
    1417           0 : int rv770_set_sw_state(struct radeon_device *rdev)
    1418             : {
    1419           0 :         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) != PPSMC_Result_OK)
    1420             :                 DRM_DEBUG("rv770_set_sw_state failed\n");
    1421           0 :         return 0;
    1422             : }
    1423             : 
    1424           0 : int rv770_set_boot_state(struct radeon_device *rdev)
    1425             : {
    1426           0 :         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) != PPSMC_Result_OK)
    1427           0 :                 return -EINVAL;
    1428           0 :         return 0;
    1429           0 : }
    1430             : 
    1431           0 : void rv770_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
    1432             :                                               struct radeon_ps *new_ps,
    1433             :                                               struct radeon_ps *old_ps)
    1434             : {
    1435           0 :         struct rv7xx_ps *new_state = rv770_get_ps(new_ps);
    1436           0 :         struct rv7xx_ps *current_state = rv770_get_ps(old_ps);
    1437             : 
    1438           0 :         if ((new_ps->vclk == old_ps->vclk) &&
    1439           0 :             (new_ps->dclk == old_ps->dclk))
    1440           0 :                 return;
    1441             : 
    1442           0 :         if (new_state->high.sclk >= current_state->high.sclk)
    1443           0 :                 return;
    1444             : 
    1445           0 :         radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
    1446           0 : }
    1447             : 
    1448           0 : void rv770_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
    1449             :                                              struct radeon_ps *new_ps,
    1450             :                                              struct radeon_ps *old_ps)
    1451             : {
    1452           0 :         struct rv7xx_ps *new_state = rv770_get_ps(new_ps);
    1453           0 :         struct rv7xx_ps *current_state = rv770_get_ps(old_ps);
    1454             : 
    1455           0 :         if ((new_ps->vclk == old_ps->vclk) &&
    1456           0 :             (new_ps->dclk == old_ps->dclk))
    1457           0 :                 return;
    1458             : 
    1459           0 :         if (new_state->high.sclk < current_state->high.sclk)
    1460           0 :                 return;
    1461             : 
    1462           0 :         radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
    1463           0 : }
    1464             : 
    1465           0 : int rv770_restrict_performance_levels_before_switch(struct radeon_device *rdev)
    1466             : {
    1467           0 :         if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_NoForcedLevel)) != PPSMC_Result_OK)
    1468           0 :                 return -EINVAL;
    1469             : 
    1470           0 :         if (rv770_send_msg_to_smc(rdev, (PPSMC_Msg)(PPSMC_MSG_TwoLevelsDisabled)) != PPSMC_Result_OK)
    1471           0 :                 return -EINVAL;
    1472             : 
    1473           0 :         return 0;
    1474           0 : }
    1475             : 
    1476           0 : int rv770_dpm_force_performance_level(struct radeon_device *rdev,
    1477             :                                       enum radeon_dpm_forced_level level)
    1478             : {
    1479             :         PPSMC_Msg msg;
    1480             : 
    1481           0 :         if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
    1482           0 :                 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ZeroLevelsDisabled) != PPSMC_Result_OK)
    1483           0 :                         return -EINVAL;
    1484             :                 msg = PPSMC_MSG_ForceHigh;
    1485           0 :         } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
    1486           0 :                 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
    1487           0 :                         return -EINVAL;
    1488             :                 msg = (PPSMC_Msg)(PPSMC_MSG_TwoLevelsDisabled);
    1489           0 :         } else {
    1490           0 :                 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
    1491           0 :                         return -EINVAL;
    1492             :                 msg = (PPSMC_Msg)(PPSMC_MSG_ZeroLevelsDisabled);
    1493             :         }
    1494             : 
    1495           0 :         if (rv770_send_msg_to_smc(rdev, msg) != PPSMC_Result_OK)
    1496           0 :                 return -EINVAL;
    1497             : 
    1498           0 :         rdev->pm.dpm.forced_level = level;
    1499             : 
    1500           0 :         return 0;
    1501           0 : }
    1502             : 
    1503           0 : void r7xx_start_smc(struct radeon_device *rdev)
    1504             : {
    1505           0 :         rv770_start_smc(rdev);
    1506           0 :         rv770_start_smc_clock(rdev);
    1507           0 : }
    1508             : 
    1509             : 
    1510           0 : void r7xx_stop_smc(struct radeon_device *rdev)
    1511             : {
    1512           0 :         rv770_reset_smc(rdev);
    1513           0 :         rv770_stop_smc_clock(rdev);
    1514           0 : }
    1515             : 
    1516           0 : static void rv770_read_clock_registers(struct radeon_device *rdev)
    1517             : {
    1518           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1519             : 
    1520           0 :         pi->clk_regs.rv770.cg_spll_func_cntl =
    1521           0 :                 RREG32(CG_SPLL_FUNC_CNTL);
    1522           0 :         pi->clk_regs.rv770.cg_spll_func_cntl_2 =
    1523           0 :                 RREG32(CG_SPLL_FUNC_CNTL_2);
    1524           0 :         pi->clk_regs.rv770.cg_spll_func_cntl_3 =
    1525           0 :                 RREG32(CG_SPLL_FUNC_CNTL_3);
    1526           0 :         pi->clk_regs.rv770.cg_spll_spread_spectrum =
    1527           0 :                 RREG32(CG_SPLL_SPREAD_SPECTRUM);
    1528           0 :         pi->clk_regs.rv770.cg_spll_spread_spectrum_2 =
    1529           0 :                 RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
    1530           0 :         pi->clk_regs.rv770.mpll_ad_func_cntl =
    1531           0 :                 RREG32(MPLL_AD_FUNC_CNTL);
    1532           0 :         pi->clk_regs.rv770.mpll_ad_func_cntl_2 =
    1533           0 :                 RREG32(MPLL_AD_FUNC_CNTL_2);
    1534           0 :         pi->clk_regs.rv770.mpll_dq_func_cntl =
    1535           0 :                 RREG32(MPLL_DQ_FUNC_CNTL);
    1536           0 :         pi->clk_regs.rv770.mpll_dq_func_cntl_2 =
    1537           0 :                 RREG32(MPLL_DQ_FUNC_CNTL_2);
    1538           0 :         pi->clk_regs.rv770.mclk_pwrmgt_cntl =
    1539           0 :                 RREG32(MCLK_PWRMGT_CNTL);
    1540           0 :         pi->clk_regs.rv770.dll_cntl = RREG32(DLL_CNTL);
    1541           0 : }
    1542             : 
    1543           0 : static void r7xx_read_clock_registers(struct radeon_device *rdev)
    1544             : {
    1545           0 :         if (rdev->family == CHIP_RV740)
    1546           0 :                 rv740_read_clock_registers(rdev);
    1547           0 :         else if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1548           0 :                 rv730_read_clock_registers(rdev);
    1549             :         else
    1550           0 :                 rv770_read_clock_registers(rdev);
    1551           0 : }
    1552             : 
    1553           0 : void rv770_read_voltage_smio_registers(struct radeon_device *rdev)
    1554             : {
    1555           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1556             : 
    1557           0 :         pi->s0_vid_lower_smio_cntl =
    1558           0 :                 RREG32(S0_VID_LOWER_SMIO_CNTL);
    1559           0 : }
    1560             : 
    1561           0 : void rv770_reset_smio_status(struct radeon_device *rdev)
    1562             : {
    1563           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1564             :         u32 sw_smio_index, vid_smio_cntl;
    1565             : 
    1566             :         sw_smio_index =
    1567           0 :                 (RREG32(GENERAL_PWRMGT) & SW_SMIO_INDEX_MASK) >> SW_SMIO_INDEX_SHIFT;
    1568           0 :         switch (sw_smio_index) {
    1569             :         case 3:
    1570           0 :                 vid_smio_cntl = RREG32(S3_VID_LOWER_SMIO_CNTL);
    1571           0 :                 break;
    1572             :         case 2:
    1573           0 :                 vid_smio_cntl = RREG32(S2_VID_LOWER_SMIO_CNTL);
    1574           0 :                 break;
    1575             :         case 1:
    1576           0 :                 vid_smio_cntl = RREG32(S1_VID_LOWER_SMIO_CNTL);
    1577           0 :                 break;
    1578             :         case 0:
    1579           0 :                 return;
    1580             :         default:
    1581           0 :                 vid_smio_cntl = pi->s0_vid_lower_smio_cntl;
    1582           0 :                 break;
    1583             :         }
    1584             : 
    1585           0 :         WREG32(S0_VID_LOWER_SMIO_CNTL, vid_smio_cntl);
    1586           0 :         WREG32_P(GENERAL_PWRMGT, SW_SMIO_INDEX(0), ~SW_SMIO_INDEX_MASK);
    1587           0 : }
    1588             : 
    1589           0 : void rv770_get_memory_type(struct radeon_device *rdev)
    1590             : {
    1591           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1592             :         u32 tmp;
    1593             : 
    1594           0 :         tmp = RREG32(MC_SEQ_MISC0);
    1595             : 
    1596           0 :         if (((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT) ==
    1597             :             MC_SEQ_MISC0_GDDR5_VALUE)
    1598           0 :                 pi->mem_gddr5 = true;
    1599             :         else
    1600           0 :                 pi->mem_gddr5 = false;
    1601             : 
    1602           0 : }
    1603             : 
    1604           0 : void rv770_get_pcie_gen2_status(struct radeon_device *rdev)
    1605             : {
    1606           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1607             :         u32 tmp;
    1608             : 
    1609           0 :         tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
    1610             : 
    1611           0 :         if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
    1612           0 :             (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
    1613           0 :                 pi->pcie_gen2 = true;
    1614             :         else
    1615           0 :                 pi->pcie_gen2 = false;
    1616             : 
    1617           0 :         if (pi->pcie_gen2) {
    1618           0 :                 if (tmp & LC_CURRENT_DATA_RATE)
    1619           0 :                         pi->boot_in_gen2 = true;
    1620             :                 else
    1621           0 :                         pi->boot_in_gen2 = false;
    1622             :         } else
    1623           0 :                 pi->boot_in_gen2 = false;
    1624           0 : }
    1625             : 
    1626             : #if 0
    1627             : static int rv770_enter_ulp_state(struct radeon_device *rdev)
    1628             : {
    1629             :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1630             : 
    1631             :         if (pi->gfx_clock_gating) {
    1632             :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
    1633             :                 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
    1634             :                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
    1635             :                 RREG32(GB_TILING_CONFIG);
    1636             :         }
    1637             : 
    1638             :         WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
    1639             :                  ~HOST_SMC_MSG_MASK);
    1640             : 
    1641             :         udelay(7000);
    1642             : 
    1643             :         return 0;
    1644             : }
    1645             : 
    1646             : static int rv770_exit_ulp_state(struct radeon_device *rdev)
    1647             : {
    1648             :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1649             :         int i;
    1650             : 
    1651             :         WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_ResumeFromMinimumPower),
    1652             :                  ~HOST_SMC_MSG_MASK);
    1653             : 
    1654             :         udelay(7000);
    1655             : 
    1656             :         for (i = 0; i < rdev->usec_timeout; i++) {
    1657             :                 if (((RREG32(SMC_MSG) & HOST_SMC_RESP_MASK) >> HOST_SMC_RESP_SHIFT) == 1)
    1658             :                         break;
    1659             :                 udelay(1000);
    1660             :         }
    1661             : 
    1662             :         if (pi->gfx_clock_gating)
    1663             :                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
    1664             : 
    1665             :         return 0;
    1666             : }
    1667             : #endif
    1668             : 
    1669           0 : static void rv770_get_mclk_odt_threshold(struct radeon_device *rdev)
    1670             : {
    1671           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1672             :         u8 memory_module_index;
    1673           0 :         struct atom_memory_info memory_info;
    1674             : 
    1675           0 :         pi->mclk_odt_threshold = 0;
    1676             : 
    1677           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710)) {
    1678           0 :                 memory_module_index = rv770_get_memory_module_index(rdev);
    1679             : 
    1680           0 :                 if (radeon_atom_get_memory_info(rdev, memory_module_index, &memory_info))
    1681           0 :                         return;
    1682             : 
    1683           0 :                 if (memory_info.mem_type == MEM_TYPE_DDR2 ||
    1684           0 :                     memory_info.mem_type == MEM_TYPE_DDR3)
    1685           0 :                         pi->mclk_odt_threshold = 30000;
    1686             :         }
    1687           0 : }
    1688             : 
    1689           0 : void rv770_get_max_vddc(struct radeon_device *rdev)
    1690             : {
    1691           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1692           0 :         u16 vddc;
    1693             : 
    1694           0 :         if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc))
    1695           0 :                 pi->max_vddc = 0;
    1696             :         else
    1697           0 :                 pi->max_vddc = vddc;
    1698           0 : }
    1699             : 
    1700           0 : void rv770_program_response_times(struct radeon_device *rdev)
    1701             : {
    1702             :         u32 voltage_response_time, backbias_response_time;
    1703             :         u32 acpi_delay_time, vbi_time_out;
    1704             :         u32 vddc_dly, bb_dly, acpi_dly, vbi_dly;
    1705             :         u32 reference_clock;
    1706             : 
    1707           0 :         voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
    1708           0 :         backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
    1709             : 
    1710           0 :         if (voltage_response_time == 0)
    1711           0 :                 voltage_response_time = 1000;
    1712             : 
    1713           0 :         if (backbias_response_time == 0)
    1714           0 :                 backbias_response_time = 1000;
    1715             : 
    1716             :         acpi_delay_time = 15000;
    1717             :         vbi_time_out = 100000;
    1718             : 
    1719           0 :         reference_clock = radeon_get_xclk(rdev);
    1720             : 
    1721           0 :         vddc_dly = (voltage_response_time  * reference_clock) / 1600;
    1722           0 :         bb_dly = (backbias_response_time * reference_clock) / 1600;
    1723           0 :         acpi_dly = (acpi_delay_time * reference_clock) / 1600;
    1724           0 :         vbi_dly = (vbi_time_out * reference_clock) / 1600;
    1725             : 
    1726           0 :         rv770_write_smc_soft_register(rdev,
    1727             :                                       RV770_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);
    1728           0 :         rv770_write_smc_soft_register(rdev,
    1729             :                                       RV770_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
    1730           0 :         rv770_write_smc_soft_register(rdev,
    1731             :                                       RV770_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);
    1732           0 :         rv770_write_smc_soft_register(rdev,
    1733             :                                       RV770_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
    1734             : #if 0
    1735             :         /* XXX look up hw revision */
    1736             :         if (WEKIVA_A21)
    1737             :                 rv770_write_smc_soft_register(rdev,
    1738             :                                               RV770_SMC_SOFT_REGISTER_baby_step_timer,
    1739             :                                               0x10);
    1740             : #endif
    1741           0 : }
    1742             : 
    1743           0 : static void rv770_program_dcodt_before_state_switch(struct radeon_device *rdev,
    1744             :                                                     struct radeon_ps *radeon_new_state,
    1745             :                                                     struct radeon_ps *radeon_current_state)
    1746             : {
    1747           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1748           0 :         struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
    1749           0 :         struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
    1750             :         bool current_use_dc = false;
    1751             :         bool new_use_dc = false;
    1752             : 
    1753           0 :         if (pi->mclk_odt_threshold == 0)
    1754           0 :                 return;
    1755             : 
    1756           0 :         if (current_state->high.mclk <= pi->mclk_odt_threshold)
    1757           0 :                 current_use_dc = true;
    1758             : 
    1759           0 :         if (new_state->high.mclk <= pi->mclk_odt_threshold)
    1760           0 :                 new_use_dc = true;
    1761             : 
    1762           0 :         if (current_use_dc == new_use_dc)
    1763           0 :                 return;
    1764             : 
    1765           0 :         if (!current_use_dc && new_use_dc)
    1766           0 :                 return;
    1767             : 
    1768           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1769           0 :                 rv730_program_dcodt(rdev, new_use_dc);
    1770           0 : }
    1771             : 
    1772           0 : static void rv770_program_dcodt_after_state_switch(struct radeon_device *rdev,
    1773             :                                                    struct radeon_ps *radeon_new_state,
    1774             :                                                    struct radeon_ps *radeon_current_state)
    1775             : {
    1776           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1777           0 :         struct rv7xx_ps *new_state = rv770_get_ps(radeon_new_state);
    1778           0 :         struct rv7xx_ps *current_state = rv770_get_ps(radeon_current_state);
    1779             :         bool current_use_dc = false;
    1780             :         bool new_use_dc = false;
    1781             : 
    1782           0 :         if (pi->mclk_odt_threshold == 0)
    1783           0 :                 return;
    1784             : 
    1785           0 :         if (current_state->high.mclk <= pi->mclk_odt_threshold)
    1786           0 :                 current_use_dc = true;
    1787             : 
    1788           0 :         if (new_state->high.mclk <= pi->mclk_odt_threshold)
    1789           0 :                 new_use_dc = true;
    1790             : 
    1791           0 :         if (current_use_dc == new_use_dc)
    1792           0 :                 return;
    1793             : 
    1794           0 :         if (current_use_dc && !new_use_dc)
    1795           0 :                 return;
    1796             : 
    1797           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1798           0 :                 rv730_program_dcodt(rdev, new_use_dc);
    1799           0 : }
    1800             : 
    1801           0 : static void rv770_retrieve_odt_values(struct radeon_device *rdev)
    1802             : {
    1803           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1804             : 
    1805           0 :         if (pi->mclk_odt_threshold == 0)
    1806           0 :                 return;
    1807             : 
    1808           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1809           0 :                 rv730_get_odt_values(rdev);
    1810           0 : }
    1811             : 
    1812           0 : static void rv770_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
    1813             : {
    1814           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1815             :         bool want_thermal_protection;
    1816             :         enum radeon_dpm_event_src dpm_event_src;
    1817             : 
    1818           0 :         switch (sources) {
    1819             :         case 0:
    1820             :         default:
    1821             :                 want_thermal_protection = false;
    1822           0 :                 break;
    1823             :         case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
    1824             :                 want_thermal_protection = true;
    1825             :                 dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
    1826           0 :                 break;
    1827             : 
    1828             :         case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
    1829             :                 want_thermal_protection = true;
    1830             :                 dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
    1831           0 :                 break;
    1832             : 
    1833             :         case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
    1834             :               (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
    1835             :                 want_thermal_protection = true;
    1836             :                 dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
    1837           0 :                 break;
    1838             :         }
    1839             : 
    1840           0 :         if (want_thermal_protection) {
    1841           0 :                 WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
    1842           0 :                 if (pi->thermal_protection)
    1843           0 :                         WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
    1844             :         } else {
    1845           0 :                 WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
    1846             :         }
    1847           0 : }
    1848             : 
    1849           0 : void rv770_enable_auto_throttle_source(struct radeon_device *rdev,
    1850             :                                        enum radeon_dpm_auto_throttle_src source,
    1851             :                                        bool enable)
    1852             : {
    1853           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1854             : 
    1855           0 :         if (enable) {
    1856           0 :                 if (!(pi->active_auto_throttle_sources & (1 << source))) {
    1857           0 :                         pi->active_auto_throttle_sources |= 1 << source;
    1858           0 :                         rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
    1859           0 :                 }
    1860             :         } else {
    1861           0 :                 if (pi->active_auto_throttle_sources & (1 << source)) {
    1862           0 :                         pi->active_auto_throttle_sources &= ~(1 << source);
    1863           0 :                         rv770_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
    1864           0 :                 }
    1865             :         }
    1866           0 : }
    1867             : 
    1868           0 : static int rv770_set_thermal_temperature_range(struct radeon_device *rdev,
    1869             :                                                int min_temp, int max_temp)
    1870             : {
    1871             :         int low_temp = 0 * 1000;
    1872             :         int high_temp = 255 * 1000;
    1873             : 
    1874           0 :         if (low_temp < min_temp)
    1875           0 :                 low_temp = min_temp;
    1876           0 :         if (high_temp > max_temp)
    1877           0 :                 high_temp = max_temp;
    1878           0 :         if (high_temp < low_temp) {
    1879           0 :                 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
    1880           0 :                 return -EINVAL;
    1881             :         }
    1882             : 
    1883           0 :         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
    1884           0 :         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
    1885           0 :         WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
    1886             : 
    1887           0 :         rdev->pm.dpm.thermal.min_temp = low_temp;
    1888           0 :         rdev->pm.dpm.thermal.max_temp = high_temp;
    1889             : 
    1890           0 :         return 0;
    1891           0 : }
    1892             : 
    1893           0 : int rv770_dpm_enable(struct radeon_device *rdev)
    1894             : {
    1895           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    1896           0 :         struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
    1897             :         int ret;
    1898             : 
    1899           0 :         if (pi->gfx_clock_gating)
    1900           0 :                 rv770_restore_cgcg(rdev);
    1901             : 
    1902           0 :         if (rv770_dpm_enabled(rdev))
    1903           0 :                 return -EINVAL;
    1904             : 
    1905           0 :         if (pi->voltage_control) {
    1906           0 :                 rv770_enable_voltage_control(rdev, true);
    1907           0 :                 ret = rv770_construct_vddc_table(rdev);
    1908           0 :                 if (ret) {
    1909           0 :                         DRM_ERROR("rv770_construct_vddc_table failed\n");
    1910           0 :                         return ret;
    1911             :                 }
    1912             :         }
    1913             : 
    1914           0 :         if (pi->dcodt)
    1915           0 :                 rv770_retrieve_odt_values(rdev);
    1916             : 
    1917           0 :         if (pi->mvdd_control) {
    1918           0 :                 ret = rv770_get_mvdd_configuration(rdev);
    1919           0 :                 if (ret) {
    1920           0 :                         DRM_ERROR("rv770_get_mvdd_configuration failed\n");
    1921           0 :                         return ret;
    1922             :                 }
    1923             :         }
    1924             : 
    1925           0 :         if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
    1926           0 :                 rv770_enable_backbias(rdev, true);
    1927             : 
    1928           0 :         rv770_enable_spread_spectrum(rdev, true);
    1929             : 
    1930           0 :         if (pi->thermal_protection)
    1931           0 :                 rv770_enable_thermal_protection(rdev, true);
    1932             : 
    1933           0 :         rv770_program_mpll_timing_parameters(rdev);
    1934           0 :         rv770_setup_bsp(rdev);
    1935           0 :         rv770_program_git(rdev);
    1936           0 :         rv770_program_tp(rdev);
    1937           0 :         rv770_program_tpp(rdev);
    1938           0 :         rv770_program_sstp(rdev);
    1939           0 :         rv770_program_engine_speed_parameters(rdev);
    1940           0 :         rv770_enable_display_gap(rdev);
    1941           0 :         rv770_program_vc(rdev);
    1942             : 
    1943           0 :         if (pi->dynamic_pcie_gen2)
    1944           0 :                 rv770_enable_dynamic_pcie_gen2(rdev, true);
    1945             : 
    1946           0 :         ret = rv770_upload_firmware(rdev);
    1947           0 :         if (ret) {
    1948           0 :                 DRM_ERROR("rv770_upload_firmware failed\n");
    1949           0 :                 return ret;
    1950             :         }
    1951           0 :         ret = rv770_init_smc_table(rdev, boot_ps);
    1952           0 :         if (ret) {
    1953           0 :                 DRM_ERROR("rv770_init_smc_table failed\n");
    1954           0 :                 return ret;
    1955             :         }
    1956             : 
    1957           0 :         rv770_program_response_times(rdev);
    1958           0 :         r7xx_start_smc(rdev);
    1959             : 
    1960           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    1961           0 :                 rv730_start_dpm(rdev);
    1962             :         else
    1963           0 :                 rv770_start_dpm(rdev);
    1964             : 
    1965           0 :         if (pi->gfx_clock_gating)
    1966           0 :                 rv770_gfx_clock_gating_enable(rdev, true);
    1967             : 
    1968           0 :         if (pi->mg_clock_gating)
    1969           0 :                 rv770_mg_clock_gating_enable(rdev, true);
    1970             : 
    1971           0 :         rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
    1972             : 
    1973           0 :         return 0;
    1974           0 : }
    1975             : 
    1976           0 : int rv770_dpm_late_enable(struct radeon_device *rdev)
    1977             : {
    1978             :         int ret;
    1979             : 
    1980           0 :         if (rdev->irq.installed &&
    1981           0 :             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
    1982             :                 PPSMC_Result result;
    1983             : 
    1984           0 :                 ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
    1985           0 :                 if (ret)
    1986           0 :                         return ret;
    1987           0 :                 rdev->irq.dpm_thermal = true;
    1988           0 :                 radeon_irq_set(rdev);
    1989           0 :                 result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
    1990             : 
    1991           0 :                 if (result != PPSMC_Result_OK)
    1992             :                         DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
    1993           0 :         }
    1994             : 
    1995           0 :         return 0;
    1996           0 : }
    1997             : 
    1998           0 : void rv770_dpm_disable(struct radeon_device *rdev)
    1999             : {
    2000           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2001             : 
    2002           0 :         if (!rv770_dpm_enabled(rdev))
    2003           0 :                 return;
    2004             : 
    2005           0 :         rv770_clear_vc(rdev);
    2006             : 
    2007           0 :         if (pi->thermal_protection)
    2008           0 :                 rv770_enable_thermal_protection(rdev, false);
    2009             : 
    2010           0 :         rv770_enable_spread_spectrum(rdev, false);
    2011             : 
    2012           0 :         if (pi->dynamic_pcie_gen2)
    2013           0 :                 rv770_enable_dynamic_pcie_gen2(rdev, false);
    2014             : 
    2015           0 :         if (rdev->irq.installed &&
    2016           0 :             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
    2017           0 :                 rdev->irq.dpm_thermal = false;
    2018           0 :                 radeon_irq_set(rdev);
    2019           0 :         }
    2020             : 
    2021           0 :         if (pi->gfx_clock_gating)
    2022           0 :                 rv770_gfx_clock_gating_enable(rdev, false);
    2023             : 
    2024           0 :         if (pi->mg_clock_gating)
    2025           0 :                 rv770_mg_clock_gating_enable(rdev, false);
    2026             : 
    2027           0 :         if ((rdev->family == CHIP_RV730) || (rdev->family == CHIP_RV710))
    2028           0 :                 rv730_stop_dpm(rdev);
    2029             :         else
    2030           0 :                 rv770_stop_dpm(rdev);
    2031             : 
    2032           0 :         r7xx_stop_smc(rdev);
    2033           0 :         rv770_reset_smio_status(rdev);
    2034           0 : }
    2035             : 
    2036           0 : int rv770_dpm_set_power_state(struct radeon_device *rdev)
    2037             : {
    2038           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2039           0 :         struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
    2040           0 :         struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
    2041             :         int ret;
    2042             : 
    2043           0 :         ret = rv770_restrict_performance_levels_before_switch(rdev);
    2044           0 :         if (ret) {
    2045           0 :                 DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
    2046           0 :                 return ret;
    2047             :         }
    2048           0 :         rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
    2049           0 :         ret = rv770_halt_smc(rdev);
    2050           0 :         if (ret) {
    2051           0 :                 DRM_ERROR("rv770_halt_smc failed\n");
    2052           0 :                 return ret;
    2053             :         }
    2054           0 :         ret = rv770_upload_sw_state(rdev, new_ps);
    2055           0 :         if (ret) {
    2056           0 :                 DRM_ERROR("rv770_upload_sw_state failed\n");
    2057           0 :                 return ret;
    2058             :         }
    2059           0 :         r7xx_program_memory_timing_parameters(rdev, new_ps);
    2060           0 :         if (pi->dcodt)
    2061           0 :                 rv770_program_dcodt_before_state_switch(rdev, new_ps, old_ps);
    2062           0 :         ret = rv770_resume_smc(rdev);
    2063           0 :         if (ret) {
    2064           0 :                 DRM_ERROR("rv770_resume_smc failed\n");
    2065           0 :                 return ret;
    2066             :         }
    2067           0 :         ret = rv770_set_sw_state(rdev);
    2068           0 :         if (ret) {
    2069           0 :                 DRM_ERROR("rv770_set_sw_state failed\n");
    2070           0 :                 return ret;
    2071             :         }
    2072           0 :         if (pi->dcodt)
    2073           0 :                 rv770_program_dcodt_after_state_switch(rdev, new_ps, old_ps);
    2074           0 :         rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
    2075             : 
    2076           0 :         return 0;
    2077           0 : }
    2078             : 
    2079             : #if 0
    2080             : void rv770_dpm_reset_asic(struct radeon_device *rdev)
    2081             : {
    2082             :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2083             :         struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
    2084             : 
    2085             :         rv770_restrict_performance_levels_before_switch(rdev);
    2086             :         if (pi->dcodt)
    2087             :                 rv770_program_dcodt_before_state_switch(rdev, boot_ps, boot_ps);
    2088             :         rv770_set_boot_state(rdev);
    2089             :         if (pi->dcodt)
    2090             :                 rv770_program_dcodt_after_state_switch(rdev, boot_ps, boot_ps);
    2091             : }
    2092             : #endif
    2093             : 
    2094           0 : void rv770_dpm_setup_asic(struct radeon_device *rdev)
    2095             : {
    2096           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2097             : 
    2098           0 :         r7xx_read_clock_registers(rdev);
    2099           0 :         rv770_read_voltage_smio_registers(rdev);
    2100           0 :         rv770_get_memory_type(rdev);
    2101           0 :         if (pi->dcodt)
    2102           0 :                 rv770_get_mclk_odt_threshold(rdev);
    2103           0 :         rv770_get_pcie_gen2_status(rdev);
    2104             : 
    2105           0 :         rv770_enable_acpi_pm(rdev);
    2106             : 
    2107           0 :         if (radeon_aspm != 0) {
    2108           0 :                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L0s)
    2109           0 :                         rv770_enable_l0s(rdev);
    2110           0 :                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_ASPM_L1)
    2111           0 :                         rv770_enable_l1(rdev);
    2112           0 :                 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1)
    2113           0 :                         rv770_enable_pll_sleep_in_l1(rdev);
    2114             :         }
    2115           0 : }
    2116             : 
    2117           0 : void rv770_dpm_display_configuration_changed(struct radeon_device *rdev)
    2118             : {
    2119           0 :         rv770_program_display_gap(rdev);
    2120           0 : }
    2121             : 
    2122             : union power_info {
    2123             :         struct _ATOM_POWERPLAY_INFO info;
    2124             :         struct _ATOM_POWERPLAY_INFO_V2 info_2;
    2125             :         struct _ATOM_POWERPLAY_INFO_V3 info_3;
    2126             :         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
    2127             :         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
    2128             :         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
    2129             : };
    2130             : 
    2131             : union pplib_clock_info {
    2132             :         struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
    2133             :         struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
    2134             :         struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
    2135             :         struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
    2136             : };
    2137             : 
    2138             : union pplib_power_state {
    2139             :         struct _ATOM_PPLIB_STATE v1;
    2140             :         struct _ATOM_PPLIB_STATE_V2 v2;
    2141             : };
    2142             : 
    2143           0 : static void rv7xx_parse_pplib_non_clock_info(struct radeon_device *rdev,
    2144             :                                              struct radeon_ps *rps,
    2145             :                                              struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
    2146             :                                              u8 table_rev)
    2147             : {
    2148           0 :         rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
    2149           0 :         rps->class = le16_to_cpu(non_clock_info->usClassification);
    2150           0 :         rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
    2151             : 
    2152           0 :         if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
    2153           0 :                 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
    2154           0 :                 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
    2155           0 :         } else {
    2156           0 :                 rps->vclk = 0;
    2157           0 :                 rps->dclk = 0;
    2158             :         }
    2159             : 
    2160           0 :         if (r600_is_uvd_state(rps->class, rps->class2)) {
    2161           0 :                 if ((rps->vclk == 0) || (rps->dclk == 0)) {
    2162           0 :                         rps->vclk = RV770_DEFAULT_VCLK_FREQ;
    2163           0 :                         rps->dclk = RV770_DEFAULT_DCLK_FREQ;
    2164           0 :                 }
    2165             :         }
    2166             : 
    2167           0 :         if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
    2168           0 :                 rdev->pm.dpm.boot_ps = rps;
    2169           0 :         if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
    2170           0 :                 rdev->pm.dpm.uvd_ps = rps;
    2171           0 : }
    2172             : 
    2173           0 : static void rv7xx_parse_pplib_clock_info(struct radeon_device *rdev,
    2174             :                                          struct radeon_ps *rps, int index,
    2175             :                                          union pplib_clock_info *clock_info)
    2176             : {
    2177           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2178           0 :         struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
    2179           0 :         struct rv7xx_ps *ps = rv770_get_ps(rps);
    2180             :         u32 sclk, mclk;
    2181             :         struct rv7xx_pl *pl;
    2182             : 
    2183           0 :         switch (index) {
    2184             :         case 0:
    2185           0 :                 pl = &ps->low;
    2186           0 :                 break;
    2187             :         case 1:
    2188           0 :                 pl = &ps->medium;
    2189           0 :                 break;
    2190             :         case 2:
    2191             :         default:
    2192           0 :                 pl = &ps->high;
    2193           0 :                 break;
    2194             :         }
    2195             : 
    2196           0 :         if (rdev->family >= CHIP_CEDAR) {
    2197           0 :                 sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
    2198           0 :                 sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
    2199           0 :                 mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
    2200           0 :                 mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
    2201             : 
    2202           0 :                 pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
    2203           0 :                 pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
    2204           0 :                 pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
    2205           0 :         } else {
    2206           0 :                 sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
    2207           0 :                 sclk |= clock_info->r600.ucEngineClockHigh << 16;
    2208           0 :                 mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow);
    2209           0 :                 mclk |= clock_info->r600.ucMemoryClockHigh << 16;
    2210             : 
    2211           0 :                 pl->vddc = le16_to_cpu(clock_info->r600.usVDDC);
    2212           0 :                 pl->flags = le32_to_cpu(clock_info->r600.ulFlags);
    2213             :         }
    2214             : 
    2215           0 :         pl->mclk = mclk;
    2216           0 :         pl->sclk = sclk;
    2217             : 
    2218             :         /* patch up vddc if necessary */
    2219           0 :         if (pl->vddc == 0xff01) {
    2220           0 :                 if (pi->max_vddc)
    2221           0 :                         pl->vddc = pi->max_vddc;
    2222             :         }
    2223             : 
    2224           0 :         if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
    2225           0 :                 pi->acpi_vddc = pl->vddc;
    2226           0 :                 if (rdev->family >= CHIP_CEDAR)
    2227           0 :                         eg_pi->acpi_vddci = pl->vddci;
    2228           0 :                 if (ps->low.flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
    2229           0 :                         pi->acpi_pcie_gen2 = true;
    2230             :                 else
    2231           0 :                         pi->acpi_pcie_gen2 = false;
    2232             :         }
    2233             : 
    2234           0 :         if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
    2235           0 :                 if (rdev->family >= CHIP_BARTS) {
    2236           0 :                         eg_pi->ulv.supported = true;
    2237           0 :                         eg_pi->ulv.pl = pl;
    2238           0 :                 }
    2239             :         }
    2240             : 
    2241           0 :         if (pi->min_vddc_in_table > pl->vddc)
    2242           0 :                 pi->min_vddc_in_table = pl->vddc;
    2243             : 
    2244           0 :         if (pi->max_vddc_in_table < pl->vddc)
    2245           0 :                 pi->max_vddc_in_table = pl->vddc;
    2246             : 
    2247             :         /* patch up boot state */
    2248           0 :         if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
    2249           0 :                 u16 vddc, vddci, mvdd;
    2250           0 :                 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
    2251           0 :                 pl->mclk = rdev->clock.default_mclk;
    2252           0 :                 pl->sclk = rdev->clock.default_sclk;
    2253           0 :                 pl->vddc = vddc;
    2254           0 :                 pl->vddci = vddci;
    2255           0 :         }
    2256             : 
    2257           0 :         if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
    2258             :             ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
    2259           0 :                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
    2260           0 :                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
    2261           0 :                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
    2262           0 :                 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
    2263           0 :         }
    2264           0 : }
    2265             : 
    2266           0 : int rv7xx_parse_power_table(struct radeon_device *rdev)
    2267             : {
    2268           0 :         struct radeon_mode_info *mode_info = &rdev->mode_info;
    2269             :         struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
    2270             :         union pplib_power_state *power_state;
    2271             :         int i, j;
    2272             :         union pplib_clock_info *clock_info;
    2273             :         union power_info *power_info;
    2274             :         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
    2275           0 :         u16 data_offset;
    2276           0 :         u8 frev, crev;
    2277             :         struct rv7xx_ps *ps;
    2278             : 
    2279           0 :         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
    2280             :                                    &frev, &crev, &data_offset))
    2281           0 :                 return -EINVAL;
    2282           0 :         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
    2283             : 
    2284           0 :         rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
    2285           0 :                                   power_info->pplib.ucNumStates, GFP_KERNEL);
    2286           0 :         if (!rdev->pm.dpm.ps)
    2287           0 :                 return -ENOMEM;
    2288             : 
    2289           0 :         for (i = 0; i < power_info->pplib.ucNumStates; i++) {
    2290           0 :                 power_state = (union pplib_power_state *)
    2291           0 :                         (mode_info->atom_context->bios + data_offset +
    2292           0 :                          le16_to_cpu(power_info->pplib.usStateArrayOffset) +
    2293           0 :                          i * power_info->pplib.ucStateEntrySize);
    2294           0 :                 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
    2295           0 :                         (mode_info->atom_context->bios + data_offset +
    2296           0 :                          le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
    2297           0 :                          (power_state->v1.ucNonClockStateIndex *
    2298           0 :                           power_info->pplib.ucNonClockSize));
    2299           0 :                 if (power_info->pplib.ucStateEntrySize - 1) {
    2300             :                         u8 *idx;
    2301           0 :                         ps = kzalloc(sizeof(struct rv7xx_ps), GFP_KERNEL);
    2302           0 :                         if (ps == NULL) {
    2303           0 :                                 kfree(rdev->pm.dpm.ps);
    2304           0 :                                 return -ENOMEM;
    2305             :                         }
    2306           0 :                         rdev->pm.dpm.ps[i].ps_priv = ps;
    2307           0 :                         rv7xx_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
    2308             :                                                          non_clock_info,
    2309           0 :                                                          power_info->pplib.ucNonClockSize);
    2310           0 :                         idx = (u8 *)&power_state->v1.ucClockStateIndices[0];
    2311           0 :                         for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
    2312           0 :                                 clock_info = (union pplib_clock_info *)
    2313           0 :                                         (mode_info->atom_context->bios + data_offset +
    2314           0 :                                          le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
    2315           0 :                                          (idx[j] * power_info->pplib.ucClockInfoSize));
    2316           0 :                                 rv7xx_parse_pplib_clock_info(rdev,
    2317           0 :                                                              &rdev->pm.dpm.ps[i], j,
    2318             :                                                              clock_info);
    2319             :                         }
    2320           0 :                 }
    2321             :         }
    2322           0 :         rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
    2323           0 :         return 0;
    2324           0 : }
    2325             : 
    2326           0 : void rv770_get_engine_memory_ss(struct radeon_device *rdev)
    2327             : {
    2328           0 :         struct rv7xx_power_info *pi = rv770_get_pi(rdev);
    2329           0 :         struct radeon_atom_ss ss;
    2330             : 
    2331           0 :         pi->sclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
    2332             :                                                        ASIC_INTERNAL_ENGINE_SS, 0);
    2333           0 :         pi->mclk_ss = radeon_atombios_get_asic_ss_info(rdev, &ss,
    2334             :                                                        ASIC_INTERNAL_MEMORY_SS, 0);
    2335             : 
    2336           0 :         if (pi->sclk_ss || pi->mclk_ss)
    2337           0 :                 pi->dynamic_ss = true;
    2338             :         else
    2339           0 :                 pi->dynamic_ss = false;
    2340           0 : }
    2341             : 
    2342           0 : int rv770_dpm_init(struct radeon_device *rdev)
    2343             : {
    2344             :         struct rv7xx_power_info *pi;
    2345           0 :         struct atom_clock_dividers dividers;
    2346             :         int ret;
    2347             : 
    2348           0 :         pi = kzalloc(sizeof(struct rv7xx_power_info), GFP_KERNEL);
    2349           0 :         if (pi == NULL)
    2350           0 :                 return -ENOMEM;
    2351           0 :         rdev->pm.dpm.priv = pi;
    2352             : 
    2353           0 :         rv770_get_max_vddc(rdev);
    2354             : 
    2355           0 :         pi->acpi_vddc = 0;
    2356           0 :         pi->min_vddc_in_table = 0;
    2357           0 :         pi->max_vddc_in_table = 0;
    2358             : 
    2359           0 :         ret = r600_get_platform_caps(rdev);
    2360           0 :         if (ret)
    2361           0 :                 return ret;
    2362             : 
    2363           0 :         ret = rv7xx_parse_power_table(rdev);
    2364           0 :         if (ret)
    2365           0 :                 return ret;
    2366             : 
    2367           0 :         if (rdev->pm.dpm.voltage_response_time == 0)
    2368           0 :                 rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
    2369           0 :         if (rdev->pm.dpm.backbias_response_time == 0)
    2370           0 :                 rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
    2371             : 
    2372           0 :         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
    2373             :                                              0, false, &dividers);
    2374           0 :         if (ret)
    2375           0 :                 pi->ref_div = dividers.ref_div + 1;
    2376             :         else
    2377           0 :                 pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
    2378             : 
    2379           0 :         pi->mclk_strobe_mode_threshold = 30000;
    2380           0 :         pi->mclk_edc_enable_threshold = 30000;
    2381             : 
    2382           0 :         pi->rlp = RV770_RLP_DFLT;
    2383           0 :         pi->rmp = RV770_RMP_DFLT;
    2384           0 :         pi->lhp = RV770_LHP_DFLT;
    2385           0 :         pi->lmp = RV770_LMP_DFLT;
    2386             : 
    2387           0 :         pi->voltage_control =
    2388           0 :                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
    2389             : 
    2390           0 :         pi->mvdd_control =
    2391           0 :                 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
    2392             : 
    2393           0 :         rv770_get_engine_memory_ss(rdev);
    2394             : 
    2395           0 :         pi->asi = RV770_ASI_DFLT;
    2396           0 :         pi->pasi = RV770_HASI_DFLT;
    2397           0 :         pi->vrc = RV770_VRC_DFLT;
    2398             : 
    2399           0 :         pi->power_gating = false;
    2400             : 
    2401           0 :         pi->gfx_clock_gating = true;
    2402             : 
    2403           0 :         pi->mg_clock_gating = true;
    2404           0 :         pi->mgcgtssm = true;
    2405             : 
    2406           0 :         pi->dynamic_pcie_gen2 = true;
    2407             : 
    2408           0 :         if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
    2409           0 :                 pi->thermal_protection = true;
    2410             :         else
    2411           0 :                 pi->thermal_protection = false;
    2412             : 
    2413           0 :         pi->display_gap = true;
    2414             : 
    2415           0 :         if (rdev->flags & RADEON_IS_MOBILITY)
    2416           0 :                 pi->dcodt = true;
    2417             :         else
    2418           0 :                 pi->dcodt = false;
    2419             : 
    2420           0 :         pi->ulps = true;
    2421             : 
    2422           0 :         pi->mclk_stutter_mode_threshold = 0;
    2423             : 
    2424           0 :         pi->sram_end = SMC_RAM_END;
    2425           0 :         pi->state_table_start = RV770_SMC_TABLE_ADDRESS;
    2426           0 :         pi->soft_regs_start = RV770_SMC_SOFT_REGISTERS_START;
    2427             : 
    2428           0 :         return 0;
    2429           0 : }
    2430             : 
    2431           0 : void rv770_dpm_print_power_state(struct radeon_device *rdev,
    2432             :                                  struct radeon_ps *rps)
    2433             : {
    2434           0 :         struct rv7xx_ps *ps = rv770_get_ps(rps);
    2435             :         struct rv7xx_pl *pl;
    2436             : 
    2437           0 :         r600_dpm_print_class_info(rps->class, rps->class2);
    2438           0 :         r600_dpm_print_cap_info(rps->caps);
    2439           0 :         printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
    2440           0 :         if (rdev->family >= CHIP_CEDAR) {
    2441             :                 pl = &ps->low;
    2442           0 :                 printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u vddci: %u\n",
    2443             :                        pl->sclk, pl->mclk, pl->vddc, pl->vddci);
    2444           0 :                 pl = &ps->medium;
    2445           0 :                 printk("\t\tpower level 1    sclk: %u mclk: %u vddc: %u vddci: %u\n",
    2446             :                        pl->sclk, pl->mclk, pl->vddc, pl->vddci);
    2447           0 :                 pl = &ps->high;
    2448           0 :                 printk("\t\tpower level 2    sclk: %u mclk: %u vddc: %u vddci: %u\n",
    2449             :                        pl->sclk, pl->mclk, pl->vddc, pl->vddci);
    2450           0 :         } else {
    2451             :                 pl = &ps->low;
    2452           0 :                 printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u\n",
    2453             :                        pl->sclk, pl->mclk, pl->vddc);
    2454           0 :                 pl = &ps->medium;
    2455           0 :                 printk("\t\tpower level 1    sclk: %u mclk: %u vddc: %u\n",
    2456             :                        pl->sclk, pl->mclk, pl->vddc);
    2457           0 :                 pl = &ps->high;
    2458           0 :                 printk("\t\tpower level 2    sclk: %u mclk: %u vddc: %u\n",
    2459             :                        pl->sclk, pl->mclk, pl->vddc);
    2460             :         }
    2461           0 :         r600_dpm_print_ps_status(rdev, rps);
    2462           0 : }
    2463             : 
    2464           0 : void rv770_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
    2465             :                                                        struct seq_file *m)
    2466             : {
    2467           0 :         struct radeon_ps *rps = rdev->pm.dpm.current_ps;
    2468           0 :         struct rv7xx_ps *ps = rv770_get_ps(rps);
    2469             :         struct rv7xx_pl *pl;
    2470             :         u32 current_index =
    2471           0 :                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
    2472             :                 CURRENT_PROFILE_INDEX_SHIFT;
    2473             : 
    2474           0 :         if (current_index > 2) {
    2475           0 :                 seq_printf(m, "invalid dpm profile %d\n", current_index);
    2476           0 :         } else {
    2477           0 :                 if (current_index == 0)
    2478           0 :                         pl = &ps->low;
    2479           0 :                 else if (current_index == 1)
    2480           0 :                         pl = &ps->medium;
    2481             :                 else /* current_index == 2 */
    2482           0 :                         pl = &ps->high;
    2483           0 :                 seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
    2484           0 :                 if (rdev->family >= CHIP_CEDAR) {
    2485           0 :                         seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
    2486           0 :                                    current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
    2487           0 :                 } else {
    2488           0 :                         seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
    2489             :                                    current_index, pl->sclk, pl->mclk, pl->vddc);
    2490             :                 }
    2491             :         }
    2492           0 : }
    2493             : 
    2494           0 : u32 rv770_dpm_get_current_sclk(struct radeon_device *rdev)
    2495             : {
    2496           0 :         struct radeon_ps *rps = rdev->pm.dpm.current_ps;
    2497           0 :         struct rv7xx_ps *ps = rv770_get_ps(rps);
    2498             :         struct rv7xx_pl *pl;
    2499             :         u32 current_index =
    2500           0 :                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
    2501             :                 CURRENT_PROFILE_INDEX_SHIFT;
    2502             : 
    2503           0 :         if (current_index > 2) {
    2504           0 :                 return 0;
    2505             :         } else {
    2506           0 :                 if (current_index == 0)
    2507           0 :                         pl = &ps->low;
    2508           0 :                 else if (current_index == 1)
    2509           0 :                         pl = &ps->medium;
    2510             :                 else /* current_index == 2 */
    2511           0 :                         pl = &ps->high;
    2512           0 :                 return  pl->sclk;
    2513             :         }
    2514           0 : }
    2515             : 
    2516           0 : u32 rv770_dpm_get_current_mclk(struct radeon_device *rdev)
    2517             : {
    2518           0 :         struct radeon_ps *rps = rdev->pm.dpm.current_ps;
    2519           0 :         struct rv7xx_ps *ps = rv770_get_ps(rps);
    2520             :         struct rv7xx_pl *pl;
    2521             :         u32 current_index =
    2522           0 :                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
    2523             :                 CURRENT_PROFILE_INDEX_SHIFT;
    2524             : 
    2525           0 :         if (current_index > 2) {
    2526           0 :                 return 0;
    2527             :         } else {
    2528           0 :                 if (current_index == 0)
    2529           0 :                         pl = &ps->low;
    2530           0 :                 else if (current_index == 1)
    2531           0 :                         pl = &ps->medium;
    2532             :                 else /* current_index == 2 */
    2533           0 :                         pl = &ps->high;
    2534           0 :                 return  pl->mclk;
    2535             :         }
    2536           0 : }
    2537             : 
    2538           0 : void rv770_dpm_fini(struct radeon_device *rdev)
    2539             : {
    2540             :         int i;
    2541             : 
    2542           0 :         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
    2543           0 :                 kfree(rdev->pm.dpm.ps[i].ps_priv);
    2544             :         }
    2545           0 :         kfree(rdev->pm.dpm.ps);
    2546           0 :         kfree(rdev->pm.dpm.priv);
    2547           0 : }
    2548             : 
    2549           0 : u32 rv770_dpm_get_sclk(struct radeon_device *rdev, bool low)
    2550             : {
    2551           0 :         struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
    2552             : 
    2553           0 :         if (low)
    2554           0 :                 return requested_state->low.sclk;
    2555             :         else
    2556           0 :                 return requested_state->high.sclk;
    2557           0 : }
    2558             : 
    2559           0 : u32 rv770_dpm_get_mclk(struct radeon_device *rdev, bool low)
    2560             : {
    2561           0 :         struct rv7xx_ps *requested_state = rv770_get_ps(rdev->pm.dpm.requested_ps);
    2562             : 
    2563           0 :         if (low)
    2564           0 :                 return requested_state->low.mclk;
    2565             :         else
    2566           0 :                 return requested_state->high.mclk;
    2567           0 : }
    2568             : 
    2569           0 : bool rv770_dpm_vblank_too_short(struct radeon_device *rdev)
    2570             : {
    2571           0 :         u32 vblank_time = r600_dpm_get_vblank_time(rdev);
    2572             :         u32 switch_limit = 200; /* 300 */
    2573             : 
    2574             :         /* RV770 */
    2575             :         /* mclk switching doesn't seem to work reliably on desktop RV770s */
    2576           0 :         if ((rdev->family == CHIP_RV770) &&
    2577           0 :             !(rdev->flags & RADEON_IS_MOBILITY))
    2578           0 :                 switch_limit = 0xffffffff; /* disable mclk switching */
    2579             : 
    2580           0 :         if (vblank_time < switch_limit)
    2581           0 :                 return true;
    2582             :         else
    2583           0 :                 return false;
    2584             : 
    2585           0 : }

Generated by: LCOV version 1.13