Subversion Repositories Kolibri OS

Rev

Rev 6104 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2012 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.  */
  23.  
  24. #include "drmP.h"
  25. #include "radeon.h"
  26. #include "radeon_asic.h"
  27. #include "sumod.h"
  28. #include "r600_dpm.h"
  29. #include "cypress_dpm.h"
  30. #include "sumo_dpm.h"
  31. #include <linux/seq_file.h>
  32.  
  33. #define SUMO_MAX_DEEPSLEEP_DIVIDER_ID 5
  34. #define SUMO_MINIMUM_ENGINE_CLOCK 800
  35. #define BOOST_DPM_LEVEL 7
  36.  
  37. static const u32 sumo_utc[SUMO_PM_NUMBER_OF_TC] =
  38. {
  39.         SUMO_UTC_DFLT_00,
  40.         SUMO_UTC_DFLT_01,
  41.         SUMO_UTC_DFLT_02,
  42.         SUMO_UTC_DFLT_03,
  43.         SUMO_UTC_DFLT_04,
  44.         SUMO_UTC_DFLT_05,
  45.         SUMO_UTC_DFLT_06,
  46.         SUMO_UTC_DFLT_07,
  47.         SUMO_UTC_DFLT_08,
  48.         SUMO_UTC_DFLT_09,
  49.         SUMO_UTC_DFLT_10,
  50.         SUMO_UTC_DFLT_11,
  51.         SUMO_UTC_DFLT_12,
  52.         SUMO_UTC_DFLT_13,
  53.         SUMO_UTC_DFLT_14,
  54. };
  55.  
  56. static const u32 sumo_dtc[SUMO_PM_NUMBER_OF_TC] =
  57. {
  58.         SUMO_DTC_DFLT_00,
  59.         SUMO_DTC_DFLT_01,
  60.         SUMO_DTC_DFLT_02,
  61.         SUMO_DTC_DFLT_03,
  62.         SUMO_DTC_DFLT_04,
  63.         SUMO_DTC_DFLT_05,
  64.         SUMO_DTC_DFLT_06,
  65.         SUMO_DTC_DFLT_07,
  66.         SUMO_DTC_DFLT_08,
  67.         SUMO_DTC_DFLT_09,
  68.         SUMO_DTC_DFLT_10,
  69.         SUMO_DTC_DFLT_11,
  70.         SUMO_DTC_DFLT_12,
  71.         SUMO_DTC_DFLT_13,
  72.         SUMO_DTC_DFLT_14,
  73. };
  74.  
  75. static struct sumo_ps *sumo_get_ps(struct radeon_ps *rps)
  76. {
  77.         struct sumo_ps *ps = rps->ps_priv;
  78.  
  79.         return ps;
  80. }
  81.  
  82. struct sumo_power_info *sumo_get_pi(struct radeon_device *rdev)
  83. {
  84.         struct sumo_power_info *pi = rdev->pm.dpm.priv;
  85.  
  86.         return pi;
  87. }
  88.  
  89. static void sumo_gfx_clockgating_enable(struct radeon_device *rdev, bool enable)
  90. {
  91.         if (enable)
  92.                 WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
  93.         else {
  94.                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
  95.                 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
  96.                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
  97.                 RREG32(GB_ADDR_CONFIG);
  98.         }
  99. }
  100.  
  101. #define CGCG_CGTT_LOCAL0_MASK 0xE5BFFFFF
  102. #define CGCG_CGTT_LOCAL1_MASK 0xEFFF07FF
  103.  
  104. static void sumo_mg_clockgating_enable(struct radeon_device *rdev, bool enable)
  105. {
  106.         u32 local0;
  107.         u32 local1;
  108.  
  109.         local0 = RREG32(CG_CGTT_LOCAL_0);
  110.         local1 = RREG32(CG_CGTT_LOCAL_1);
  111.  
  112.         if (enable) {
  113.                 WREG32(CG_CGTT_LOCAL_0, (0 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
  114.                 WREG32(CG_CGTT_LOCAL_1, (0 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
  115.         } else {
  116.                 WREG32(CG_CGTT_LOCAL_0, (0xFFFFFFFF & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
  117.                 WREG32(CG_CGTT_LOCAL_1, (0xFFFFCFFF & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
  118.         }
  119. }
  120.  
  121. static void sumo_program_git(struct radeon_device *rdev)
  122. {
  123.         u32 p, u;
  124.         u32 xclk = radeon_get_xclk(rdev);
  125.  
  126.         r600_calculate_u_and_p(SUMO_GICST_DFLT,
  127.                                xclk, 16, &p, &u);
  128.  
  129.         WREG32_P(CG_GIT, CG_GICST(p), ~CG_GICST_MASK);
  130. }
  131.  
  132. static void sumo_program_grsd(struct radeon_device *rdev)
  133. {
  134.         u32 p, u;
  135.         u32 xclk = radeon_get_xclk(rdev);
  136.         u32 grs = 256 * 25 / 100;
  137.  
  138.         r600_calculate_u_and_p(1, xclk, 14, &p, &u);
  139.  
  140.         WREG32(CG_GCOOR, PHC(grs) | SDC(p) | SU(u));
  141. }
  142.  
  143. void sumo_gfx_clockgating_initialize(struct radeon_device *rdev)
  144. {
  145.         sumo_program_git(rdev);
  146.         sumo_program_grsd(rdev);
  147. }
  148.  
  149. static void sumo_gfx_powergating_initialize(struct radeon_device *rdev)
  150. {
  151.         u32 rcu_pwr_gating_cntl;
  152.         u32 p, u;
  153.         u32 p_c, p_p, d_p;
  154.         u32 r_t, i_t;
  155.         u32 xclk = radeon_get_xclk(rdev);
  156.  
  157.         if (rdev->family == CHIP_PALM) {
  158.                 p_c = 4;
  159.                 d_p = 10;
  160.                 r_t = 10;
  161.                 i_t = 4;
  162.                 p_p = 50 + 1000/200 + 6 * 32;
  163.         } else {
  164.                 p_c = 16;
  165.                 d_p = 50;
  166.                 r_t = 50;
  167.                 i_t  = 50;
  168.                 p_p = 113;
  169.         }
  170.  
  171.         WREG32(CG_SCRATCH2, 0x01B60A17);
  172.  
  173.         r600_calculate_u_and_p(SUMO_GFXPOWERGATINGT_DFLT,
  174.                                xclk, 16, &p, &u);
  175.  
  176.         WREG32_P(CG_PWR_GATING_CNTL, PGP(p) | PGU(u),
  177.                  ~(PGP_MASK | PGU_MASK));
  178.  
  179.         r600_calculate_u_and_p(SUMO_VOLTAGEDROPT_DFLT,
  180.                                xclk, 16, &p, &u);
  181.  
  182.         WREG32_P(CG_CG_VOLTAGE_CNTL, PGP(p) | PGU(u),
  183.                  ~(PGP_MASK | PGU_MASK));
  184.  
  185.         if (rdev->family == CHIP_PALM) {
  186.                 WREG32_RCU(RCU_PWR_GATING_SEQ0, 0x10103210);
  187.                 WREG32_RCU(RCU_PWR_GATING_SEQ1, 0x10101010);
  188.         } else {
  189.                 WREG32_RCU(RCU_PWR_GATING_SEQ0, 0x76543210);
  190.                 WREG32_RCU(RCU_PWR_GATING_SEQ1, 0xFEDCBA98);
  191.         }
  192.  
  193.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
  194.         rcu_pwr_gating_cntl &=
  195.                 ~(RSVD_MASK | PCV_MASK | PGS_MASK);
  196.         rcu_pwr_gating_cntl |= PCV(p_c) | PGS(1) | PWR_GATING_EN;
  197.         if (rdev->family == CHIP_PALM) {
  198.                 rcu_pwr_gating_cntl &= ~PCP_MASK;
  199.                 rcu_pwr_gating_cntl |= PCP(0x77);
  200.         }
  201.         WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
  202.  
  203.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
  204.         rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
  205.         rcu_pwr_gating_cntl |= MPPU(p_p) | MPPD(50);
  206.         WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
  207.  
  208.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
  209.         rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
  210.         rcu_pwr_gating_cntl |= DPPU(d_p) | DPPD(50);
  211.         WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
  212.  
  213.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_4);
  214.         rcu_pwr_gating_cntl &= ~(RT_MASK | IT_MASK);
  215.         rcu_pwr_gating_cntl |= RT(r_t) | IT(i_t);
  216.         WREG32_RCU(RCU_PWR_GATING_CNTL_4, rcu_pwr_gating_cntl);
  217.  
  218.         if (rdev->family == CHIP_PALM)
  219.                 WREG32_RCU(RCU_PWR_GATING_CNTL_5, 0xA02);
  220.  
  221.         sumo_smu_pg_init(rdev);
  222.  
  223.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
  224.         rcu_pwr_gating_cntl &=
  225.                 ~(RSVD_MASK | PCV_MASK | PGS_MASK);
  226.         rcu_pwr_gating_cntl |= PCV(p_c) | PGS(4) | PWR_GATING_EN;
  227.         if (rdev->family == CHIP_PALM) {
  228.                 rcu_pwr_gating_cntl &= ~PCP_MASK;
  229.                 rcu_pwr_gating_cntl |= PCP(0x77);
  230.         }
  231.         WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
  232.  
  233.         if (rdev->family == CHIP_PALM) {
  234.                 rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
  235.                 rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
  236.                 rcu_pwr_gating_cntl |= MPPU(113) | MPPD(50);
  237.                 WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
  238.  
  239.                 rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
  240.                 rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
  241.                 rcu_pwr_gating_cntl |= DPPU(16) | DPPD(50);
  242.                 WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
  243.         }
  244.  
  245.         sumo_smu_pg_init(rdev);
  246.  
  247.         rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL);
  248.         rcu_pwr_gating_cntl &=
  249.                 ~(RSVD_MASK | PCV_MASK | PGS_MASK);
  250.         rcu_pwr_gating_cntl |= PGS(5) | PWR_GATING_EN;
  251.  
  252.         if (rdev->family == CHIP_PALM) {
  253.                 rcu_pwr_gating_cntl |= PCV(4);
  254.                 rcu_pwr_gating_cntl &= ~PCP_MASK;
  255.                 rcu_pwr_gating_cntl |= PCP(0x77);
  256.         } else
  257.                 rcu_pwr_gating_cntl |= PCV(11);
  258.         WREG32_RCU(RCU_PWR_GATING_CNTL, rcu_pwr_gating_cntl);
  259.  
  260.         if (rdev->family == CHIP_PALM) {
  261.                 rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_2);
  262.                 rcu_pwr_gating_cntl &= ~(MPPU_MASK | MPPD_MASK);
  263.                 rcu_pwr_gating_cntl |= MPPU(113) | MPPD(50);
  264.                 WREG32_RCU(RCU_PWR_GATING_CNTL_2, rcu_pwr_gating_cntl);
  265.  
  266.                 rcu_pwr_gating_cntl = RREG32_RCU(RCU_PWR_GATING_CNTL_3);
  267.                 rcu_pwr_gating_cntl &= ~(DPPU_MASK | DPPD_MASK);
  268.                 rcu_pwr_gating_cntl |= DPPU(22) | DPPD(50);
  269.                 WREG32_RCU(RCU_PWR_GATING_CNTL_3, rcu_pwr_gating_cntl);
  270.         }
  271.  
  272.         sumo_smu_pg_init(rdev);
  273. }
  274.  
  275. static void sumo_gfx_powergating_enable(struct radeon_device *rdev, bool enable)
  276. {
  277.         if (enable)
  278.                 WREG32_P(CG_PWR_GATING_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
  279.         else {
  280.                 WREG32_P(CG_PWR_GATING_CNTL, 0, ~DYN_PWR_DOWN_EN);
  281.                 RREG32(GB_ADDR_CONFIG);
  282.         }
  283. }
  284.  
  285. static int sumo_enable_clock_power_gating(struct radeon_device *rdev)
  286. {
  287.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  288.  
  289.         if (pi->enable_gfx_clock_gating)
  290.                 sumo_gfx_clockgating_initialize(rdev);
  291.         if (pi->enable_gfx_power_gating)
  292.                 sumo_gfx_powergating_initialize(rdev);
  293.         if (pi->enable_mg_clock_gating)
  294.                 sumo_mg_clockgating_enable(rdev, true);
  295.         if (pi->enable_gfx_clock_gating)
  296.                 sumo_gfx_clockgating_enable(rdev, true);
  297.         if (pi->enable_gfx_power_gating)
  298.                 sumo_gfx_powergating_enable(rdev, true);
  299.  
  300.         return 0;
  301. }
  302.  
  303. static void sumo_disable_clock_power_gating(struct radeon_device *rdev)
  304. {
  305.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  306.  
  307.         if (pi->enable_gfx_clock_gating)
  308.                 sumo_gfx_clockgating_enable(rdev, false);
  309.         if (pi->enable_gfx_power_gating)
  310.                 sumo_gfx_powergating_enable(rdev, false);
  311.         if (pi->enable_mg_clock_gating)
  312.                 sumo_mg_clockgating_enable(rdev, false);
  313. }
  314.  
  315. static void sumo_calculate_bsp(struct radeon_device *rdev,
  316.                                u32 high_clk)
  317. {
  318.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  319.         u32 xclk = radeon_get_xclk(rdev);
  320.  
  321.         pi->pasi = 65535 * 100 / high_clk;
  322.         pi->asi = 65535 * 100 / high_clk;
  323.  
  324.         r600_calculate_u_and_p(pi->asi,
  325.                                xclk, 16, &pi->bsp, &pi->bsu);
  326.  
  327.         r600_calculate_u_and_p(pi->pasi,
  328.                                xclk, 16, &pi->pbsp, &pi->pbsu);
  329.  
  330.         pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
  331.         pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
  332. }
  333.  
  334. static void sumo_init_bsp(struct radeon_device *rdev)
  335. {
  336.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  337.  
  338.         WREG32(CG_BSP_0, pi->psp);
  339. }
  340.  
  341.  
  342. static void sumo_program_bsp(struct radeon_device *rdev,
  343.                              struct radeon_ps *rps)
  344. {
  345.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  346.         struct sumo_ps *ps = sumo_get_ps(rps);
  347.         u32 i;
  348.         u32 highest_engine_clock = ps->levels[ps->num_levels - 1].sclk;
  349.  
  350.         if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
  351.                 highest_engine_clock = pi->boost_pl.sclk;
  352.  
  353.         sumo_calculate_bsp(rdev, highest_engine_clock);
  354.  
  355.         for (i = 0; i < ps->num_levels - 1; i++)
  356.                 WREG32(CG_BSP_0 + (i * 4), pi->dsp);
  357.  
  358.         WREG32(CG_BSP_0 + (i * 4), pi->psp);
  359.  
  360.         if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
  361.                 WREG32(CG_BSP_0 + (BOOST_DPM_LEVEL * 4), pi->psp);
  362. }
  363.  
  364. static void sumo_write_at(struct radeon_device *rdev,
  365.                           u32 index, u32 value)
  366. {
  367.         if (index == 0)
  368.                 WREG32(CG_AT_0, value);
  369.         else if (index == 1)
  370.                 WREG32(CG_AT_1, value);
  371.         else if (index == 2)
  372.                 WREG32(CG_AT_2, value);
  373.         else if (index == 3)
  374.                 WREG32(CG_AT_3, value);
  375.         else if (index == 4)
  376.                 WREG32(CG_AT_4, value);
  377.         else if (index == 5)
  378.                 WREG32(CG_AT_5, value);
  379.         else if (index == 6)
  380.                 WREG32(CG_AT_6, value);
  381.         else if (index == 7)
  382.                 WREG32(CG_AT_7, value);
  383. }
  384.  
  385. static void sumo_program_at(struct radeon_device *rdev,
  386.                             struct radeon_ps *rps)
  387. {
  388.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  389.         struct sumo_ps *ps = sumo_get_ps(rps);
  390.         u32 asi;
  391.         u32 i;
  392.         u32 m_a;
  393.         u32 a_t;
  394.         u32 r[SUMO_MAX_HARDWARE_POWERLEVELS];
  395.         u32 l[SUMO_MAX_HARDWARE_POWERLEVELS];
  396.  
  397.         r[0] = SUMO_R_DFLT0;
  398.         r[1] = SUMO_R_DFLT1;
  399.         r[2] = SUMO_R_DFLT2;
  400.         r[3] = SUMO_R_DFLT3;
  401.         r[4] = SUMO_R_DFLT4;
  402.  
  403.         l[0] = SUMO_L_DFLT0;
  404.         l[1] = SUMO_L_DFLT1;
  405.         l[2] = SUMO_L_DFLT2;
  406.         l[3] = SUMO_L_DFLT3;
  407.         l[4] = SUMO_L_DFLT4;
  408.  
  409.         for (i = 0; i < ps->num_levels; i++) {
  410.                 asi = (i == ps->num_levels - 1) ? pi->pasi : pi->asi;
  411.  
  412.                 m_a = asi * ps->levels[i].sclk / 100;
  413.  
  414.                 a_t = CG_R(m_a * r[i] / 100) | CG_L(m_a * l[i] / 100);
  415.  
  416.                 sumo_write_at(rdev, i, a_t);
  417.         }
  418.  
  419.         if (ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE) {
  420.                 asi = pi->pasi;
  421.  
  422.                 m_a = asi * pi->boost_pl.sclk / 100;
  423.  
  424.                 a_t = CG_R(m_a * r[ps->num_levels - 1] / 100) |
  425.                         CG_L(m_a * l[ps->num_levels - 1] / 100);
  426.  
  427.                 sumo_write_at(rdev, BOOST_DPM_LEVEL, a_t);
  428.         }
  429. }
  430.  
  431. static void sumo_program_tp(struct radeon_device *rdev)
  432. {
  433.         int i;
  434.         enum r600_td td = R600_TD_DFLT;
  435.  
  436.         for (i = 0; i < SUMO_PM_NUMBER_OF_TC; i++) {
  437.                 WREG32_P(CG_FFCT_0 + (i * 4), UTC_0(sumo_utc[i]), ~UTC_0_MASK);
  438.                 WREG32_P(CG_FFCT_0 + (i * 4), DTC_0(sumo_dtc[i]), ~DTC_0_MASK);
  439.         }
  440.  
  441.         if (td == R600_TD_AUTO)
  442.                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
  443.         else
  444.                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
  445.  
  446.         if (td == R600_TD_UP)
  447.                 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
  448.  
  449.         if (td == R600_TD_DOWN)
  450.                 WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
  451. }
  452.  
  453. void sumo_program_vc(struct radeon_device *rdev, u32 vrc)
  454. {
  455.         WREG32(CG_FTV, vrc);
  456. }
  457.  
  458. void sumo_clear_vc(struct radeon_device *rdev)
  459. {
  460.         WREG32(CG_FTV, 0);
  461. }
  462.  
  463. void sumo_program_sstp(struct radeon_device *rdev)
  464. {
  465.         u32 p, u;
  466.         u32 xclk = radeon_get_xclk(rdev);
  467.  
  468.         r600_calculate_u_and_p(SUMO_SST_DFLT,
  469.                                xclk, 16, &p, &u);
  470.  
  471.         WREG32(CG_SSP, SSTU(u) | SST(p));
  472. }
  473.  
  474. static void sumo_set_divider_value(struct radeon_device *rdev,
  475.                                    u32 index, u32 divider)
  476. {
  477.         u32 reg_index = index / 4;
  478.         u32 field_index = index % 4;
  479.  
  480.         if (field_index == 0)
  481.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  482.                          SCLK_FSTATE_0_DIV(divider), ~SCLK_FSTATE_0_DIV_MASK);
  483.         else if (field_index == 1)
  484.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  485.                          SCLK_FSTATE_1_DIV(divider), ~SCLK_FSTATE_1_DIV_MASK);
  486.         else if (field_index == 2)
  487.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  488.                          SCLK_FSTATE_2_DIV(divider), ~SCLK_FSTATE_2_DIV_MASK);
  489.         else if (field_index == 3)
  490.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  491.                          SCLK_FSTATE_3_DIV(divider), ~SCLK_FSTATE_3_DIV_MASK);
  492. }
  493.  
  494. static void sumo_set_ds_dividers(struct radeon_device *rdev,
  495.                                  u32 index, u32 divider)
  496. {
  497.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  498.  
  499.         if (pi->enable_sclk_ds) {
  500.                 u32 dpm_ctrl = RREG32(CG_SCLK_DPM_CTRL_6);
  501.  
  502.                 dpm_ctrl &= ~(0x7 << (index * 3));
  503.                 dpm_ctrl |= (divider << (index * 3));
  504.                 WREG32(CG_SCLK_DPM_CTRL_6, dpm_ctrl);
  505.         }
  506. }
  507.  
  508. static void sumo_set_ss_dividers(struct radeon_device *rdev,
  509.                                  u32 index, u32 divider)
  510. {
  511.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  512.  
  513.         if (pi->enable_sclk_ds) {
  514.                 u32 dpm_ctrl = RREG32(CG_SCLK_DPM_CTRL_11);
  515.  
  516.                 dpm_ctrl &= ~(0x7 << (index * 3));
  517.                 dpm_ctrl |= (divider << (index * 3));
  518.                 WREG32(CG_SCLK_DPM_CTRL_11, dpm_ctrl);
  519.         }
  520. }
  521.  
  522. static void sumo_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
  523. {
  524.         u32 voltage_cntl = RREG32(CG_DPM_VOLTAGE_CNTL);
  525.  
  526.         voltage_cntl &= ~(DPM_STATE0_LEVEL_MASK << (index * 2));
  527.         voltage_cntl |= (vid << (DPM_STATE0_LEVEL_SHIFT + index * 2));
  528.         WREG32(CG_DPM_VOLTAGE_CNTL, voltage_cntl);
  529. }
  530.  
  531. static void sumo_set_allos_gnb_slow(struct radeon_device *rdev, u32 index, u32 gnb_slow)
  532. {
  533.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  534.         u32 temp = gnb_slow;
  535.         u32 cg_sclk_dpm_ctrl_3;
  536.  
  537.         if (pi->driver_nbps_policy_disable)
  538.                 temp = 1;
  539.  
  540.         cg_sclk_dpm_ctrl_3 = RREG32(CG_SCLK_DPM_CTRL_3);
  541.         cg_sclk_dpm_ctrl_3 &= ~(GNB_SLOW_FSTATE_0_MASK << index);
  542.         cg_sclk_dpm_ctrl_3 |= (temp << (GNB_SLOW_FSTATE_0_SHIFT + index));
  543.  
  544.         WREG32(CG_SCLK_DPM_CTRL_3, cg_sclk_dpm_ctrl_3);
  545. }
  546.  
  547. static void sumo_program_power_level(struct radeon_device *rdev,
  548.                                      struct sumo_pl *pl, u32 index)
  549. {
  550.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  551.         int ret;
  552.         struct atom_clock_dividers dividers;
  553.         u32 ds_en = RREG32(DEEP_SLEEP_CNTL) & ENABLE_DS;
  554.  
  555.         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  556.                                              pl->sclk, false, &dividers);
  557.         if (ret)
  558.                 return;
  559.  
  560.         sumo_set_divider_value(rdev, index, dividers.post_div);
  561.  
  562.         sumo_set_vid(rdev, index, pl->vddc_index);
  563.  
  564.         if (pl->ss_divider_index == 0 || pl->ds_divider_index == 0) {
  565.                 if (ds_en)
  566.                         WREG32_P(DEEP_SLEEP_CNTL, 0, ~ENABLE_DS);
  567.         } else {
  568.                 sumo_set_ss_dividers(rdev, index, pl->ss_divider_index);
  569.                 sumo_set_ds_dividers(rdev, index, pl->ds_divider_index);
  570.  
  571.                 if (!ds_en)
  572.                         WREG32_P(DEEP_SLEEP_CNTL, ENABLE_DS, ~ENABLE_DS);
  573.         }
  574.  
  575.         sumo_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
  576.  
  577.         if (pi->enable_boost)
  578.                 sumo_set_tdp_limit(rdev, index, pl->sclk_dpm_tdp_limit);
  579. }
  580.  
  581. static void sumo_power_level_enable(struct radeon_device *rdev, u32 index, bool enable)
  582. {
  583.         u32 reg_index = index / 4;
  584.         u32 field_index = index % 4;
  585.  
  586.         if (field_index == 0)
  587.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  588.                          enable ? SCLK_FSTATE_0_VLD : 0, ~SCLK_FSTATE_0_VLD);
  589.         else if (field_index == 1)
  590.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  591.                          enable ? SCLK_FSTATE_1_VLD : 0, ~SCLK_FSTATE_1_VLD);
  592.         else if (field_index == 2)
  593.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  594.                          enable ? SCLK_FSTATE_2_VLD : 0, ~SCLK_FSTATE_2_VLD);
  595.         else if (field_index == 3)
  596.                 WREG32_P(CG_SCLK_DPM_CTRL + (reg_index * 4),
  597.                          enable ? SCLK_FSTATE_3_VLD : 0, ~SCLK_FSTATE_3_VLD);
  598. }
  599.  
  600. static bool sumo_dpm_enabled(struct radeon_device *rdev)
  601. {
  602.         if (RREG32(CG_SCLK_DPM_CTRL_3) & DPM_SCLK_ENABLE)
  603.                 return true;
  604.         else
  605.                 return false;
  606. }
  607.  
  608. static void sumo_start_dpm(struct radeon_device *rdev)
  609. {
  610.         WREG32_P(CG_SCLK_DPM_CTRL_3, DPM_SCLK_ENABLE, ~DPM_SCLK_ENABLE);
  611. }
  612.  
  613. static void sumo_stop_dpm(struct radeon_device *rdev)
  614. {
  615.         WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~DPM_SCLK_ENABLE);
  616. }
  617.  
  618. static void sumo_set_forced_mode(struct radeon_device *rdev, bool enable)
  619. {
  620.         if (enable)
  621.                 WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_SCLK_STATE_EN, ~FORCE_SCLK_STATE_EN);
  622.         else
  623.                 WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~FORCE_SCLK_STATE_EN);
  624. }
  625.  
  626. static void sumo_set_forced_mode_enabled(struct radeon_device *rdev)
  627. {
  628.         int i;
  629.  
  630.         sumo_set_forced_mode(rdev, true);
  631.         for (i = 0; i < rdev->usec_timeout; i++) {
  632.                 if (RREG32(CG_SCLK_STATUS) & SCLK_OVERCLK_DETECT)
  633.                         break;
  634.                 udelay(1);
  635.         }
  636. }
  637.  
  638. static void sumo_wait_for_level_0(struct radeon_device *rdev)
  639. {
  640.         int i;
  641.  
  642.         for (i = 0; i < rdev->usec_timeout; i++) {
  643.                 if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_SCLK_INDEX_MASK) == 0)
  644.                         break;
  645.                 udelay(1);
  646.         }
  647.         for (i = 0; i < rdev->usec_timeout; i++) {
  648.                 if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) == 0)
  649.                         break;
  650.                 udelay(1);
  651.         }
  652. }
  653.  
  654. static void sumo_set_forced_mode_disabled(struct radeon_device *rdev)
  655. {
  656.         sumo_set_forced_mode(rdev, false);
  657. }
  658.  
  659. static void sumo_enable_power_level_0(struct radeon_device *rdev)
  660. {
  661.         sumo_power_level_enable(rdev, 0, true);
  662. }
  663.  
  664. static void sumo_patch_boost_state(struct radeon_device *rdev,
  665.                                    struct radeon_ps *rps)
  666. {
  667.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  668.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  669.  
  670.         if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE) {
  671.                 pi->boost_pl = new_ps->levels[new_ps->num_levels - 1];
  672.                 pi->boost_pl.sclk = pi->sys_info.boost_sclk;
  673.                 pi->boost_pl.vddc_index = pi->sys_info.boost_vid_2bit;
  674.                 pi->boost_pl.sclk_dpm_tdp_limit = pi->sys_info.sclk_dpm_tdp_limit_boost;
  675.         }
  676. }
  677.  
  678. static void sumo_pre_notify_alt_vddnb_change(struct radeon_device *rdev,
  679.                                              struct radeon_ps *new_rps,
  680.                                              struct radeon_ps *old_rps)
  681. {
  682.         struct sumo_ps *new_ps = sumo_get_ps(new_rps);
  683.         struct sumo_ps *old_ps = sumo_get_ps(old_rps);
  684.         u32 nbps1_old = 0;
  685.         u32 nbps1_new = 0;
  686.  
  687.         if (old_ps != NULL)
  688.                 nbps1_old = (old_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE) ? 1 : 0;
  689.  
  690.         nbps1_new = (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE) ? 1 : 0;
  691.  
  692.         if (nbps1_old == 1 && nbps1_new == 0)
  693.                 sumo_smu_notify_alt_vddnb_change(rdev, 0, 0);
  694. }
  695.  
  696. static void sumo_post_notify_alt_vddnb_change(struct radeon_device *rdev,
  697.                                               struct radeon_ps *new_rps,
  698.                                               struct radeon_ps *old_rps)
  699. {
  700.         struct sumo_ps *new_ps = sumo_get_ps(new_rps);
  701.         struct sumo_ps *old_ps = sumo_get_ps(old_rps);
  702.         u32 nbps1_old = 0;
  703.         u32 nbps1_new = 0;
  704.  
  705.         if (old_ps != NULL)
  706.                 nbps1_old = (old_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)? 1 : 0;
  707.  
  708.         nbps1_new = (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)? 1 : 0;
  709.  
  710.         if (nbps1_old == 0 && nbps1_new == 1)
  711.                 sumo_smu_notify_alt_vddnb_change(rdev, 1, 1);
  712. }
  713.  
  714. static void sumo_enable_boost(struct radeon_device *rdev,
  715.                               struct radeon_ps *rps,
  716.                               bool enable)
  717. {
  718.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  719.  
  720.         if (enable) {
  721.                 if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
  722.                         sumo_boost_state_enable(rdev, true);
  723.         } else
  724.                 sumo_boost_state_enable(rdev, false);
  725. }
  726.  
  727. static void sumo_set_forced_level(struct radeon_device *rdev, u32 index)
  728. {
  729.         WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_SCLK_STATE(index), ~FORCE_SCLK_STATE_MASK);
  730. }
  731.  
  732. static void sumo_set_forced_level_0(struct radeon_device *rdev)
  733. {
  734.         sumo_set_forced_level(rdev, 0);
  735. }
  736.  
  737. static void sumo_program_wl(struct radeon_device *rdev,
  738.                             struct radeon_ps *rps)
  739. {
  740.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  741.         u32 dpm_ctrl4 = RREG32(CG_SCLK_DPM_CTRL_4);
  742.  
  743.         dpm_ctrl4 &= 0xFFFFFF00;
  744.         dpm_ctrl4 |= (1 << (new_ps->num_levels - 1));
  745.  
  746.         if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
  747.                 dpm_ctrl4 |= (1 << BOOST_DPM_LEVEL);
  748.  
  749.         WREG32(CG_SCLK_DPM_CTRL_4, dpm_ctrl4);
  750. }
  751.  
  752. static void sumo_program_power_levels_0_to_n(struct radeon_device *rdev,
  753.                                              struct radeon_ps *new_rps,
  754.                                              struct radeon_ps *old_rps)
  755. {
  756.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  757.         struct sumo_ps *new_ps = sumo_get_ps(new_rps);
  758.         struct sumo_ps *old_ps = sumo_get_ps(old_rps);
  759.         u32 i;
  760.         u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
  761.  
  762.         for (i = 0; i < new_ps->num_levels; i++) {
  763.                 sumo_program_power_level(rdev, &new_ps->levels[i], i);
  764.                 sumo_power_level_enable(rdev, i, true);
  765.         }
  766.  
  767.         for (i = new_ps->num_levels; i < n_current_state_levels; i++)
  768.                 sumo_power_level_enable(rdev, i, false);
  769.  
  770.         if (new_ps->flags & SUMO_POWERSTATE_FLAGS_BOOST_STATE)
  771.                 sumo_program_power_level(rdev, &pi->boost_pl, BOOST_DPM_LEVEL);
  772. }
  773.  
  774. static void sumo_enable_acpi_pm(struct radeon_device *rdev)
  775. {
  776.         WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
  777. }
  778.  
  779. static void sumo_program_power_level_enter_state(struct radeon_device *rdev)
  780. {
  781.         WREG32_P(CG_SCLK_DPM_CTRL_5, SCLK_FSTATE_BOOTUP(0), ~SCLK_FSTATE_BOOTUP_MASK);
  782. }
  783.  
  784. static void sumo_program_acpi_power_level(struct radeon_device *rdev)
  785. {
  786.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  787.         struct atom_clock_dividers dividers;
  788.         int ret;
  789.  
  790.         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  791.                                              pi->acpi_pl.sclk,
  792.                                              false, &dividers);
  793.         if (ret)
  794.                 return;
  795.  
  796.         WREG32_P(CG_ACPI_CNTL, SCLK_ACPI_DIV(dividers.post_div), ~SCLK_ACPI_DIV_MASK);
  797.         WREG32_P(CG_ACPI_VOLTAGE_CNTL, 0, ~ACPI_VOLTAGE_EN);
  798. }
  799.  
  800. static void sumo_program_bootup_state(struct radeon_device *rdev)
  801. {
  802.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  803.         u32 dpm_ctrl4 = RREG32(CG_SCLK_DPM_CTRL_4);
  804.         u32 i;
  805.  
  806.         sumo_program_power_level(rdev, &pi->boot_pl, 0);
  807.  
  808.         dpm_ctrl4 &= 0xFFFFFF00;
  809.         WREG32(CG_SCLK_DPM_CTRL_4, dpm_ctrl4);
  810.  
  811.         for (i = 1; i < 8; i++)
  812.                 sumo_power_level_enable(rdev, i, false);
  813. }
  814.  
  815. static void sumo_setup_uvd_clocks(struct radeon_device *rdev,
  816.                                   struct radeon_ps *new_rps,
  817.                                   struct radeon_ps *old_rps)
  818. {
  819.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  820.  
  821.         if (pi->enable_gfx_power_gating) {
  822.                 sumo_gfx_powergating_enable(rdev, false);
  823.         }
  824.  
  825.         radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
  826.  
  827.         if (pi->enable_gfx_power_gating) {
  828.                 if (!pi->disable_gfx_power_gating_in_uvd ||
  829.                     !r600_is_uvd_state(new_rps->class, new_rps->class2))
  830.                         sumo_gfx_powergating_enable(rdev, true);
  831.         }
  832. }
  833.  
  834. static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
  835.                                                     struct radeon_ps *new_rps,
  836.                                                     struct radeon_ps *old_rps)
  837. {
  838.         struct sumo_ps *new_ps = sumo_get_ps(new_rps);
  839.         struct sumo_ps *current_ps = sumo_get_ps(old_rps);
  840.  
  841.         if ((new_rps->vclk == old_rps->vclk) &&
  842.             (new_rps->dclk == old_rps->dclk))
  843.                 return;
  844.  
  845.         if (new_ps->levels[new_ps->num_levels - 1].sclk >=
  846.             current_ps->levels[current_ps->num_levels - 1].sclk)
  847.                 return;
  848.  
  849.         sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
  850. }
  851.  
  852. static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
  853.                                                    struct radeon_ps *new_rps,
  854.                                                    struct radeon_ps *old_rps)
  855. {
  856.         struct sumo_ps *new_ps = sumo_get_ps(new_rps);
  857.         struct sumo_ps *current_ps = sumo_get_ps(old_rps);
  858.  
  859.         if ((new_rps->vclk == old_rps->vclk) &&
  860.             (new_rps->dclk == old_rps->dclk))
  861.                 return;
  862.  
  863.         if (new_ps->levels[new_ps->num_levels - 1].sclk <
  864.             current_ps->levels[current_ps->num_levels - 1].sclk)
  865.                 return;
  866.  
  867.         sumo_setup_uvd_clocks(rdev, new_rps, old_rps);
  868. }
  869.  
  870. void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
  871. {
  872. /* This bit selects who handles display phy powergating.
  873.  * Clear the bit to let atom handle it.
  874.  * Set it to let the driver handle it.
  875.  * For now we just let atom handle it.
  876.  */
  877. #if 0
  878.         u32 v = RREG32(DOUT_SCRATCH3);
  879.  
  880.         if (enable)
  881.                 v |= 0x4;
  882.         else
  883.                 v &= 0xFFFFFFFB;
  884.  
  885.         WREG32(DOUT_SCRATCH3, v);
  886. #endif
  887. }
  888.  
  889. static void sumo_enable_sclk_ds(struct radeon_device *rdev, bool enable)
  890. {
  891.         if (enable) {
  892.                 u32 deep_sleep_cntl = RREG32(DEEP_SLEEP_CNTL);
  893.                 u32 deep_sleep_cntl2 = RREG32(DEEP_SLEEP_CNTL2);
  894.                 u32 t = 1;
  895.  
  896.                 deep_sleep_cntl &= ~R_DIS;
  897.                 deep_sleep_cntl &= ~HS_MASK;
  898.                 deep_sleep_cntl |= HS(t > 4095 ? 4095 : t);
  899.  
  900.                 deep_sleep_cntl2 |= LB_UFP_EN;
  901.                 deep_sleep_cntl2 &= INOUT_C_MASK;
  902.                 deep_sleep_cntl2 |= INOUT_C(0xf);
  903.  
  904.                 WREG32(DEEP_SLEEP_CNTL2, deep_sleep_cntl2);
  905.                 WREG32(DEEP_SLEEP_CNTL, deep_sleep_cntl);
  906.         } else
  907.                 WREG32_P(DEEP_SLEEP_CNTL, 0, ~ENABLE_DS);
  908. }
  909.  
  910. static void sumo_program_bootup_at(struct radeon_device *rdev)
  911. {
  912.         WREG32_P(CG_AT_0, CG_R(0xffff), ~CG_R_MASK);
  913.         WREG32_P(CG_AT_0, CG_L(0), ~CG_L_MASK);
  914. }
  915.  
  916. static void sumo_reset_am(struct radeon_device *rdev)
  917. {
  918.         WREG32_P(SCLK_PWRMGT_CNTL, FIR_RESET, ~FIR_RESET);
  919. }
  920.  
  921. static void sumo_start_am(struct radeon_device *rdev)
  922. {
  923.         WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_RESET);
  924. }
  925.  
  926. static void sumo_program_ttp(struct radeon_device *rdev)
  927. {
  928.         u32 xclk = radeon_get_xclk(rdev);
  929.         u32 p, u;
  930.         u32 cg_sclk_dpm_ctrl_5 = RREG32(CG_SCLK_DPM_CTRL_5);
  931.  
  932.         r600_calculate_u_and_p(1000,
  933.                                xclk, 16, &p, &u);
  934.  
  935.         cg_sclk_dpm_ctrl_5 &= ~(TT_TP_MASK | TT_TU_MASK);
  936.         cg_sclk_dpm_ctrl_5 |= TT_TP(p) | TT_TU(u);
  937.  
  938.         WREG32(CG_SCLK_DPM_CTRL_5, cg_sclk_dpm_ctrl_5);
  939. }
  940.  
  941. static void sumo_program_ttt(struct radeon_device *rdev)
  942. {
  943.         u32 cg_sclk_dpm_ctrl_3 = RREG32(CG_SCLK_DPM_CTRL_3);
  944.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  945.  
  946.         cg_sclk_dpm_ctrl_3 &= ~(GNB_TT_MASK | GNB_THERMTHRO_MASK);
  947.         cg_sclk_dpm_ctrl_3 |= GNB_TT(pi->thermal_auto_throttling + 49);
  948.  
  949.         WREG32(CG_SCLK_DPM_CTRL_3, cg_sclk_dpm_ctrl_3);
  950. }
  951.  
  952.  
  953. static void sumo_enable_voltage_scaling(struct radeon_device *rdev, bool enable)
  954. {
  955.         if (enable) {
  956.                 WREG32_P(CG_DPM_VOLTAGE_CNTL, DPM_VOLTAGE_EN, ~DPM_VOLTAGE_EN);
  957.                 WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~CG_VOLTAGE_EN);
  958.         } else {
  959.                 WREG32_P(CG_CG_VOLTAGE_CNTL, CG_VOLTAGE_EN, ~CG_VOLTAGE_EN);
  960.                 WREG32_P(CG_DPM_VOLTAGE_CNTL, 0, ~DPM_VOLTAGE_EN);
  961.         }
  962. }
  963.  
  964. static void sumo_override_cnb_thermal_events(struct radeon_device *rdev)
  965. {
  966.         WREG32_P(CG_SCLK_DPM_CTRL_3, CNB_THERMTHRO_MASK_SCLK,
  967.                  ~CNB_THERMTHRO_MASK_SCLK);
  968. }
  969.  
  970. static void sumo_program_dc_hto(struct radeon_device *rdev)
  971. {
  972.         u32 cg_sclk_dpm_ctrl_4 = RREG32(CG_SCLK_DPM_CTRL_4);
  973.         u32 p, u;
  974.         u32 xclk = radeon_get_xclk(rdev);
  975.  
  976.         r600_calculate_u_and_p(100000,
  977.                                xclk, 14, &p, &u);
  978.  
  979.         cg_sclk_dpm_ctrl_4 &= ~(DC_HDC_MASK | DC_HU_MASK);
  980.         cg_sclk_dpm_ctrl_4 |= DC_HDC(p) | DC_HU(u);
  981.  
  982.         WREG32(CG_SCLK_DPM_CTRL_4, cg_sclk_dpm_ctrl_4);
  983. }
  984.  
  985. static void sumo_force_nbp_state(struct radeon_device *rdev,
  986.                                  struct radeon_ps *rps)
  987. {
  988.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  989.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  990.  
  991.         if (!pi->driver_nbps_policy_disable) {
  992.                 if (new_ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)
  993.                         WREG32_P(CG_SCLK_DPM_CTRL_3, FORCE_NB_PSTATE_1, ~FORCE_NB_PSTATE_1);
  994.                 else
  995.                         WREG32_P(CG_SCLK_DPM_CTRL_3, 0, ~FORCE_NB_PSTATE_1);
  996.         }
  997. }
  998.  
  999. u32 sumo_get_sleep_divider_from_id(u32 id)
  1000. {
  1001.         return 1 << id;
  1002. }
  1003.  
  1004. u32 sumo_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
  1005.                                          u32 sclk,
  1006.                                          u32 min_sclk_in_sr)
  1007. {
  1008.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1009.         u32 i;
  1010.         u32 temp;
  1011.         u32 min = (min_sclk_in_sr > SUMO_MINIMUM_ENGINE_CLOCK) ?
  1012.                 min_sclk_in_sr : SUMO_MINIMUM_ENGINE_CLOCK;
  1013.  
  1014.         if (sclk < min)
  1015.                 return 0;
  1016.  
  1017.         if (!pi->enable_sclk_ds)
  1018.                 return 0;
  1019.  
  1020.         for (i = SUMO_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
  1021.                 temp = sclk / sumo_get_sleep_divider_from_id(i);
  1022.  
  1023.                 if (temp >= min || i == 0)
  1024.                         break;
  1025.         }
  1026.         return i;
  1027. }
  1028.  
  1029. static u32 sumo_get_valid_engine_clock(struct radeon_device *rdev,
  1030.                                        u32 lower_limit)
  1031. {
  1032.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1033.         u32 i;
  1034.  
  1035.         for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
  1036.                 if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
  1037.                         return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
  1038.         }
  1039.  
  1040.         return pi->sys_info.sclk_voltage_mapping_table.entries[pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries - 1].sclk_frequency;
  1041. }
  1042.  
  1043. static void sumo_patch_thermal_state(struct radeon_device *rdev,
  1044.                                      struct sumo_ps *ps,
  1045.                                      struct sumo_ps *current_ps)
  1046. {
  1047.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1048.         u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
  1049.         u32 current_vddc;
  1050.         u32 current_sclk;
  1051.         u32 current_index = 0;
  1052.  
  1053.         if (current_ps) {
  1054.                 current_vddc = current_ps->levels[current_index].vddc_index;
  1055.                 current_sclk = current_ps->levels[current_index].sclk;
  1056.         } else {
  1057.                 current_vddc = pi->boot_pl.vddc_index;
  1058.                 current_sclk = pi->boot_pl.sclk;
  1059.         }
  1060.  
  1061.         ps->levels[0].vddc_index = current_vddc;
  1062.  
  1063.         if (ps->levels[0].sclk > current_sclk)
  1064.                 ps->levels[0].sclk = current_sclk;
  1065.  
  1066.         ps->levels[0].ss_divider_index =
  1067.                 sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
  1068.  
  1069.         ps->levels[0].ds_divider_index =
  1070.                 sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, SUMO_MINIMUM_ENGINE_CLOCK);
  1071.  
  1072.         if (ps->levels[0].ds_divider_index > ps->levels[0].ss_divider_index + 1)
  1073.                 ps->levels[0].ds_divider_index = ps->levels[0].ss_divider_index + 1;
  1074.  
  1075.         if (ps->levels[0].ss_divider_index == ps->levels[0].ds_divider_index) {
  1076.                 if (ps->levels[0].ss_divider_index > 1)
  1077.                         ps->levels[0].ss_divider_index = ps->levels[0].ss_divider_index - 1;
  1078.         }
  1079.  
  1080.         if (ps->levels[0].ss_divider_index == 0)
  1081.                 ps->levels[0].ds_divider_index = 0;
  1082.  
  1083.         if (ps->levels[0].ds_divider_index == 0)
  1084.                 ps->levels[0].ss_divider_index = 0;
  1085. }
  1086.  
  1087. static void sumo_apply_state_adjust_rules(struct radeon_device *rdev,
  1088.                                           struct radeon_ps *new_rps,
  1089.                                           struct radeon_ps *old_rps)
  1090. {
  1091.         struct sumo_ps *ps = sumo_get_ps(new_rps);
  1092.         struct sumo_ps *current_ps = sumo_get_ps(old_rps);
  1093.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1094.         u32 min_voltage = 0; /* ??? */
  1095.         u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
  1096.         u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
  1097.         u32 i;
  1098.  
  1099.         if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
  1100.                 return sumo_patch_thermal_state(rdev, ps, current_ps);
  1101.  
  1102.         if (pi->enable_boost) {
  1103.                 if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE)
  1104.                         ps->flags |= SUMO_POWERSTATE_FLAGS_BOOST_STATE;
  1105.         }
  1106.  
  1107.         if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) ||
  1108.             (new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) ||
  1109.             (new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE))
  1110.                 ps->flags |= SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE;
  1111.  
  1112.         for (i = 0; i < ps->num_levels; i++) {
  1113.                 if (ps->levels[i].vddc_index < min_voltage)
  1114.                         ps->levels[i].vddc_index = min_voltage;
  1115.  
  1116.                 if (ps->levels[i].sclk < min_sclk)
  1117.                         ps->levels[i].sclk =
  1118.                                 sumo_get_valid_engine_clock(rdev, min_sclk);
  1119.  
  1120.                 ps->levels[i].ss_divider_index =
  1121.                         sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
  1122.  
  1123.                 ps->levels[i].ds_divider_index =
  1124.                         sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, SUMO_MINIMUM_ENGINE_CLOCK);
  1125.  
  1126.                 if (ps->levels[i].ds_divider_index > ps->levels[i].ss_divider_index + 1)
  1127.                         ps->levels[i].ds_divider_index = ps->levels[i].ss_divider_index + 1;
  1128.  
  1129.                 if (ps->levels[i].ss_divider_index == ps->levels[i].ds_divider_index) {
  1130.                         if (ps->levels[i].ss_divider_index > 1)
  1131.                                 ps->levels[i].ss_divider_index = ps->levels[i].ss_divider_index - 1;
  1132.                 }
  1133.  
  1134.                 if (ps->levels[i].ss_divider_index == 0)
  1135.                         ps->levels[i].ds_divider_index = 0;
  1136.  
  1137.                 if (ps->levels[i].ds_divider_index == 0)
  1138.                         ps->levels[i].ss_divider_index = 0;
  1139.  
  1140.                 if (ps->flags & SUMO_POWERSTATE_FLAGS_FORCE_NBPS1_STATE)
  1141.                         ps->levels[i].allow_gnb_slow = 1;
  1142.                 else if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE) ||
  1143.                          (new_rps->class2 & ATOM_PPLIB_CLASSIFICATION2_MVC))
  1144.                         ps->levels[i].allow_gnb_slow = 0;
  1145.                 else if (i == ps->num_levels - 1)
  1146.                         ps->levels[i].allow_gnb_slow = 0;
  1147.                 else
  1148.                         ps->levels[i].allow_gnb_slow = 1;
  1149.         }
  1150. }
  1151.  
  1152. static void sumo_cleanup_asic(struct radeon_device *rdev)
  1153. {
  1154.         sumo_take_smu_control(rdev, false);
  1155. }
  1156.  
  1157. static int sumo_set_thermal_temperature_range(struct radeon_device *rdev,
  1158.                                               int min_temp, int max_temp)
  1159. {
  1160.         int low_temp = 0 * 1000;
  1161.         int high_temp = 255 * 1000;
  1162.  
  1163.         if (low_temp < min_temp)
  1164.                 low_temp = min_temp;
  1165.         if (high_temp > max_temp)
  1166.                 high_temp = max_temp;
  1167.         if (high_temp < low_temp) {
  1168.                 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
  1169.                 return -EINVAL;
  1170.         }
  1171.  
  1172.         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
  1173.         WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
  1174.  
  1175.         rdev->pm.dpm.thermal.min_temp = low_temp;
  1176.         rdev->pm.dpm.thermal.max_temp = high_temp;
  1177.  
  1178.         return 0;
  1179. }
  1180.  
  1181. static void sumo_update_current_ps(struct radeon_device *rdev,
  1182.                                    struct radeon_ps *rps)
  1183. {
  1184.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  1185.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1186.  
  1187.         pi->current_rps = *rps;
  1188.         pi->current_ps = *new_ps;
  1189.         pi->current_rps.ps_priv = &pi->current_ps;
  1190. }
  1191.  
  1192. static void sumo_update_requested_ps(struct radeon_device *rdev,
  1193.                                      struct radeon_ps *rps)
  1194. {
  1195.         struct sumo_ps *new_ps = sumo_get_ps(rps);
  1196.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1197.  
  1198.         pi->requested_rps = *rps;
  1199.         pi->requested_ps = *new_ps;
  1200.         pi->requested_rps.ps_priv = &pi->requested_ps;
  1201. }
  1202.  
  1203. int sumo_dpm_enable(struct radeon_device *rdev)
  1204. {
  1205.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1206.  
  1207.         if (sumo_dpm_enabled(rdev))
  1208.                 return -EINVAL;
  1209.  
  1210.         sumo_program_bootup_state(rdev);
  1211.         sumo_init_bsp(rdev);
  1212.         sumo_reset_am(rdev);
  1213.         sumo_program_tp(rdev);
  1214.         sumo_program_bootup_at(rdev);
  1215.         sumo_start_am(rdev);
  1216.         if (pi->enable_auto_thermal_throttling) {
  1217.                 sumo_program_ttp(rdev);
  1218.                 sumo_program_ttt(rdev);
  1219.         }
  1220.         sumo_program_dc_hto(rdev);
  1221.         sumo_program_power_level_enter_state(rdev);
  1222.         sumo_enable_voltage_scaling(rdev, true);
  1223.         sumo_program_sstp(rdev);
  1224.         sumo_program_vc(rdev, SUMO_VRC_DFLT);
  1225.         sumo_override_cnb_thermal_events(rdev);
  1226.         sumo_start_dpm(rdev);
  1227.         sumo_wait_for_level_0(rdev);
  1228.         if (pi->enable_sclk_ds)
  1229.                 sumo_enable_sclk_ds(rdev, true);
  1230.         if (pi->enable_boost)
  1231.                 sumo_enable_boost_timer(rdev);
  1232.  
  1233.         sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
  1234.  
  1235.         return 0;
  1236. }
  1237.  
  1238. int sumo_dpm_late_enable(struct radeon_device *rdev)
  1239. {
  1240.         int ret;
  1241.  
  1242.         ret = sumo_enable_clock_power_gating(rdev);
  1243.         if (ret)
  1244.                 return ret;
  1245.  
  1246.         if (rdev->irq.installed &&
  1247.             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
  1248.                 ret = sumo_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
  1249.                 if (ret)
  1250.                         return ret;
  1251.                 rdev->irq.dpm_thermal = true;
  1252.                 radeon_irq_set(rdev);
  1253.         }
  1254.  
  1255.         return 0;
  1256. }
  1257.  
  1258. void sumo_dpm_disable(struct radeon_device *rdev)
  1259. {
  1260.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1261.  
  1262.         if (!sumo_dpm_enabled(rdev))
  1263.                 return;
  1264.         sumo_disable_clock_power_gating(rdev);
  1265.         if (pi->enable_sclk_ds)
  1266.                 sumo_enable_sclk_ds(rdev, false);
  1267.         sumo_clear_vc(rdev);
  1268.         sumo_wait_for_level_0(rdev);
  1269.         sumo_stop_dpm(rdev);
  1270.         sumo_enable_voltage_scaling(rdev, false);
  1271.  
  1272.         if (rdev->irq.installed &&
  1273.             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
  1274.                 rdev->irq.dpm_thermal = false;
  1275.                 radeon_irq_set(rdev);
  1276.         }
  1277.  
  1278.         sumo_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
  1279. }
  1280.  
  1281. int sumo_dpm_pre_set_power_state(struct radeon_device *rdev)
  1282. {
  1283.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1284.         struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
  1285.         struct radeon_ps *new_ps = &requested_ps;
  1286.  
  1287.         sumo_update_requested_ps(rdev, new_ps);
  1288.  
  1289.         if (pi->enable_dynamic_patch_ps)
  1290.                 sumo_apply_state_adjust_rules(rdev,
  1291.                                               &pi->requested_rps,
  1292.                                               &pi->current_rps);
  1293.  
  1294.         return 0;
  1295. }
  1296.  
  1297. int sumo_dpm_set_power_state(struct radeon_device *rdev)
  1298. {
  1299.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1300.         struct radeon_ps *new_ps = &pi->requested_rps;
  1301.         struct radeon_ps *old_ps = &pi->current_rps;
  1302.  
  1303.         if (pi->enable_dpm)
  1304.                 sumo_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
  1305.         if (pi->enable_boost) {
  1306.                 sumo_enable_boost(rdev, new_ps, false);
  1307.                 sumo_patch_boost_state(rdev, new_ps);
  1308.         }
  1309.         if (pi->enable_dpm) {
  1310.                 sumo_pre_notify_alt_vddnb_change(rdev, new_ps, old_ps);
  1311.                 sumo_enable_power_level_0(rdev);
  1312.                 sumo_set_forced_level_0(rdev);
  1313.                 sumo_set_forced_mode_enabled(rdev);
  1314.                 sumo_wait_for_level_0(rdev);
  1315.                 sumo_program_power_levels_0_to_n(rdev, new_ps, old_ps);
  1316.                 sumo_program_wl(rdev, new_ps);
  1317.                 sumo_program_bsp(rdev, new_ps);
  1318.                 sumo_program_at(rdev, new_ps);
  1319.                 sumo_force_nbp_state(rdev, new_ps);
  1320.                 sumo_set_forced_mode_disabled(rdev);
  1321.                 sumo_set_forced_mode_enabled(rdev);
  1322.                 sumo_set_forced_mode_disabled(rdev);
  1323.                 sumo_post_notify_alt_vddnb_change(rdev, new_ps, old_ps);
  1324.         }
  1325.         if (pi->enable_boost)
  1326.                 sumo_enable_boost(rdev, new_ps, true);
  1327.         if (pi->enable_dpm)
  1328.                 sumo_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
  1329.  
  1330.         return 0;
  1331. }
  1332.  
  1333. void sumo_dpm_post_set_power_state(struct radeon_device *rdev)
  1334. {
  1335.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1336.         struct radeon_ps *new_ps = &pi->requested_rps;
  1337.  
  1338.         sumo_update_current_ps(rdev, new_ps);
  1339. }
  1340.  
  1341. #if 0
  1342. void sumo_dpm_reset_asic(struct radeon_device *rdev)
  1343. {
  1344.         sumo_program_bootup_state(rdev);
  1345.         sumo_enable_power_level_0(rdev);
  1346.         sumo_set_forced_level_0(rdev);
  1347.         sumo_set_forced_mode_enabled(rdev);
  1348.         sumo_wait_for_level_0(rdev);
  1349.         sumo_set_forced_mode_disabled(rdev);
  1350.         sumo_set_forced_mode_enabled(rdev);
  1351.         sumo_set_forced_mode_disabled(rdev);
  1352. }
  1353. #endif
  1354.  
  1355. void sumo_dpm_setup_asic(struct radeon_device *rdev)
  1356. {
  1357.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1358.  
  1359.         sumo_initialize_m3_arb(rdev);
  1360.         pi->fw_version = sumo_get_running_fw_version(rdev);
  1361.         DRM_INFO("Found smc ucode version: 0x%08x\n", pi->fw_version);
  1362.         sumo_program_acpi_power_level(rdev);
  1363.         sumo_enable_acpi_pm(rdev);
  1364.         sumo_take_smu_control(rdev, true);
  1365. }
  1366.  
  1367. void sumo_dpm_display_configuration_changed(struct radeon_device *rdev)
  1368. {
  1369.  
  1370. }
  1371.  
  1372. union power_info {
  1373.         struct _ATOM_POWERPLAY_INFO info;
  1374.         struct _ATOM_POWERPLAY_INFO_V2 info_2;
  1375.         struct _ATOM_POWERPLAY_INFO_V3 info_3;
  1376.         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
  1377.         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
  1378.         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
  1379. };
  1380.  
  1381. union pplib_clock_info {
  1382.         struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
  1383.         struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
  1384.         struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
  1385.         struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
  1386. };
  1387.  
  1388. union pplib_power_state {
  1389.         struct _ATOM_PPLIB_STATE v1;
  1390.         struct _ATOM_PPLIB_STATE_V2 v2;
  1391. };
  1392.  
  1393. static void sumo_patch_boot_state(struct radeon_device *rdev,
  1394.                                   struct sumo_ps *ps)
  1395. {
  1396.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1397.  
  1398.         ps->num_levels = 1;
  1399.         ps->flags = 0;
  1400.         ps->levels[0] = pi->boot_pl;
  1401. }
  1402.  
  1403. static void sumo_parse_pplib_non_clock_info(struct radeon_device *rdev,
  1404.                                             struct radeon_ps *rps,
  1405.                                             struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
  1406.                                             u8 table_rev)
  1407. {
  1408.         struct sumo_ps *ps = sumo_get_ps(rps);
  1409.  
  1410.         rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
  1411.         rps->class = le16_to_cpu(non_clock_info->usClassification);
  1412.         rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
  1413.  
  1414.         if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
  1415.                 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
  1416.                 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
  1417.         } else {
  1418.                 rps->vclk = 0;
  1419.                 rps->dclk = 0;
  1420.         }
  1421.  
  1422.         if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
  1423.                 rdev->pm.dpm.boot_ps = rps;
  1424.                 sumo_patch_boot_state(rdev, ps);
  1425.         }
  1426.         if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
  1427.                 rdev->pm.dpm.uvd_ps = rps;
  1428. }
  1429.  
  1430. static void sumo_parse_pplib_clock_info(struct radeon_device *rdev,
  1431.                                         struct radeon_ps *rps, int index,
  1432.                                         union pplib_clock_info *clock_info)
  1433. {
  1434.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1435.         struct sumo_ps *ps = sumo_get_ps(rps);
  1436.         struct sumo_pl *pl = &ps->levels[index];
  1437.         u32 sclk;
  1438.  
  1439.         sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
  1440.         sclk |= clock_info->sumo.ucEngineClockHigh << 16;
  1441.         pl->sclk = sclk;
  1442.         pl->vddc_index = clock_info->sumo.vddcIndex;
  1443.         pl->sclk_dpm_tdp_limit = clock_info->sumo.tdpLimit;
  1444.  
  1445.         ps->num_levels = index + 1;
  1446.  
  1447.         if (pi->enable_sclk_ds) {
  1448.                 pl->ds_divider_index = 5;
  1449.                 pl->ss_divider_index = 4;
  1450.         }
  1451. }
  1452.  
  1453. static int sumo_parse_power_table(struct radeon_device *rdev)
  1454. {
  1455.         struct radeon_mode_info *mode_info = &rdev->mode_info;
  1456.         struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
  1457.         union pplib_power_state *power_state;
  1458.         int i, j, k, non_clock_array_index, clock_array_index;
  1459.         union pplib_clock_info *clock_info;
  1460.         struct _StateArray *state_array;
  1461.         struct _ClockInfoArray *clock_info_array;
  1462.         struct _NonClockInfoArray *non_clock_info_array;
  1463.         union power_info *power_info;
  1464.         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
  1465.         u16 data_offset;
  1466.         u8 frev, crev;
  1467.         u8 *power_state_offset;
  1468.         struct sumo_ps *ps;
  1469.  
  1470.         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
  1471.                                    &frev, &crev, &data_offset))
  1472.                 return -EINVAL;
  1473.         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
  1474.  
  1475.         state_array = (struct _StateArray *)
  1476.                 (mode_info->atom_context->bios + data_offset +
  1477.                  le16_to_cpu(power_info->pplib.usStateArrayOffset));
  1478.         clock_info_array = (struct _ClockInfoArray *)
  1479.                 (mode_info->atom_context->bios + data_offset +
  1480.                  le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
  1481.         non_clock_info_array = (struct _NonClockInfoArray *)
  1482.                 (mode_info->atom_context->bios + data_offset +
  1483.                  le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
  1484.  
  1485.         rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
  1486.                                   state_array->ucNumEntries, GFP_KERNEL);
  1487.         if (!rdev->pm.dpm.ps)
  1488.                 return -ENOMEM;
  1489.         power_state_offset = (u8 *)state_array->states;
  1490.         for (i = 0; i < state_array->ucNumEntries; i++) {
  1491.                 u8 *idx;
  1492.                 power_state = (union pplib_power_state *)power_state_offset;
  1493.                 non_clock_array_index = power_state->v2.nonClockInfoIndex;
  1494.                 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
  1495.                         &non_clock_info_array->nonClockInfo[non_clock_array_index];
  1496.                 if (!rdev->pm.power_state[i].clock_info)
  1497.                         return -EINVAL;
  1498.                 ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
  1499.                 if (ps == NULL) {
  1500.                         kfree(rdev->pm.dpm.ps);
  1501.                         return -ENOMEM;
  1502.                 }
  1503.                 rdev->pm.dpm.ps[i].ps_priv = ps;
  1504.                 k = 0;
  1505.                 idx = (u8 *)&power_state->v2.clockInfoIndex[0];
  1506.                 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
  1507.                         clock_array_index = idx[j];
  1508.                         if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
  1509.                                 break;
  1510.  
  1511.                         clock_info = (union pplib_clock_info *)
  1512.                                 ((u8 *)&clock_info_array->clockInfo[0] +
  1513.                                  (clock_array_index * clock_info_array->ucEntrySize));
  1514.                         sumo_parse_pplib_clock_info(rdev,
  1515.                                                     &rdev->pm.dpm.ps[i], k,
  1516.                                                     clock_info);
  1517.                         k++;
  1518.                 }
  1519.                 sumo_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
  1520.                                                 non_clock_info,
  1521.                                                 non_clock_info_array->ucEntrySize);
  1522.                 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
  1523.         }
  1524.         rdev->pm.dpm.num_ps = state_array->ucNumEntries;
  1525.         return 0;
  1526. }
  1527.  
  1528. u32 sumo_convert_vid2_to_vid7(struct radeon_device *rdev,
  1529.                               struct sumo_vid_mapping_table *vid_mapping_table,
  1530.                               u32 vid_2bit)
  1531. {
  1532.         u32 i;
  1533.  
  1534.         for (i = 0; i < vid_mapping_table->num_entries; i++) {
  1535.                 if (vid_mapping_table->entries[i].vid_2bit == vid_2bit)
  1536.                         return vid_mapping_table->entries[i].vid_7bit;
  1537.         }
  1538.  
  1539.         return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
  1540. }
  1541.  
  1542. #if 0
  1543. u32 sumo_convert_vid7_to_vid2(struct radeon_device *rdev,
  1544.                               struct sumo_vid_mapping_table *vid_mapping_table,
  1545.                               u32 vid_7bit)
  1546. {
  1547.         u32 i;
  1548.  
  1549.         for (i = 0; i < vid_mapping_table->num_entries; i++) {
  1550.                 if (vid_mapping_table->entries[i].vid_7bit == vid_7bit)
  1551.                         return vid_mapping_table->entries[i].vid_2bit;
  1552.         }
  1553.  
  1554.         return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit;
  1555. }
  1556. #endif
  1557.  
  1558. static u16 sumo_convert_voltage_index_to_value(struct radeon_device *rdev,
  1559.                                                u32 vid_2bit)
  1560. {
  1561.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1562.         u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
  1563.  
  1564.         if (vid_7bit > 0x7C)
  1565.                 return 0;
  1566.  
  1567.         return (15500 - vid_7bit * 125 + 5) / 10;
  1568. }
  1569.  
  1570. static void sumo_construct_display_voltage_mapping_table(struct radeon_device *rdev,
  1571.                                                          struct sumo_disp_clock_voltage_mapping_table *disp_clk_voltage_mapping_table,
  1572.                                                          ATOM_CLK_VOLT_CAPABILITY *table)
  1573. {
  1574.         u32 i;
  1575.  
  1576.         for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
  1577.                 if (table[i].ulMaximumSupportedCLK == 0)
  1578.                         break;
  1579.  
  1580.                 disp_clk_voltage_mapping_table->display_clock_frequency[i] =
  1581.                         table[i].ulMaximumSupportedCLK;
  1582.         }
  1583.  
  1584.         disp_clk_voltage_mapping_table->num_max_voltage_levels = i;
  1585.  
  1586.         if (disp_clk_voltage_mapping_table->num_max_voltage_levels == 0) {
  1587.                 disp_clk_voltage_mapping_table->display_clock_frequency[0] = 80000;
  1588.                 disp_clk_voltage_mapping_table->num_max_voltage_levels = 1;
  1589.         }
  1590. }
  1591.  
  1592. void sumo_construct_sclk_voltage_mapping_table(struct radeon_device *rdev,
  1593.                                                struct sumo_sclk_voltage_mapping_table *sclk_voltage_mapping_table,
  1594.                                                ATOM_AVAILABLE_SCLK_LIST *table)
  1595. {
  1596.         u32 i;
  1597.         u32 n = 0;
  1598.         u32 prev_sclk = 0;
  1599.  
  1600.         for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
  1601.                 if (table[i].ulSupportedSCLK > prev_sclk) {
  1602.                         sclk_voltage_mapping_table->entries[n].sclk_frequency =
  1603.                                 table[i].ulSupportedSCLK;
  1604.                         sclk_voltage_mapping_table->entries[n].vid_2bit =
  1605.                                 table[i].usVoltageIndex;
  1606.                         prev_sclk = table[i].ulSupportedSCLK;
  1607.                         n++;
  1608.                 }
  1609.         }
  1610.  
  1611.         sclk_voltage_mapping_table->num_max_dpm_entries = n;
  1612. }
  1613.  
  1614. void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
  1615.                                       struct sumo_vid_mapping_table *vid_mapping_table,
  1616.                                       ATOM_AVAILABLE_SCLK_LIST *table)
  1617. {
  1618.         u32 i, j;
  1619.  
  1620.         for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
  1621.                 if (table[i].ulSupportedSCLK != 0) {
  1622.                         vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
  1623.                                 table[i].usVoltageID;
  1624.                         vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
  1625.                                 table[i].usVoltageIndex;
  1626.                 }
  1627.         }
  1628.  
  1629.         for (i = 0; i < SUMO_MAX_NUMBER_VOLTAGES; i++) {
  1630.                 if (vid_mapping_table->entries[i].vid_7bit == 0) {
  1631.                         for (j = i + 1; j < SUMO_MAX_NUMBER_VOLTAGES; j++) {
  1632.                                 if (vid_mapping_table->entries[j].vid_7bit != 0) {
  1633.                                         vid_mapping_table->entries[i] =
  1634.                                                 vid_mapping_table->entries[j];
  1635.                                         vid_mapping_table->entries[j].vid_7bit = 0;
  1636.                                         break;
  1637.                                 }
  1638.                         }
  1639.  
  1640.                         if (j == SUMO_MAX_NUMBER_VOLTAGES)
  1641.                                 break;
  1642.                 }
  1643.         }
  1644.  
  1645.         vid_mapping_table->num_entries = i;
  1646. }
  1647.  
  1648. union igp_info {
  1649.         struct _ATOM_INTEGRATED_SYSTEM_INFO info;
  1650.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
  1651.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
  1652.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
  1653. };
  1654.  
  1655. static int sumo_parse_sys_info_table(struct radeon_device *rdev)
  1656. {
  1657.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1658.         struct radeon_mode_info *mode_info = &rdev->mode_info;
  1659.         int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
  1660.         union igp_info *igp_info;
  1661.         u8 frev, crev;
  1662.         u16 data_offset;
  1663.         int i;
  1664.  
  1665.         if (atom_parse_data_header(mode_info->atom_context, index, NULL,
  1666.                                    &frev, &crev, &data_offset)) {
  1667.                 igp_info = (union igp_info *)(mode_info->atom_context->bios +
  1668.                                               data_offset);
  1669.  
  1670.                 if (crev != 6) {
  1671.                         DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
  1672.                         return -EINVAL;
  1673.                 }
  1674.                 pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_6.ulBootUpEngineClock);
  1675.                 pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_6.ulMinEngineClock);
  1676.                 pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_6.ulBootUpUMAClock);
  1677.                 pi->sys_info.bootup_nb_voltage_index =
  1678.                         le16_to_cpu(igp_info->info_6.usBootUpNBVoltage);
  1679.                 if (igp_info->info_6.ucHtcTmpLmt == 0)
  1680.                         pi->sys_info.htc_tmp_lmt = 203;
  1681.                 else
  1682.                         pi->sys_info.htc_tmp_lmt = igp_info->info_6.ucHtcTmpLmt;
  1683.                 if (igp_info->info_6.ucHtcHystLmt == 0)
  1684.                         pi->sys_info.htc_hyst_lmt = 5;
  1685.                 else
  1686.                         pi->sys_info.htc_hyst_lmt = igp_info->info_6.ucHtcHystLmt;
  1687.                 if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
  1688.                         DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
  1689.                 }
  1690.                 for (i = 0; i < NUMBER_OF_M3ARB_PARAM_SETS; i++) {
  1691.                         pi->sys_info.csr_m3_arb_cntl_default[i] =
  1692.                                 le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_DEFAULT[i]);
  1693.                         pi->sys_info.csr_m3_arb_cntl_uvd[i] =
  1694.                                 le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_UVD[i]);
  1695.                         pi->sys_info.csr_m3_arb_cntl_fs3d[i] =
  1696.                                 le32_to_cpu(igp_info->info_6.ulCSR_M3_ARB_CNTL_FS3D[i]);
  1697.                 }
  1698.                 pi->sys_info.sclk_dpm_boost_margin =
  1699.                         le32_to_cpu(igp_info->info_6.SclkDpmBoostMargin);
  1700.                 pi->sys_info.sclk_dpm_throttle_margin =
  1701.                         le32_to_cpu(igp_info->info_6.SclkDpmThrottleMargin);
  1702.                 pi->sys_info.sclk_dpm_tdp_limit_pg =
  1703.                         le16_to_cpu(igp_info->info_6.SclkDpmTdpLimitPG);
  1704.                 pi->sys_info.gnb_tdp_limit = le16_to_cpu(igp_info->info_6.GnbTdpLimit);
  1705.                 pi->sys_info.sclk_dpm_tdp_limit_boost =
  1706.                         le16_to_cpu(igp_info->info_6.SclkDpmTdpLimitBoost);
  1707.                 pi->sys_info.boost_sclk = le32_to_cpu(igp_info->info_6.ulBoostEngineCLock);
  1708.                 pi->sys_info.boost_vid_2bit = igp_info->info_6.ulBoostVid_2bit;
  1709.                 if (igp_info->info_6.EnableBoost)
  1710.                         pi->sys_info.enable_boost = true;
  1711.                 else
  1712.                         pi->sys_info.enable_boost = false;
  1713.                 sumo_construct_display_voltage_mapping_table(rdev,
  1714.                                                              &pi->sys_info.disp_clk_voltage_mapping_table,
  1715.                                                              igp_info->info_6.sDISPCLK_Voltage);
  1716.                 sumo_construct_sclk_voltage_mapping_table(rdev,
  1717.                                                           &pi->sys_info.sclk_voltage_mapping_table,
  1718.                                                           igp_info->info_6.sAvail_SCLK);
  1719.                 sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
  1720.                                                  igp_info->info_6.sAvail_SCLK);
  1721.  
  1722.         }
  1723.         return 0;
  1724. }
  1725.  
  1726. static void sumo_construct_boot_and_acpi_state(struct radeon_device *rdev)
  1727. {
  1728.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1729.  
  1730.         pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
  1731.         pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
  1732.         pi->boot_pl.ds_divider_index = 0;
  1733.         pi->boot_pl.ss_divider_index = 0;
  1734.         pi->boot_pl.allow_gnb_slow = 1;
  1735.         pi->acpi_pl = pi->boot_pl;
  1736.         pi->current_ps.num_levels = 1;
  1737.         pi->current_ps.levels[0] = pi->boot_pl;
  1738. }
  1739.  
  1740. int sumo_dpm_init(struct radeon_device *rdev)
  1741. {
  1742.         struct sumo_power_info *pi;
  1743.         u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
  1744.         int ret;
  1745.  
  1746.         pi = kzalloc(sizeof(struct sumo_power_info), GFP_KERNEL);
  1747.         if (pi == NULL)
  1748.                 return -ENOMEM;
  1749.         rdev->pm.dpm.priv = pi;
  1750.  
  1751.         pi->driver_nbps_policy_disable = false;
  1752.         if ((rdev->family == CHIP_PALM) && (hw_rev < 3))
  1753.                 pi->disable_gfx_power_gating_in_uvd = true;
  1754.         else
  1755.                 pi->disable_gfx_power_gating_in_uvd = false;
  1756.         pi->enable_alt_vddnb = true;
  1757.         pi->enable_sclk_ds = true;
  1758.         pi->enable_dynamic_m3_arbiter = false;
  1759.         pi->enable_dynamic_patch_ps = true;
  1760.         /* Some PALM chips don't seem to properly ungate gfx when UVD is in use;
  1761.          * for now just disable gfx PG.
  1762.          */
  1763.         if (rdev->family == CHIP_PALM)
  1764.                 pi->enable_gfx_power_gating = false;
  1765.         else
  1766.                 pi->enable_gfx_power_gating = true;
  1767.         pi->enable_gfx_clock_gating = true;
  1768.         pi->enable_mg_clock_gating = true;
  1769.         pi->enable_auto_thermal_throttling = true;
  1770.  
  1771.         ret = sumo_parse_sys_info_table(rdev);
  1772.         if (ret)
  1773.                 return ret;
  1774.  
  1775.         sumo_construct_boot_and_acpi_state(rdev);
  1776.  
  1777.         ret = r600_get_platform_caps(rdev);
  1778.         if (ret)
  1779.                 return ret;
  1780.  
  1781.         ret = sumo_parse_power_table(rdev);
  1782.         if (ret)
  1783.                 return ret;
  1784.  
  1785.         pi->pasi = CYPRESS_HASI_DFLT;
  1786.         pi->asi = RV770_ASI_DFLT;
  1787.         pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
  1788.         pi->enable_boost = pi->sys_info.enable_boost;
  1789.         pi->enable_dpm = true;
  1790.  
  1791.         return 0;
  1792. }
  1793.  
  1794. void sumo_dpm_print_power_state(struct radeon_device *rdev,
  1795.                                 struct radeon_ps *rps)
  1796. {
  1797.         int i;
  1798.         struct sumo_ps *ps = sumo_get_ps(rps);
  1799.  
  1800.         r600_dpm_print_class_info(rps->class, rps->class2);
  1801.         r600_dpm_print_cap_info(rps->caps);
  1802.         printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
  1803.         for (i = 0; i < ps->num_levels; i++) {
  1804.                 struct sumo_pl *pl = &ps->levels[i];
  1805.                 printk("\t\tpower level %d    sclk: %u vddc: %u\n",
  1806.                        i, pl->sclk,
  1807.                        sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
  1808.         }
  1809.         r600_dpm_print_ps_status(rdev, rps);
  1810. }
  1811.  
  1812. void sumo_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
  1813.                                                       struct seq_file *m)
  1814. {
  1815.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1816.         struct radeon_ps *rps = &pi->current_rps;
  1817.         struct sumo_ps *ps = sumo_get_ps(rps);
  1818.         struct sumo_pl *pl;
  1819.         u32 current_index =
  1820.                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) >>
  1821.                 CURR_INDEX_SHIFT;
  1822.  
  1823.         if (current_index == BOOST_DPM_LEVEL) {
  1824.                 pl = &pi->boost_pl;
  1825.                 seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
  1826.                 seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
  1827.                            current_index, pl->sclk,
  1828.                            sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
  1829.         } else if (current_index >= ps->num_levels) {
  1830.                 seq_printf(m, "invalid dpm profile %d\n", current_index);
  1831.         } else {
  1832.                 pl = &ps->levels[current_index];
  1833.                 seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
  1834.                 seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
  1835.                            current_index, pl->sclk,
  1836.                            sumo_convert_voltage_index_to_value(rdev, pl->vddc_index));
  1837.         }
  1838. }
  1839.  
  1840. u32 sumo_dpm_get_current_sclk(struct radeon_device *rdev)
  1841. {
  1842.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1843.         struct radeon_ps *rps = &pi->current_rps;
  1844.         struct sumo_ps *ps = sumo_get_ps(rps);
  1845.         struct sumo_pl *pl;
  1846.         u32 current_index =
  1847.                 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_INDEX_MASK) >>
  1848.                 CURR_INDEX_SHIFT;
  1849.  
  1850.         if (current_index == BOOST_DPM_LEVEL) {
  1851.                 pl = &pi->boost_pl;
  1852.                 return pl->sclk;
  1853.         } else if (current_index >= ps->num_levels) {
  1854.                 return 0;
  1855.         } else {
  1856.                 pl = &ps->levels[current_index];
  1857.                 return pl->sclk;
  1858.         }
  1859. }
  1860.  
  1861. u32 sumo_dpm_get_current_mclk(struct radeon_device *rdev)
  1862. {
  1863.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1864.  
  1865.         return pi->sys_info.bootup_uma_clk;
  1866. }
  1867.  
  1868. void sumo_dpm_fini(struct radeon_device *rdev)
  1869. {
  1870.         int i;
  1871.  
  1872.         sumo_cleanup_asic(rdev); /* ??? */
  1873.  
  1874.         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
  1875.                 kfree(rdev->pm.dpm.ps[i].ps_priv);
  1876.         }
  1877.         kfree(rdev->pm.dpm.ps);
  1878.         kfree(rdev->pm.dpm.priv);
  1879. }
  1880.  
  1881. u32 sumo_dpm_get_sclk(struct radeon_device *rdev, bool low)
  1882. {
  1883.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1884.         struct sumo_ps *requested_state = sumo_get_ps(&pi->requested_rps);
  1885.  
  1886.         if (low)
  1887.                 return requested_state->levels[0].sclk;
  1888.         else
  1889.                 return requested_state->levels[requested_state->num_levels - 1].sclk;
  1890. }
  1891.  
  1892. u32 sumo_dpm_get_mclk(struct radeon_device *rdev, bool low)
  1893. {
  1894.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1895.  
  1896.         return pi->sys_info.bootup_uma_clk;
  1897. }
  1898.  
  1899. int sumo_dpm_force_performance_level(struct radeon_device *rdev,
  1900.                                      enum radeon_dpm_forced_level level)
  1901. {
  1902.         struct sumo_power_info *pi = sumo_get_pi(rdev);
  1903.         struct radeon_ps *rps = &pi->current_rps;
  1904.         struct sumo_ps *ps = sumo_get_ps(rps);
  1905.         int i;
  1906.  
  1907.         if (ps->num_levels <= 1)
  1908.                 return 0;
  1909.  
  1910.         if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
  1911.                 if (pi->enable_boost)
  1912.                         sumo_enable_boost(rdev, rps, false);
  1913.                 sumo_power_level_enable(rdev, ps->num_levels - 1, true);
  1914.                 sumo_set_forced_level(rdev, ps->num_levels - 1);
  1915.                 sumo_set_forced_mode_enabled(rdev);
  1916.                 for (i = 0; i < ps->num_levels - 1; i++) {
  1917.                         sumo_power_level_enable(rdev, i, false);
  1918.                 }
  1919.                 sumo_set_forced_mode(rdev, false);
  1920.                 sumo_set_forced_mode_enabled(rdev);
  1921.                 sumo_set_forced_mode(rdev, false);
  1922.         } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
  1923.                 if (pi->enable_boost)
  1924.                         sumo_enable_boost(rdev, rps, false);
  1925.                 sumo_power_level_enable(rdev, 0, true);
  1926.                 sumo_set_forced_level(rdev, 0);
  1927.                 sumo_set_forced_mode_enabled(rdev);
  1928.                 for (i = 1; i < ps->num_levels; i++) {
  1929.                         sumo_power_level_enable(rdev, i, false);
  1930.                 }
  1931.                 sumo_set_forced_mode(rdev, false);
  1932.                 sumo_set_forced_mode_enabled(rdev);
  1933.                 sumo_set_forced_mode(rdev, false);
  1934.         } else {
  1935.                 for (i = 0; i < ps->num_levels; i++) {
  1936.                         sumo_power_level_enable(rdev, i, true);
  1937.                 }
  1938.                 if (pi->enable_boost)
  1939.                         sumo_enable_boost(rdev, rps, true);
  1940.         }
  1941.  
  1942.         rdev->pm.dpm.forced_level = level;
  1943.  
  1944.         return 0;
  1945. }
  1946.