Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright 2013 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 "cikd.h"
  27. #include "r600_dpm.h"
  28. #include "kv_dpm.h"
  29. #include "radeon_asic.h"
  30. #include <linux/seq_file.h>
  31.  
  32. #define KV_MAX_DEEPSLEEP_DIVIDER_ID     5
  33. #define KV_MINIMUM_ENGINE_CLOCK         800
  34. #define SMC_RAM_END                     0x40000
  35.  
  36. static int kv_enable_nb_dpm(struct radeon_device *rdev,
  37.                             bool enable);
  38. static void kv_init_graphics_levels(struct radeon_device *rdev);
  39. static int kv_calculate_ds_divider(struct radeon_device *rdev);
  40. static int kv_calculate_nbps_level_settings(struct radeon_device *rdev);
  41. static int kv_calculate_dpm_settings(struct radeon_device *rdev);
  42. static void kv_enable_new_levels(struct radeon_device *rdev);
  43. static void kv_program_nbps_index_settings(struct radeon_device *rdev,
  44.                                            struct radeon_ps *new_rps);
  45. static int kv_set_enabled_level(struct radeon_device *rdev, u32 level);
  46. static int kv_set_enabled_levels(struct radeon_device *rdev);
  47. static int kv_force_dpm_highest(struct radeon_device *rdev);
  48. static int kv_force_dpm_lowest(struct radeon_device *rdev);
  49. static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
  50.                                         struct radeon_ps *new_rps,
  51.                                         struct radeon_ps *old_rps);
  52. static int kv_set_thermal_temperature_range(struct radeon_device *rdev,
  53.                                             int min_temp, int max_temp);
  54. static int kv_init_fps_limits(struct radeon_device *rdev);
  55.  
  56. void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate);
  57. static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate);
  58. static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate);
  59. static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate);
  60.  
  61. extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
  62. extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
  63. extern void cik_update_cg(struct radeon_device *rdev,
  64.                           u32 block, bool enable);
  65.  
  66. static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] =
  67. {
  68.         {  0,       4,        1    },
  69.         {  1,       4,        1    },
  70.         {  2,       5,        1    },
  71.         {  3,       4,        2    },
  72.         {  4,       1,        1    },
  73.         {  5,       5,        2    },
  74.         {  6,       6,        1    },
  75.         {  7,       9,        2    },
  76.         { 0xffffffff }
  77. };
  78.  
  79. static const struct kv_lcac_config_values mc0_local_cac_cfg_kv[] =
  80. {
  81.         {  0,       4,        1    },
  82.         { 0xffffffff }
  83. };
  84.  
  85. static const struct kv_lcac_config_values mc1_local_cac_cfg_kv[] =
  86. {
  87.         {  0,       4,        1    },
  88.         { 0xffffffff }
  89. };
  90.  
  91. static const struct kv_lcac_config_values mc2_local_cac_cfg_kv[] =
  92. {
  93.         {  0,       4,        1    },
  94.         { 0xffffffff }
  95. };
  96.  
  97. static const struct kv_lcac_config_values mc3_local_cac_cfg_kv[] =
  98. {
  99.         {  0,       4,        1    },
  100.         { 0xffffffff }
  101. };
  102.  
  103. static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] =
  104. {
  105.         {  0,       4,        1    },
  106.         {  1,       4,        1    },
  107.         {  2,       5,        1    },
  108.         {  3,       4,        1    },
  109.         {  4,       1,        1    },
  110.         {  5,       5,        1    },
  111.         {  6,       6,        1    },
  112.         {  7,       9,        1    },
  113.         {  8,       4,        1    },
  114.         {  9,       2,        1    },
  115.         {  10,      3,        1    },
  116.         {  11,      6,        1    },
  117.         {  12,      8,        2    },
  118.         {  13,      1,        1    },
  119.         {  14,      2,        1    },
  120.         {  15,      3,        1    },
  121.         {  16,      1,        1    },
  122.         {  17,      4,        1    },
  123.         {  18,      3,        1    },
  124.         {  19,      1,        1    },
  125.         {  20,      8,        1    },
  126.         {  21,      5,        1    },
  127.         {  22,      1,        1    },
  128.         {  23,      1,        1    },
  129.         {  24,      4,        1    },
  130.         {  27,      6,        1    },
  131.         {  28,      1,        1    },
  132.         { 0xffffffff }
  133. };
  134.  
  135. static const struct kv_lcac_config_reg sx0_cac_config_reg[] =
  136. {
  137.         { 0xc0400d00, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  138. };
  139.  
  140. static const struct kv_lcac_config_reg mc0_cac_config_reg[] =
  141. {
  142.         { 0xc0400d30, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  143. };
  144.  
  145. static const struct kv_lcac_config_reg mc1_cac_config_reg[] =
  146. {
  147.         { 0xc0400d3c, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  148. };
  149.  
  150. static const struct kv_lcac_config_reg mc2_cac_config_reg[] =
  151. {
  152.         { 0xc0400d48, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  153. };
  154.  
  155. static const struct kv_lcac_config_reg mc3_cac_config_reg[] =
  156. {
  157.         { 0xc0400d54, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  158. };
  159.  
  160. static const struct kv_lcac_config_reg cpl_cac_config_reg[] =
  161. {
  162.         { 0xc0400d80, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
  163. };
  164.  
  165. static const struct kv_pt_config_reg didt_config_kv[] =
  166. {
  167.         { 0x10, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  168.         { 0x10, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  169.         { 0x10, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  170.         { 0x10, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  171.         { 0x11, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  172.         { 0x11, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  173.         { 0x11, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  174.         { 0x11, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  175.         { 0x12, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  176.         { 0x12, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  177.         { 0x12, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  178.         { 0x12, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  179.         { 0x2, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
  180.         { 0x2, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
  181.         { 0x2, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
  182.         { 0x1, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  183.         { 0x1, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  184.         { 0x0, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  185.         { 0x30, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  186.         { 0x30, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  187.         { 0x30, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  188.         { 0x30, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  189.         { 0x31, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  190.         { 0x31, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  191.         { 0x31, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  192.         { 0x31, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  193.         { 0x32, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  194.         { 0x32, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  195.         { 0x32, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  196.         { 0x32, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  197.         { 0x22, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
  198.         { 0x22, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
  199.         { 0x22, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
  200.         { 0x21, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  201.         { 0x21, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  202.         { 0x20, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  203.         { 0x50, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  204.         { 0x50, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  205.         { 0x50, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  206.         { 0x50, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  207.         { 0x51, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  208.         { 0x51, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  209.         { 0x51, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  210.         { 0x51, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  211.         { 0x52, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  212.         { 0x52, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  213.         { 0x52, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  214.         { 0x52, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  215.         { 0x42, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
  216.         { 0x42, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
  217.         { 0x42, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
  218.         { 0x41, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  219.         { 0x41, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  220.         { 0x40, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  221.         { 0x70, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  222.         { 0x70, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  223.         { 0x70, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  224.         { 0x70, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  225.         { 0x71, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  226.         { 0x71, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  227.         { 0x71, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  228.         { 0x71, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  229.         { 0x72, 0x000000ff, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  230.         { 0x72, 0x0000ff00, 8, 0x0, KV_CONFIGREG_DIDT_IND },
  231.         { 0x72, 0x00ff0000, 16, 0x0, KV_CONFIGREG_DIDT_IND },
  232.         { 0x72, 0xff000000, 24, 0x0, KV_CONFIGREG_DIDT_IND },
  233.         { 0x62, 0x00003fff, 0, 0x4, KV_CONFIGREG_DIDT_IND },
  234.         { 0x62, 0x03ff0000, 16, 0x80, KV_CONFIGREG_DIDT_IND },
  235.         { 0x62, 0x78000000, 27, 0x3, KV_CONFIGREG_DIDT_IND },
  236.         { 0x61, 0x0000ffff, 0, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  237.         { 0x61, 0xffff0000, 16, 0x3FFF, KV_CONFIGREG_DIDT_IND },
  238.         { 0x60, 0x00000001, 0, 0x0, KV_CONFIGREG_DIDT_IND },
  239.         { 0xFFFFFFFF }
  240. };
  241.  
  242. static struct kv_ps *kv_get_ps(struct radeon_ps *rps)
  243. {
  244.         struct kv_ps *ps = rps->ps_priv;
  245.  
  246.         return ps;
  247. }
  248.  
  249. static struct kv_power_info *kv_get_pi(struct radeon_device *rdev)
  250. {
  251.         struct kv_power_info *pi = rdev->pm.dpm.priv;
  252.  
  253.         return pi;
  254. }
  255.  
  256. #if 0
  257. static void kv_program_local_cac_table(struct radeon_device *rdev,
  258.                                        const struct kv_lcac_config_values *local_cac_table,
  259.                                        const struct kv_lcac_config_reg *local_cac_reg)
  260. {
  261.         u32 i, count, data;
  262.         const struct kv_lcac_config_values *values = local_cac_table;
  263.  
  264.         while (values->block_id != 0xffffffff) {
  265.                 count = values->signal_id;
  266.                 for (i = 0; i < count; i++) {
  267.                         data = ((values->block_id << local_cac_reg->block_shift) &
  268.                                 local_cac_reg->block_mask);
  269.                         data |= ((i << local_cac_reg->signal_shift) &
  270.                                  local_cac_reg->signal_mask);
  271.                         data |= ((values->t << local_cac_reg->t_shift) &
  272.                                  local_cac_reg->t_mask);
  273.                         data |= ((1 << local_cac_reg->enable_shift) &
  274.                                  local_cac_reg->enable_mask);
  275.                         WREG32_SMC(local_cac_reg->cntl, data);
  276.                 }
  277.                 values++;
  278.         }
  279. }
  280. #endif
  281.  
  282. static int kv_program_pt_config_registers(struct radeon_device *rdev,
  283.                                           const struct kv_pt_config_reg *cac_config_regs)
  284. {
  285.         const struct kv_pt_config_reg *config_regs = cac_config_regs;
  286.         u32 data;
  287.         u32 cache = 0;
  288.  
  289.         if (config_regs == NULL)
  290.                 return -EINVAL;
  291.  
  292.         while (config_regs->offset != 0xFFFFFFFF) {
  293.                 if (config_regs->type == KV_CONFIGREG_CACHE) {
  294.                         cache |= ((config_regs->value << config_regs->shift) & config_regs->mask);
  295.                 } else {
  296.                         switch (config_regs->type) {
  297.                         case KV_CONFIGREG_SMC_IND:
  298.                                 data = RREG32_SMC(config_regs->offset);
  299.                                 break;
  300.                         case KV_CONFIGREG_DIDT_IND:
  301.                                 data = RREG32_DIDT(config_regs->offset);
  302.                                 break;
  303.                         default:
  304.                                 data = RREG32(config_regs->offset << 2);
  305.                                 break;
  306.                         }
  307.  
  308.                         data &= ~config_regs->mask;
  309.                         data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
  310.                         data |= cache;
  311.                         cache = 0;
  312.  
  313.                         switch (config_regs->type) {
  314.                         case KV_CONFIGREG_SMC_IND:
  315.                                 WREG32_SMC(config_regs->offset, data);
  316.                                 break;
  317.                         case KV_CONFIGREG_DIDT_IND:
  318.                                 WREG32_DIDT(config_regs->offset, data);
  319.                                 break;
  320.                         default:
  321.                                 WREG32(config_regs->offset << 2, data);
  322.                                 break;
  323.                         }
  324.                 }
  325.                 config_regs++;
  326.         }
  327.  
  328.         return 0;
  329. }
  330.  
  331. static void kv_do_enable_didt(struct radeon_device *rdev, bool enable)
  332. {
  333.         struct kv_power_info *pi = kv_get_pi(rdev);
  334.         u32 data;
  335.  
  336.         if (pi->caps_sq_ramping) {
  337.                 data = RREG32_DIDT(DIDT_SQ_CTRL0);
  338.                 if (enable)
  339.                         data |= DIDT_CTRL_EN;
  340.                 else
  341.                         data &= ~DIDT_CTRL_EN;
  342.                 WREG32_DIDT(DIDT_SQ_CTRL0, data);
  343.         }
  344.  
  345.         if (pi->caps_db_ramping) {
  346.                 data = RREG32_DIDT(DIDT_DB_CTRL0);
  347.                 if (enable)
  348.                         data |= DIDT_CTRL_EN;
  349.                 else
  350.                         data &= ~DIDT_CTRL_EN;
  351.                 WREG32_DIDT(DIDT_DB_CTRL0, data);
  352.         }
  353.  
  354.         if (pi->caps_td_ramping) {
  355.                 data = RREG32_DIDT(DIDT_TD_CTRL0);
  356.                 if (enable)
  357.                         data |= DIDT_CTRL_EN;
  358.                 else
  359.                         data &= ~DIDT_CTRL_EN;
  360.                 WREG32_DIDT(DIDT_TD_CTRL0, data);
  361.         }
  362.  
  363.         if (pi->caps_tcp_ramping) {
  364.                 data = RREG32_DIDT(DIDT_TCP_CTRL0);
  365.                 if (enable)
  366.                         data |= DIDT_CTRL_EN;
  367.                 else
  368.                         data &= ~DIDT_CTRL_EN;
  369.                 WREG32_DIDT(DIDT_TCP_CTRL0, data);
  370.         }
  371. }
  372.  
  373. static int kv_enable_didt(struct radeon_device *rdev, bool enable)
  374. {
  375.         struct kv_power_info *pi = kv_get_pi(rdev);
  376.         int ret;
  377.  
  378.         if (pi->caps_sq_ramping ||
  379.             pi->caps_db_ramping ||
  380.             pi->caps_td_ramping ||
  381.             pi->caps_tcp_ramping) {
  382.                 cik_enter_rlc_safe_mode(rdev);
  383.  
  384.                 if (enable) {
  385.                         ret = kv_program_pt_config_registers(rdev, didt_config_kv);
  386.                         if (ret) {
  387.                                 cik_exit_rlc_safe_mode(rdev);
  388.                                 return ret;
  389.                         }
  390.                 }
  391.  
  392.                 kv_do_enable_didt(rdev, enable);
  393.  
  394.                 cik_exit_rlc_safe_mode(rdev);
  395.         }
  396.  
  397.         return 0;
  398. }
  399.  
  400. #if 0
  401. static void kv_initialize_hardware_cac_manager(struct radeon_device *rdev)
  402. {
  403.         struct kv_power_info *pi = kv_get_pi(rdev);
  404.  
  405.         if (pi->caps_cac) {
  406.                 WREG32_SMC(LCAC_SX0_OVR_SEL, 0);
  407.                 WREG32_SMC(LCAC_SX0_OVR_VAL, 0);
  408.                 kv_program_local_cac_table(rdev, sx_local_cac_cfg_kv, sx0_cac_config_reg);
  409.  
  410.                 WREG32_SMC(LCAC_MC0_OVR_SEL, 0);
  411.                 WREG32_SMC(LCAC_MC0_OVR_VAL, 0);
  412.                 kv_program_local_cac_table(rdev, mc0_local_cac_cfg_kv, mc0_cac_config_reg);
  413.  
  414.                 WREG32_SMC(LCAC_MC1_OVR_SEL, 0);
  415.                 WREG32_SMC(LCAC_MC1_OVR_VAL, 0);
  416.                 kv_program_local_cac_table(rdev, mc1_local_cac_cfg_kv, mc1_cac_config_reg);
  417.  
  418.                 WREG32_SMC(LCAC_MC2_OVR_SEL, 0);
  419.                 WREG32_SMC(LCAC_MC2_OVR_VAL, 0);
  420.                 kv_program_local_cac_table(rdev, mc2_local_cac_cfg_kv, mc2_cac_config_reg);
  421.  
  422.                 WREG32_SMC(LCAC_MC3_OVR_SEL, 0);
  423.                 WREG32_SMC(LCAC_MC3_OVR_VAL, 0);
  424.                 kv_program_local_cac_table(rdev, mc3_local_cac_cfg_kv, mc3_cac_config_reg);
  425.  
  426.                 WREG32_SMC(LCAC_CPL_OVR_SEL, 0);
  427.                 WREG32_SMC(LCAC_CPL_OVR_VAL, 0);
  428.                 kv_program_local_cac_table(rdev, cpl_local_cac_cfg_kv, cpl_cac_config_reg);
  429.         }
  430. }
  431. #endif
  432.  
  433. static int kv_enable_smc_cac(struct radeon_device *rdev, bool enable)
  434. {
  435.         struct kv_power_info *pi = kv_get_pi(rdev);
  436.         int ret = 0;
  437.  
  438.         if (pi->caps_cac) {
  439.                 if (enable) {
  440.                         ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_EnableCac);
  441.                         if (ret)
  442.                                 pi->cac_enabled = false;
  443.                         else
  444.                                 pi->cac_enabled = true;
  445.                 } else if (pi->cac_enabled) {
  446.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_DisableCac);
  447.                         pi->cac_enabled = false;
  448.                 }
  449.         }
  450.  
  451.         return ret;
  452. }
  453.  
  454. static int kv_process_firmware_header(struct radeon_device *rdev)
  455. {
  456.         struct kv_power_info *pi = kv_get_pi(rdev);
  457.         u32 tmp;
  458.         int ret;
  459.  
  460.         ret = kv_read_smc_sram_dword(rdev, SMU7_FIRMWARE_HEADER_LOCATION +
  461.                                      offsetof(SMU7_Firmware_Header, DpmTable),
  462.                                      &tmp, pi->sram_end);
  463.  
  464.         if (ret == 0)
  465.                 pi->dpm_table_start = tmp;
  466.  
  467.         ret = kv_read_smc_sram_dword(rdev, SMU7_FIRMWARE_HEADER_LOCATION +
  468.                                      offsetof(SMU7_Firmware_Header, SoftRegisters),
  469.                                      &tmp, pi->sram_end);
  470.  
  471.         if (ret == 0)
  472.                 pi->soft_regs_start = tmp;
  473.  
  474.         return ret;
  475. }
  476.  
  477. static int kv_enable_dpm_voltage_scaling(struct radeon_device *rdev)
  478. {
  479.         struct kv_power_info *pi = kv_get_pi(rdev);
  480.         int ret;
  481.  
  482.         pi->graphics_voltage_change_enable = 1;
  483.  
  484.         ret = kv_copy_bytes_to_smc(rdev,
  485.                                    pi->dpm_table_start +
  486.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsVoltageChangeEnable),
  487.                                    &pi->graphics_voltage_change_enable,
  488.                                    sizeof(u8), pi->sram_end);
  489.  
  490.         return ret;
  491. }
  492.  
  493. static int kv_set_dpm_interval(struct radeon_device *rdev)
  494. {
  495.         struct kv_power_info *pi = kv_get_pi(rdev);
  496.         int ret;
  497.  
  498.         pi->graphics_interval = 1;
  499.  
  500.         ret = kv_copy_bytes_to_smc(rdev,
  501.                                    pi->dpm_table_start +
  502.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsInterval),
  503.                                    &pi->graphics_interval,
  504.                                    sizeof(u8), pi->sram_end);
  505.  
  506.         return ret;
  507. }
  508.  
  509. static int kv_set_dpm_boot_state(struct radeon_device *rdev)
  510. {
  511.         struct kv_power_info *pi = kv_get_pi(rdev);
  512.         int ret;
  513.  
  514.         ret = kv_copy_bytes_to_smc(rdev,
  515.                                    pi->dpm_table_start +
  516.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsBootLevel),
  517.                                    &pi->graphics_boot_level,
  518.                                    sizeof(u8), pi->sram_end);
  519.  
  520.         return ret;
  521. }
  522.  
  523. static void kv_program_vc(struct radeon_device *rdev)
  524. {
  525.         WREG32_SMC(CG_FTV_0, 0x3FFFC100);
  526. }
  527.  
  528. static void kv_clear_vc(struct radeon_device *rdev)
  529. {
  530.         WREG32_SMC(CG_FTV_0, 0);
  531. }
  532.  
  533. static int kv_set_divider_value(struct radeon_device *rdev,
  534.                                 u32 index, u32 sclk)
  535. {
  536.         struct kv_power_info *pi = kv_get_pi(rdev);
  537.         struct atom_clock_dividers dividers;
  538.         int ret;
  539.  
  540.         ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  541.                                              sclk, false, &dividers);
  542.         if (ret)
  543.                 return ret;
  544.  
  545.         pi->graphics_level[index].SclkDid = (u8)dividers.post_div;
  546.         pi->graphics_level[index].SclkFrequency = cpu_to_be32(sclk);
  547.  
  548.         return 0;
  549. }
  550.  
  551. static u32 kv_convert_vid2_to_vid7(struct radeon_device *rdev,
  552.                                    struct sumo_vid_mapping_table *vid_mapping_table,
  553.                                    u32 vid_2bit)
  554. {
  555.         struct radeon_clock_voltage_dependency_table *vddc_sclk_table =
  556.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  557.         u32 i;
  558.  
  559.         if (vddc_sclk_table && vddc_sclk_table->count) {
  560.                 if (vid_2bit < vddc_sclk_table->count)
  561.                         return vddc_sclk_table->entries[vid_2bit].v;
  562.                 else
  563.                         return vddc_sclk_table->entries[vddc_sclk_table->count - 1].v;
  564.         } else {
  565.                 for (i = 0; i < vid_mapping_table->num_entries; i++) {
  566.                         if (vid_mapping_table->entries[i].vid_2bit == vid_2bit)
  567.                                 return vid_mapping_table->entries[i].vid_7bit;
  568.                 }
  569.                 return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit;
  570.         }
  571. }
  572.  
  573. static u32 kv_convert_vid7_to_vid2(struct radeon_device *rdev,
  574.                                    struct sumo_vid_mapping_table *vid_mapping_table,
  575.                                    u32 vid_7bit)
  576. {
  577.         struct radeon_clock_voltage_dependency_table *vddc_sclk_table =
  578.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  579.         u32 i;
  580.  
  581.         if (vddc_sclk_table && vddc_sclk_table->count) {
  582.                 for (i = 0; i < vddc_sclk_table->count; i++) {
  583.                         if (vddc_sclk_table->entries[i].v == vid_7bit)
  584.                                 return i;
  585.                 }
  586.                 return vddc_sclk_table->count - 1;
  587.         } else {
  588.                 for (i = 0; i < vid_mapping_table->num_entries; i++) {
  589.                         if (vid_mapping_table->entries[i].vid_7bit == vid_7bit)
  590.                                 return vid_mapping_table->entries[i].vid_2bit;
  591.                 }
  592.  
  593.                 return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit;
  594.         }
  595. }
  596.  
  597. static u16 kv_convert_8bit_index_to_voltage(struct radeon_device *rdev,
  598.                                             u16 voltage)
  599. {
  600.         return 6200 - (voltage * 25);
  601. }
  602.  
  603. static u16 kv_convert_2bit_index_to_voltage(struct radeon_device *rdev,
  604.                                             u32 vid_2bit)
  605. {
  606.         struct kv_power_info *pi = kv_get_pi(rdev);
  607.         u32 vid_8bit = kv_convert_vid2_to_vid7(rdev,
  608.                                                &pi->sys_info.vid_mapping_table,
  609.                                                vid_2bit);
  610.  
  611.         return kv_convert_8bit_index_to_voltage(rdev, (u16)vid_8bit);
  612. }
  613.  
  614.  
  615. static int kv_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
  616. {
  617.         struct kv_power_info *pi = kv_get_pi(rdev);
  618.  
  619.         pi->graphics_level[index].VoltageDownH = (u8)pi->voltage_drop_t;
  620.         pi->graphics_level[index].MinVddNb =
  621.                 cpu_to_be32(kv_convert_2bit_index_to_voltage(rdev, vid));
  622.  
  623.         return 0;
  624. }
  625.  
  626. static int kv_set_at(struct radeon_device *rdev, u32 index, u32 at)
  627. {
  628.         struct kv_power_info *pi = kv_get_pi(rdev);
  629.  
  630.         pi->graphics_level[index].AT = cpu_to_be16((u16)at);
  631.  
  632.         return 0;
  633. }
  634.  
  635. static void kv_dpm_power_level_enable(struct radeon_device *rdev,
  636.                                       u32 index, bool enable)
  637. {
  638.         struct kv_power_info *pi = kv_get_pi(rdev);
  639.  
  640.         pi->graphics_level[index].EnabledForActivity = enable ? 1 : 0;
  641. }
  642.  
  643. static void kv_start_dpm(struct radeon_device *rdev)
  644. {
  645.         u32 tmp = RREG32_SMC(GENERAL_PWRMGT);
  646.  
  647.         tmp |= GLOBAL_PWRMGT_EN;
  648.         WREG32_SMC(GENERAL_PWRMGT, tmp);
  649.  
  650.         kv_smc_dpm_enable(rdev, true);
  651. }
  652.  
  653. static void kv_stop_dpm(struct radeon_device *rdev)
  654. {
  655.         kv_smc_dpm_enable(rdev, false);
  656. }
  657.  
  658. static void kv_start_am(struct radeon_device *rdev)
  659. {
  660.         u32 sclk_pwrmgt_cntl = RREG32_SMC(SCLK_PWRMGT_CNTL);
  661.  
  662.         sclk_pwrmgt_cntl &= ~(RESET_SCLK_CNT | RESET_BUSY_CNT);
  663.         sclk_pwrmgt_cntl |= DYNAMIC_PM_EN;
  664.  
  665.         WREG32_SMC(SCLK_PWRMGT_CNTL, sclk_pwrmgt_cntl);
  666. }
  667.  
  668. static void kv_reset_am(struct radeon_device *rdev)
  669. {
  670.         u32 sclk_pwrmgt_cntl = RREG32_SMC(SCLK_PWRMGT_CNTL);
  671.  
  672.         sclk_pwrmgt_cntl |= (RESET_SCLK_CNT | RESET_BUSY_CNT);
  673.  
  674.         WREG32_SMC(SCLK_PWRMGT_CNTL, sclk_pwrmgt_cntl);
  675. }
  676.  
  677. static int kv_freeze_sclk_dpm(struct radeon_device *rdev, bool freeze)
  678. {
  679.         return kv_notify_message_to_smu(rdev, freeze ?
  680.                                         PPSMC_MSG_SCLKDPM_FreezeLevel : PPSMC_MSG_SCLKDPM_UnfreezeLevel);
  681. }
  682.  
  683. static int kv_force_lowest_valid(struct radeon_device *rdev)
  684. {
  685.         return kv_force_dpm_lowest(rdev);
  686. }
  687.  
  688. static int kv_unforce_levels(struct radeon_device *rdev)
  689. {
  690.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  691.                 return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel);
  692.         else
  693.                 return kv_set_enabled_levels(rdev);
  694. }
  695.  
  696. static int kv_update_sclk_t(struct radeon_device *rdev)
  697. {
  698.         struct kv_power_info *pi = kv_get_pi(rdev);
  699.         u32 low_sclk_interrupt_t = 0;
  700.         int ret = 0;
  701.  
  702.         if (pi->caps_sclk_throttle_low_notification) {
  703.                 low_sclk_interrupt_t = cpu_to_be32(pi->low_sclk_interrupt_t);
  704.  
  705.                 ret = kv_copy_bytes_to_smc(rdev,
  706.                                            pi->dpm_table_start +
  707.                                            offsetof(SMU7_Fusion_DpmTable, LowSclkInterruptT),
  708.                                            (u8 *)&low_sclk_interrupt_t,
  709.                                            sizeof(u32), pi->sram_end);
  710.         }
  711.         return ret;
  712. }
  713.  
  714. static int kv_program_bootup_state(struct radeon_device *rdev)
  715. {
  716.         struct kv_power_info *pi = kv_get_pi(rdev);
  717.         u32 i;
  718.         struct radeon_clock_voltage_dependency_table *table =
  719.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  720.  
  721.         if (table && table->count) {
  722.                 for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
  723.                         if (table->entries[i].clk == pi->boot_pl.sclk)
  724.                                 break;
  725.                 }
  726.  
  727.                 pi->graphics_boot_level = (u8)i;
  728.                 kv_dpm_power_level_enable(rdev, i, true);
  729.         } else {
  730.                 struct sumo_sclk_voltage_mapping_table *table =
  731.                         &pi->sys_info.sclk_voltage_mapping_table;
  732.  
  733.                 if (table->num_max_dpm_entries == 0)
  734.                         return -EINVAL;
  735.  
  736.                 for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
  737.                         if (table->entries[i].sclk_frequency == pi->boot_pl.sclk)
  738.                                 break;
  739.                 }
  740.  
  741.                 pi->graphics_boot_level = (u8)i;
  742.                 kv_dpm_power_level_enable(rdev, i, true);
  743.         }
  744.         return 0;
  745. }
  746.  
  747. static int kv_enable_auto_thermal_throttling(struct radeon_device *rdev)
  748. {
  749.         struct kv_power_info *pi = kv_get_pi(rdev);
  750.         int ret;
  751.  
  752.         pi->graphics_therm_throttle_enable = 1;
  753.  
  754.         ret = kv_copy_bytes_to_smc(rdev,
  755.                                    pi->dpm_table_start +
  756.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsThermThrottleEnable),
  757.                                    &pi->graphics_therm_throttle_enable,
  758.                                    sizeof(u8), pi->sram_end);
  759.  
  760.         return ret;
  761. }
  762.  
  763. static int kv_upload_dpm_settings(struct radeon_device *rdev)
  764. {
  765.         struct kv_power_info *pi = kv_get_pi(rdev);
  766.         int ret;
  767.  
  768.         ret = kv_copy_bytes_to_smc(rdev,
  769.                                    pi->dpm_table_start +
  770.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsLevel),
  771.                                    (u8 *)&pi->graphics_level,
  772.                                    sizeof(SMU7_Fusion_GraphicsLevel) * SMU7_MAX_LEVELS_GRAPHICS,
  773.                                    pi->sram_end);
  774.  
  775.         if (ret)
  776.                 return ret;
  777.  
  778.         ret = kv_copy_bytes_to_smc(rdev,
  779.                                    pi->dpm_table_start +
  780.                                    offsetof(SMU7_Fusion_DpmTable, GraphicsDpmLevelCount),
  781.                                    &pi->graphics_dpm_level_count,
  782.                                    sizeof(u8), pi->sram_end);
  783.  
  784.         return ret;
  785. }
  786.  
  787. static u32 kv_get_clock_difference(u32 a, u32 b)
  788. {
  789.         return (a >= b) ? a - b : b - a;
  790. }
  791.  
  792. static u32 kv_get_clk_bypass(struct radeon_device *rdev, u32 clk)
  793. {
  794.         struct kv_power_info *pi = kv_get_pi(rdev);
  795.         u32 value;
  796.  
  797.         if (pi->caps_enable_dfs_bypass) {
  798.                 if (kv_get_clock_difference(clk, 40000) < 200)
  799.                         value = 3;
  800.                 else if (kv_get_clock_difference(clk, 30000) < 200)
  801.                         value = 2;
  802.                 else if (kv_get_clock_difference(clk, 20000) < 200)
  803.                         value = 7;
  804.                 else if (kv_get_clock_difference(clk, 15000) < 200)
  805.                         value = 6;
  806.                 else if (kv_get_clock_difference(clk, 10000) < 200)
  807.                         value = 8;
  808.                 else
  809.                         value = 0;
  810.         } else {
  811.                 value = 0;
  812.         }
  813.  
  814.         return value;
  815. }
  816.  
  817. static int kv_populate_uvd_table(struct radeon_device *rdev)
  818. {
  819.         struct kv_power_info *pi = kv_get_pi(rdev);
  820.         struct radeon_uvd_clock_voltage_dependency_table *table =
  821.                 &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
  822.         struct atom_clock_dividers dividers;
  823.         int ret;
  824.         u32 i;
  825.  
  826.         if (table == NULL || table->count == 0)
  827.                 return 0;
  828.  
  829.         pi->uvd_level_count = 0;
  830.         for (i = 0; i < table->count; i++) {
  831.                 if (pi->high_voltage_t &&
  832.                     (pi->high_voltage_t < table->entries[i].v))
  833.                         break;
  834.  
  835.                 pi->uvd_level[i].VclkFrequency = cpu_to_be32(table->entries[i].vclk);
  836.                 pi->uvd_level[i].DclkFrequency = cpu_to_be32(table->entries[i].dclk);
  837.                 pi->uvd_level[i].MinVddNb = cpu_to_be16(table->entries[i].v);
  838.  
  839.                 pi->uvd_level[i].VClkBypassCntl =
  840.                         (u8)kv_get_clk_bypass(rdev, table->entries[i].vclk);
  841.                 pi->uvd_level[i].DClkBypassCntl =
  842.                         (u8)kv_get_clk_bypass(rdev, table->entries[i].dclk);
  843.  
  844.                 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  845.                                                      table->entries[i].vclk, false, &dividers);
  846.                 if (ret)
  847.                         return ret;
  848.                 pi->uvd_level[i].VclkDivider = (u8)dividers.post_div;
  849.  
  850.                 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  851.                                                      table->entries[i].dclk, false, &dividers);
  852.                 if (ret)
  853.                         return ret;
  854.                 pi->uvd_level[i].DclkDivider = (u8)dividers.post_div;
  855.  
  856.                 pi->uvd_level_count++;
  857.         }
  858.  
  859.         ret = kv_copy_bytes_to_smc(rdev,
  860.                                    pi->dpm_table_start +
  861.                                    offsetof(SMU7_Fusion_DpmTable, UvdLevelCount),
  862.                                    (u8 *)&pi->uvd_level_count,
  863.                                    sizeof(u8), pi->sram_end);
  864.         if (ret)
  865.                 return ret;
  866.  
  867.         pi->uvd_interval = 1;
  868.  
  869.         ret = kv_copy_bytes_to_smc(rdev,
  870.                                    pi->dpm_table_start +
  871.                                    offsetof(SMU7_Fusion_DpmTable, UVDInterval),
  872.                                    &pi->uvd_interval,
  873.                                    sizeof(u8), pi->sram_end);
  874.         if (ret)
  875.                 return ret;
  876.  
  877.         ret = kv_copy_bytes_to_smc(rdev,
  878.                                    pi->dpm_table_start +
  879.                                    offsetof(SMU7_Fusion_DpmTable, UvdLevel),
  880.                                    (u8 *)&pi->uvd_level,
  881.                                    sizeof(SMU7_Fusion_UvdLevel) * SMU7_MAX_LEVELS_UVD,
  882.                                    pi->sram_end);
  883.  
  884.         return ret;
  885.  
  886. }
  887.  
  888. static int kv_populate_vce_table(struct radeon_device *rdev)
  889. {
  890.         struct kv_power_info *pi = kv_get_pi(rdev);
  891.         int ret;
  892.         u32 i;
  893.         struct radeon_vce_clock_voltage_dependency_table *table =
  894.                 &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
  895.         struct atom_clock_dividers dividers;
  896.  
  897.         if (table == NULL || table->count == 0)
  898.                 return 0;
  899.  
  900.         pi->vce_level_count = 0;
  901.         for (i = 0; i < table->count; i++) {
  902.                 if (pi->high_voltage_t &&
  903.                     pi->high_voltage_t < table->entries[i].v)
  904.                         break;
  905.  
  906.                 pi->vce_level[i].Frequency = cpu_to_be32(table->entries[i].evclk);
  907.                 pi->vce_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
  908.  
  909.                 pi->vce_level[i].ClkBypassCntl =
  910.                         (u8)kv_get_clk_bypass(rdev, table->entries[i].evclk);
  911.  
  912.                 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  913.                                                      table->entries[i].evclk, false, &dividers);
  914.                 if (ret)
  915.                         return ret;
  916.                 pi->vce_level[i].Divider = (u8)dividers.post_div;
  917.  
  918.                 pi->vce_level_count++;
  919.         }
  920.  
  921.         ret = kv_copy_bytes_to_smc(rdev,
  922.                                    pi->dpm_table_start +
  923.                                    offsetof(SMU7_Fusion_DpmTable, VceLevelCount),
  924.                                    (u8 *)&pi->vce_level_count,
  925.                                    sizeof(u8),
  926.                                    pi->sram_end);
  927.         if (ret)
  928.                 return ret;
  929.  
  930.         pi->vce_interval = 1;
  931.  
  932.         ret = kv_copy_bytes_to_smc(rdev,
  933.                                    pi->dpm_table_start +
  934.                                    offsetof(SMU7_Fusion_DpmTable, VCEInterval),
  935.                                    (u8 *)&pi->vce_interval,
  936.                                    sizeof(u8),
  937.                                    pi->sram_end);
  938.         if (ret)
  939.                 return ret;
  940.  
  941.         ret = kv_copy_bytes_to_smc(rdev,
  942.                                    pi->dpm_table_start +
  943.                                    offsetof(SMU7_Fusion_DpmTable, VceLevel),
  944.                                    (u8 *)&pi->vce_level,
  945.                                    sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_VCE,
  946.                                    pi->sram_end);
  947.  
  948.         return ret;
  949. }
  950.  
  951. static int kv_populate_samu_table(struct radeon_device *rdev)
  952. {
  953.         struct kv_power_info *pi = kv_get_pi(rdev);
  954.         struct radeon_clock_voltage_dependency_table *table =
  955.                 &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
  956.         struct atom_clock_dividers dividers;
  957.         int ret;
  958.         u32 i;
  959.  
  960.         if (table == NULL || table->count == 0)
  961.                 return 0;
  962.  
  963.         pi->samu_level_count = 0;
  964.         for (i = 0; i < table->count; i++) {
  965.                 if (pi->high_voltage_t &&
  966.                     pi->high_voltage_t < table->entries[i].v)
  967.                         break;
  968.  
  969.                 pi->samu_level[i].Frequency = cpu_to_be32(table->entries[i].clk);
  970.                 pi->samu_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
  971.  
  972.                 pi->samu_level[i].ClkBypassCntl =
  973.                         (u8)kv_get_clk_bypass(rdev, table->entries[i].clk);
  974.  
  975.                 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  976.                                                      table->entries[i].clk, false, &dividers);
  977.                 if (ret)
  978.                         return ret;
  979.                 pi->samu_level[i].Divider = (u8)dividers.post_div;
  980.  
  981.                 pi->samu_level_count++;
  982.         }
  983.  
  984.         ret = kv_copy_bytes_to_smc(rdev,
  985.                                    pi->dpm_table_start +
  986.                                    offsetof(SMU7_Fusion_DpmTable, SamuLevelCount),
  987.                                    (u8 *)&pi->samu_level_count,
  988.                                    sizeof(u8),
  989.                                    pi->sram_end);
  990.         if (ret)
  991.                 return ret;
  992.  
  993.         pi->samu_interval = 1;
  994.  
  995.         ret = kv_copy_bytes_to_smc(rdev,
  996.                                    pi->dpm_table_start +
  997.                                    offsetof(SMU7_Fusion_DpmTable, SAMUInterval),
  998.                                    (u8 *)&pi->samu_interval,
  999.                                    sizeof(u8),
  1000.                                    pi->sram_end);
  1001.         if (ret)
  1002.                 return ret;
  1003.  
  1004.         ret = kv_copy_bytes_to_smc(rdev,
  1005.                                    pi->dpm_table_start +
  1006.                                    offsetof(SMU7_Fusion_DpmTable, SamuLevel),
  1007.                                    (u8 *)&pi->samu_level,
  1008.                                    sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_SAMU,
  1009.                                    pi->sram_end);
  1010.         if (ret)
  1011.                 return ret;
  1012.  
  1013.         return ret;
  1014. }
  1015.  
  1016.  
  1017. static int kv_populate_acp_table(struct radeon_device *rdev)
  1018. {
  1019.         struct kv_power_info *pi = kv_get_pi(rdev);
  1020.         struct radeon_clock_voltage_dependency_table *table =
  1021.                 &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
  1022.         struct atom_clock_dividers dividers;
  1023.         int ret;
  1024.         u32 i;
  1025.  
  1026.         if (table == NULL || table->count == 0)
  1027.                 return 0;
  1028.  
  1029.         pi->acp_level_count = 0;
  1030.         for (i = 0; i < table->count; i++) {
  1031.                 pi->acp_level[i].Frequency = cpu_to_be32(table->entries[i].clk);
  1032.                 pi->acp_level[i].MinVoltage = cpu_to_be16(table->entries[i].v);
  1033.  
  1034.                 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
  1035.                                                      table->entries[i].clk, false, &dividers);
  1036.                 if (ret)
  1037.                         return ret;
  1038.                 pi->acp_level[i].Divider = (u8)dividers.post_div;
  1039.  
  1040.                 pi->acp_level_count++;
  1041.         }
  1042.  
  1043.         ret = kv_copy_bytes_to_smc(rdev,
  1044.                                    pi->dpm_table_start +
  1045.                                    offsetof(SMU7_Fusion_DpmTable, AcpLevelCount),
  1046.                                    (u8 *)&pi->acp_level_count,
  1047.                                    sizeof(u8),
  1048.                                    pi->sram_end);
  1049.         if (ret)
  1050.                 return ret;
  1051.  
  1052.         pi->acp_interval = 1;
  1053.  
  1054.         ret = kv_copy_bytes_to_smc(rdev,
  1055.                                    pi->dpm_table_start +
  1056.                                    offsetof(SMU7_Fusion_DpmTable, ACPInterval),
  1057.                                    (u8 *)&pi->acp_interval,
  1058.                                    sizeof(u8),
  1059.                                    pi->sram_end);
  1060.         if (ret)
  1061.                 return ret;
  1062.  
  1063.         ret = kv_copy_bytes_to_smc(rdev,
  1064.                                    pi->dpm_table_start +
  1065.                                    offsetof(SMU7_Fusion_DpmTable, AcpLevel),
  1066.                                    (u8 *)&pi->acp_level,
  1067.                                    sizeof(SMU7_Fusion_ExtClkLevel) * SMU7_MAX_LEVELS_ACP,
  1068.                                    pi->sram_end);
  1069.         if (ret)
  1070.                 return ret;
  1071.  
  1072.         return ret;
  1073. }
  1074.  
  1075. static void kv_calculate_dfs_bypass_settings(struct radeon_device *rdev)
  1076. {
  1077.         struct kv_power_info *pi = kv_get_pi(rdev);
  1078.         u32 i;
  1079.         struct radeon_clock_voltage_dependency_table *table =
  1080.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  1081.  
  1082.         if (table && table->count) {
  1083.                 for (i = 0; i < pi->graphics_dpm_level_count; i++) {
  1084.                         if (pi->caps_enable_dfs_bypass) {
  1085.                                 if (kv_get_clock_difference(table->entries[i].clk, 40000) < 200)
  1086.                                         pi->graphics_level[i].ClkBypassCntl = 3;
  1087.                                 else if (kv_get_clock_difference(table->entries[i].clk, 30000) < 200)
  1088.                                         pi->graphics_level[i].ClkBypassCntl = 2;
  1089.                                 else if (kv_get_clock_difference(table->entries[i].clk, 26600) < 200)
  1090.                                         pi->graphics_level[i].ClkBypassCntl = 7;
  1091.                                 else if (kv_get_clock_difference(table->entries[i].clk , 20000) < 200)
  1092.                                         pi->graphics_level[i].ClkBypassCntl = 6;
  1093.                                 else if (kv_get_clock_difference(table->entries[i].clk , 10000) < 200)
  1094.                                         pi->graphics_level[i].ClkBypassCntl = 8;
  1095.                                 else
  1096.                                         pi->graphics_level[i].ClkBypassCntl = 0;
  1097.                         } else {
  1098.                                 pi->graphics_level[i].ClkBypassCntl = 0;
  1099.                         }
  1100.                 }
  1101.         } else {
  1102.                 struct sumo_sclk_voltage_mapping_table *table =
  1103.                         &pi->sys_info.sclk_voltage_mapping_table;
  1104.                 for (i = 0; i < pi->graphics_dpm_level_count; i++) {
  1105.                         if (pi->caps_enable_dfs_bypass) {
  1106.                                 if (kv_get_clock_difference(table->entries[i].sclk_frequency, 40000) < 200)
  1107.                                         pi->graphics_level[i].ClkBypassCntl = 3;
  1108.                                 else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 30000) < 200)
  1109.                                         pi->graphics_level[i].ClkBypassCntl = 2;
  1110.                                 else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 26600) < 200)
  1111.                                         pi->graphics_level[i].ClkBypassCntl = 7;
  1112.                                 else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 20000) < 200)
  1113.                                         pi->graphics_level[i].ClkBypassCntl = 6;
  1114.                                 else if (kv_get_clock_difference(table->entries[i].sclk_frequency, 10000) < 200)
  1115.                                         pi->graphics_level[i].ClkBypassCntl = 8;
  1116.                                 else
  1117.                                         pi->graphics_level[i].ClkBypassCntl = 0;
  1118.                         } else {
  1119.                                 pi->graphics_level[i].ClkBypassCntl = 0;
  1120.                         }
  1121.                 }
  1122.         }
  1123. }
  1124.  
  1125. static int kv_enable_ulv(struct radeon_device *rdev, bool enable)
  1126. {
  1127.         return kv_notify_message_to_smu(rdev, enable ?
  1128.                                         PPSMC_MSG_EnableULV : PPSMC_MSG_DisableULV);
  1129. }
  1130.  
  1131. static void kv_reset_acp_boot_level(struct radeon_device *rdev)
  1132. {
  1133.         struct kv_power_info *pi = kv_get_pi(rdev);
  1134.  
  1135.         pi->acp_boot_level = 0xff;
  1136. }
  1137.  
  1138. static void kv_update_current_ps(struct radeon_device *rdev,
  1139.                                  struct radeon_ps *rps)
  1140. {
  1141.         struct kv_ps *new_ps = kv_get_ps(rps);
  1142.         struct kv_power_info *pi = kv_get_pi(rdev);
  1143.  
  1144.         pi->current_rps = *rps;
  1145.         pi->current_ps = *new_ps;
  1146.         pi->current_rps.ps_priv = &pi->current_ps;
  1147. }
  1148.  
  1149. static void kv_update_requested_ps(struct radeon_device *rdev,
  1150.                                    struct radeon_ps *rps)
  1151. {
  1152.         struct kv_ps *new_ps = kv_get_ps(rps);
  1153.         struct kv_power_info *pi = kv_get_pi(rdev);
  1154.  
  1155.         pi->requested_rps = *rps;
  1156.         pi->requested_ps = *new_ps;
  1157.         pi->requested_rps.ps_priv = &pi->requested_ps;
  1158. }
  1159.  
  1160. void kv_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
  1161. {
  1162.         struct kv_power_info *pi = kv_get_pi(rdev);
  1163.         int ret;
  1164.  
  1165.         if (pi->bapm_enable) {
  1166.                 ret = kv_smc_bapm_enable(rdev, enable);
  1167.                 if (ret)
  1168.                         DRM_ERROR("kv_smc_bapm_enable failed\n");
  1169.         }
  1170. }
  1171.  
  1172. static void kv_enable_thermal_int(struct radeon_device *rdev, bool enable)
  1173. {
  1174.         u32 thermal_int;
  1175.  
  1176.         thermal_int = RREG32_SMC(CG_THERMAL_INT_CTRL);
  1177.         if (enable)
  1178.                 thermal_int |= THERM_INTH_MASK | THERM_INTL_MASK;
  1179.         else
  1180.                 thermal_int &= ~(THERM_INTH_MASK | THERM_INTL_MASK);
  1181.         WREG32_SMC(CG_THERMAL_INT_CTRL, thermal_int);
  1182.  
  1183. }
  1184.  
  1185. int kv_dpm_enable(struct radeon_device *rdev)
  1186. {
  1187.         struct kv_power_info *pi = kv_get_pi(rdev);
  1188.         int ret;
  1189.  
  1190.         ret = kv_process_firmware_header(rdev);
  1191.         if (ret) {
  1192.                 DRM_ERROR("kv_process_firmware_header failed\n");
  1193.                 return ret;
  1194.         }
  1195.         kv_init_fps_limits(rdev);
  1196.         kv_init_graphics_levels(rdev);
  1197.         ret = kv_program_bootup_state(rdev);
  1198.         if (ret) {
  1199.                 DRM_ERROR("kv_program_bootup_state failed\n");
  1200.                 return ret;
  1201.         }
  1202.         kv_calculate_dfs_bypass_settings(rdev);
  1203.         ret = kv_upload_dpm_settings(rdev);
  1204.         if (ret) {
  1205.                 DRM_ERROR("kv_upload_dpm_settings failed\n");
  1206.                 return ret;
  1207.         }
  1208.         ret = kv_populate_uvd_table(rdev);
  1209.         if (ret) {
  1210.                 DRM_ERROR("kv_populate_uvd_table failed\n");
  1211.                 return ret;
  1212.         }
  1213.         ret = kv_populate_vce_table(rdev);
  1214.         if (ret) {
  1215.                 DRM_ERROR("kv_populate_vce_table failed\n");
  1216.                 return ret;
  1217.         }
  1218.         ret = kv_populate_samu_table(rdev);
  1219.         if (ret) {
  1220.                 DRM_ERROR("kv_populate_samu_table failed\n");
  1221.                 return ret;
  1222.         }
  1223.         ret = kv_populate_acp_table(rdev);
  1224.         if (ret) {
  1225.                 DRM_ERROR("kv_populate_acp_table failed\n");
  1226.                 return ret;
  1227.         }
  1228.         kv_program_vc(rdev);
  1229. #if 0
  1230.         kv_initialize_hardware_cac_manager(rdev);
  1231. #endif
  1232.         kv_start_am(rdev);
  1233.         if (pi->enable_auto_thermal_throttling) {
  1234.                 ret = kv_enable_auto_thermal_throttling(rdev);
  1235.                 if (ret) {
  1236.                         DRM_ERROR("kv_enable_auto_thermal_throttling failed\n");
  1237.                         return ret;
  1238.                 }
  1239.         }
  1240.         ret = kv_enable_dpm_voltage_scaling(rdev);
  1241.         if (ret) {
  1242.                 DRM_ERROR("kv_enable_dpm_voltage_scaling failed\n");
  1243.                 return ret;
  1244.         }
  1245.         ret = kv_set_dpm_interval(rdev);
  1246.         if (ret) {
  1247.                 DRM_ERROR("kv_set_dpm_interval failed\n");
  1248.                 return ret;
  1249.         }
  1250.         ret = kv_set_dpm_boot_state(rdev);
  1251.         if (ret) {
  1252.                 DRM_ERROR("kv_set_dpm_boot_state failed\n");
  1253.                 return ret;
  1254.         }
  1255.         ret = kv_enable_ulv(rdev, true);
  1256.         if (ret) {
  1257.                 DRM_ERROR("kv_enable_ulv failed\n");
  1258.                 return ret;
  1259.         }
  1260.         kv_start_dpm(rdev);
  1261.         ret = kv_enable_didt(rdev, true);
  1262.         if (ret) {
  1263.                 DRM_ERROR("kv_enable_didt failed\n");
  1264.                 return ret;
  1265.         }
  1266.         ret = kv_enable_smc_cac(rdev, true);
  1267.         if (ret) {
  1268.                 DRM_ERROR("kv_enable_smc_cac failed\n");
  1269.                 return ret;
  1270.         }
  1271.  
  1272.         kv_reset_acp_boot_level(rdev);
  1273.  
  1274.         ret = kv_smc_bapm_enable(rdev, false);
  1275.         if (ret) {
  1276.                 DRM_ERROR("kv_smc_bapm_enable failed\n");
  1277.                 return ret;
  1278.         }
  1279.  
  1280.         kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
  1281.  
  1282.         return ret;
  1283. }
  1284.  
  1285. int kv_dpm_late_enable(struct radeon_device *rdev)
  1286. {
  1287.         int ret = 0;
  1288.  
  1289.         if (rdev->irq.installed &&
  1290.             r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
  1291.                 ret = kv_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
  1292.                 if (ret) {
  1293.                         DRM_ERROR("kv_set_thermal_temperature_range failed\n");
  1294.                         return ret;
  1295.                 }
  1296.                 kv_enable_thermal_int(rdev, true);
  1297.         }
  1298.  
  1299.         /* powerdown unused blocks for now */
  1300.         kv_dpm_powergate_acp(rdev, true);
  1301.         kv_dpm_powergate_samu(rdev, true);
  1302.         kv_dpm_powergate_vce(rdev, true);
  1303.         kv_dpm_powergate_uvd(rdev, true);
  1304.  
  1305.         return ret;
  1306. }
  1307.  
  1308. void kv_dpm_disable(struct radeon_device *rdev)
  1309. {
  1310.         kv_smc_bapm_enable(rdev, false);
  1311.  
  1312.         if (rdev->family == CHIP_MULLINS)
  1313.                 kv_enable_nb_dpm(rdev, false);
  1314.  
  1315.         /* powerup blocks */
  1316.         kv_dpm_powergate_acp(rdev, false);
  1317.         kv_dpm_powergate_samu(rdev, false);
  1318.         kv_dpm_powergate_vce(rdev, false);
  1319.         kv_dpm_powergate_uvd(rdev, false);
  1320.  
  1321.         kv_enable_smc_cac(rdev, false);
  1322.         kv_enable_didt(rdev, false);
  1323.         kv_clear_vc(rdev);
  1324.         kv_stop_dpm(rdev);
  1325.         kv_enable_ulv(rdev, false);
  1326.         kv_reset_am(rdev);
  1327.         kv_enable_thermal_int(rdev, false);
  1328.  
  1329.         kv_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
  1330. }
  1331.  
  1332. #if 0
  1333. static int kv_write_smc_soft_register(struct radeon_device *rdev,
  1334.                                       u16 reg_offset, u32 value)
  1335. {
  1336.         struct kv_power_info *pi = kv_get_pi(rdev);
  1337.  
  1338.         return kv_copy_bytes_to_smc(rdev, pi->soft_regs_start + reg_offset,
  1339.                                     (u8 *)&value, sizeof(u16), pi->sram_end);
  1340. }
  1341.  
  1342. static int kv_read_smc_soft_register(struct radeon_device *rdev,
  1343.                                      u16 reg_offset, u32 *value)
  1344. {
  1345.         struct kv_power_info *pi = kv_get_pi(rdev);
  1346.  
  1347.         return kv_read_smc_sram_dword(rdev, pi->soft_regs_start + reg_offset,
  1348.                                       value, pi->sram_end);
  1349. }
  1350. #endif
  1351.  
  1352. static void kv_init_sclk_t(struct radeon_device *rdev)
  1353. {
  1354.         struct kv_power_info *pi = kv_get_pi(rdev);
  1355.  
  1356.         pi->low_sclk_interrupt_t = 0;
  1357. }
  1358.  
  1359. static int kv_init_fps_limits(struct radeon_device *rdev)
  1360. {
  1361.         struct kv_power_info *pi = kv_get_pi(rdev);
  1362.         int ret = 0;
  1363.  
  1364.         if (pi->caps_fps) {
  1365.                 u16 tmp;
  1366.  
  1367.                 tmp = 45;
  1368.                 pi->fps_high_t = cpu_to_be16(tmp);
  1369.                 ret = kv_copy_bytes_to_smc(rdev,
  1370.                                            pi->dpm_table_start +
  1371.                                            offsetof(SMU7_Fusion_DpmTable, FpsHighT),
  1372.                                            (u8 *)&pi->fps_high_t,
  1373.                                            sizeof(u16), pi->sram_end);
  1374.  
  1375.                 tmp = 30;
  1376.                 pi->fps_low_t = cpu_to_be16(tmp);
  1377.  
  1378.                 ret = kv_copy_bytes_to_smc(rdev,
  1379.                                            pi->dpm_table_start +
  1380.                                            offsetof(SMU7_Fusion_DpmTable, FpsLowT),
  1381.                                            (u8 *)&pi->fps_low_t,
  1382.                                            sizeof(u16), pi->sram_end);
  1383.  
  1384.         }
  1385.         return ret;
  1386. }
  1387.  
  1388. static void kv_init_powergate_state(struct radeon_device *rdev)
  1389. {
  1390.         struct kv_power_info *pi = kv_get_pi(rdev);
  1391.  
  1392.         pi->uvd_power_gated = false;
  1393.         pi->vce_power_gated = false;
  1394.         pi->samu_power_gated = false;
  1395.         pi->acp_power_gated = false;
  1396.  
  1397. }
  1398.  
  1399. static int kv_enable_uvd_dpm(struct radeon_device *rdev, bool enable)
  1400. {
  1401.         return kv_notify_message_to_smu(rdev, enable ?
  1402.                                         PPSMC_MSG_UVDDPM_Enable : PPSMC_MSG_UVDDPM_Disable);
  1403. }
  1404.  
  1405. static int kv_enable_vce_dpm(struct radeon_device *rdev, bool enable)
  1406. {
  1407.         return kv_notify_message_to_smu(rdev, enable ?
  1408.                                         PPSMC_MSG_VCEDPM_Enable : PPSMC_MSG_VCEDPM_Disable);
  1409. }
  1410.  
  1411. static int kv_enable_samu_dpm(struct radeon_device *rdev, bool enable)
  1412. {
  1413.         return kv_notify_message_to_smu(rdev, enable ?
  1414.                                         PPSMC_MSG_SAMUDPM_Enable : PPSMC_MSG_SAMUDPM_Disable);
  1415. }
  1416.  
  1417. static int kv_enable_acp_dpm(struct radeon_device *rdev, bool enable)
  1418. {
  1419.         return kv_notify_message_to_smu(rdev, enable ?
  1420.                                         PPSMC_MSG_ACPDPM_Enable : PPSMC_MSG_ACPDPM_Disable);
  1421. }
  1422.  
  1423. static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate)
  1424. {
  1425.         struct kv_power_info *pi = kv_get_pi(rdev);
  1426.         struct radeon_uvd_clock_voltage_dependency_table *table =
  1427.                 &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
  1428.         int ret;
  1429.         u32 mask;
  1430.  
  1431.         if (!gate) {
  1432.                 if (table->count)
  1433.                         pi->uvd_boot_level = table->count - 1;
  1434.                 else
  1435.                         pi->uvd_boot_level = 0;
  1436.  
  1437.                 if (!pi->caps_uvd_dpm || pi->caps_stable_p_state) {
  1438.                         mask = 1 << pi->uvd_boot_level;
  1439.                 } else {
  1440.                         mask = 0x1f;
  1441.                 }
  1442.  
  1443.                 ret = kv_copy_bytes_to_smc(rdev,
  1444.                                            pi->dpm_table_start +
  1445.                                            offsetof(SMU7_Fusion_DpmTable, UvdBootLevel),
  1446.                                            (uint8_t *)&pi->uvd_boot_level,
  1447.                                            sizeof(u8), pi->sram_end);
  1448.                 if (ret)
  1449.                         return ret;
  1450.  
  1451.                 kv_send_msg_to_smc_with_parameter(rdev,
  1452.                                                   PPSMC_MSG_UVDDPM_SetEnabledMask,
  1453.                                                   mask);
  1454.         }
  1455.  
  1456.         return kv_enable_uvd_dpm(rdev, !gate);
  1457. }
  1458.  
  1459. static u8 kv_get_vce_boot_level(struct radeon_device *rdev, u32 evclk)
  1460. {
  1461.         u8 i;
  1462.         struct radeon_vce_clock_voltage_dependency_table *table =
  1463.                 &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
  1464.  
  1465.         for (i = 0; i < table->count; i++) {
  1466.                 if (table->entries[i].evclk >= evclk)
  1467.                         break;
  1468.         }
  1469.  
  1470.         return i;
  1471. }
  1472.  
  1473. static int kv_update_vce_dpm(struct radeon_device *rdev,
  1474.                              struct radeon_ps *radeon_new_state,
  1475.                              struct radeon_ps *radeon_current_state)
  1476. {
  1477.         struct kv_power_info *pi = kv_get_pi(rdev);
  1478.         struct radeon_vce_clock_voltage_dependency_table *table =
  1479.                 &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
  1480.         int ret;
  1481.  
  1482.         if (radeon_new_state->evclk > 0 && radeon_current_state->evclk == 0) {
  1483.                 kv_dpm_powergate_vce(rdev, false);
  1484.                 /* turn the clocks on when encoding */
  1485.                 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, false);
  1486.                 if (pi->caps_stable_p_state)
  1487.                         pi->vce_boot_level = table->count - 1;
  1488.                 else
  1489.                         pi->vce_boot_level = kv_get_vce_boot_level(rdev, radeon_new_state->evclk);
  1490.  
  1491.                 ret = kv_copy_bytes_to_smc(rdev,
  1492.                                            pi->dpm_table_start +
  1493.                                            offsetof(SMU7_Fusion_DpmTable, VceBootLevel),
  1494.                                            (u8 *)&pi->vce_boot_level,
  1495.                                            sizeof(u8),
  1496.                                            pi->sram_end);
  1497.                 if (ret)
  1498.                         return ret;
  1499.  
  1500.                 if (pi->caps_stable_p_state)
  1501.                         kv_send_msg_to_smc_with_parameter(rdev,
  1502.                                                           PPSMC_MSG_VCEDPM_SetEnabledMask,
  1503.                                                           (1 << pi->vce_boot_level));
  1504.  
  1505.                 kv_enable_vce_dpm(rdev, true);
  1506.         } else if (radeon_new_state->evclk == 0 && radeon_current_state->evclk > 0) {
  1507.                 kv_enable_vce_dpm(rdev, false);
  1508.                 /* turn the clocks off when not encoding */
  1509.                 cik_update_cg(rdev, RADEON_CG_BLOCK_VCE, true);
  1510.                 kv_dpm_powergate_vce(rdev, true);
  1511.         }
  1512.  
  1513.         return 0;
  1514. }
  1515.  
  1516. static int kv_update_samu_dpm(struct radeon_device *rdev, bool gate)
  1517. {
  1518.         struct kv_power_info *pi = kv_get_pi(rdev);
  1519.         struct radeon_clock_voltage_dependency_table *table =
  1520.                 &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
  1521.         int ret;
  1522.  
  1523.         if (!gate) {
  1524.                 if (pi->caps_stable_p_state)
  1525.                         pi->samu_boot_level = table->count - 1;
  1526.                 else
  1527.                         pi->samu_boot_level = 0;
  1528.  
  1529.                 ret = kv_copy_bytes_to_smc(rdev,
  1530.                                            pi->dpm_table_start +
  1531.                                            offsetof(SMU7_Fusion_DpmTable, SamuBootLevel),
  1532.                                            (u8 *)&pi->samu_boot_level,
  1533.                                            sizeof(u8),
  1534.                                            pi->sram_end);
  1535.                 if (ret)
  1536.                         return ret;
  1537.  
  1538.                 if (pi->caps_stable_p_state)
  1539.                         kv_send_msg_to_smc_with_parameter(rdev,
  1540.                                                           PPSMC_MSG_SAMUDPM_SetEnabledMask,
  1541.                                                           (1 << pi->samu_boot_level));
  1542.         }
  1543.  
  1544.         return kv_enable_samu_dpm(rdev, !gate);
  1545. }
  1546.  
  1547. static u8 kv_get_acp_boot_level(struct radeon_device *rdev)
  1548. {
  1549.         u8 i;
  1550.         struct radeon_clock_voltage_dependency_table *table =
  1551.                 &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
  1552.  
  1553.         for (i = 0; i < table->count; i++) {
  1554.                 if (table->entries[i].clk >= 0) /* XXX */
  1555.                         break;
  1556.         }
  1557.  
  1558.         if (i >= table->count)
  1559.                 i = table->count - 1;
  1560.  
  1561.         return i;
  1562. }
  1563.  
  1564. static void kv_update_acp_boot_level(struct radeon_device *rdev)
  1565. {
  1566.         struct kv_power_info *pi = kv_get_pi(rdev);
  1567.         u8 acp_boot_level;
  1568.  
  1569.         if (!pi->caps_stable_p_state) {
  1570.                 acp_boot_level = kv_get_acp_boot_level(rdev);
  1571.                 if (acp_boot_level != pi->acp_boot_level) {
  1572.                         pi->acp_boot_level = acp_boot_level;
  1573.                         kv_send_msg_to_smc_with_parameter(rdev,
  1574.                                                           PPSMC_MSG_ACPDPM_SetEnabledMask,
  1575.                                                           (1 << pi->acp_boot_level));
  1576.                 }
  1577.         }
  1578. }
  1579.  
  1580. static int kv_update_acp_dpm(struct radeon_device *rdev, bool gate)
  1581. {
  1582.         struct kv_power_info *pi = kv_get_pi(rdev);
  1583.         struct radeon_clock_voltage_dependency_table *table =
  1584.                 &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
  1585.         int ret;
  1586.  
  1587.         if (!gate) {
  1588.                 if (pi->caps_stable_p_state)
  1589.                         pi->acp_boot_level = table->count - 1;
  1590.                 else
  1591.                         pi->acp_boot_level = kv_get_acp_boot_level(rdev);
  1592.  
  1593.                 ret = kv_copy_bytes_to_smc(rdev,
  1594.                                            pi->dpm_table_start +
  1595.                                            offsetof(SMU7_Fusion_DpmTable, AcpBootLevel),
  1596.                                            (u8 *)&pi->acp_boot_level,
  1597.                                            sizeof(u8),
  1598.                                            pi->sram_end);
  1599.                 if (ret)
  1600.                         return ret;
  1601.  
  1602.                 if (pi->caps_stable_p_state)
  1603.                         kv_send_msg_to_smc_with_parameter(rdev,
  1604.                                                           PPSMC_MSG_ACPDPM_SetEnabledMask,
  1605.                                                           (1 << pi->acp_boot_level));
  1606.         }
  1607.  
  1608.         return kv_enable_acp_dpm(rdev, !gate);
  1609. }
  1610.  
  1611. void kv_dpm_powergate_uvd(struct radeon_device *rdev, bool gate)
  1612. {
  1613.         struct kv_power_info *pi = kv_get_pi(rdev);
  1614.  
  1615.         if (pi->uvd_power_gated == gate)
  1616.                 return;
  1617.  
  1618.         pi->uvd_power_gated = gate;
  1619.  
  1620.         if (gate) {
  1621.                 if (pi->caps_uvd_pg) {
  1622.                         uvd_v1_0_stop(rdev);
  1623.                         cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
  1624.                 }
  1625.                 kv_update_uvd_dpm(rdev, gate);
  1626.                 if (pi->caps_uvd_pg)
  1627.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerOFF);
  1628.         } else {
  1629.                 if (pi->caps_uvd_pg) {
  1630.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_UVDPowerON);
  1631.                         uvd_v4_2_resume(rdev);
  1632.                         uvd_v1_0_start(rdev);
  1633.                         cik_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
  1634.                 }
  1635.                 kv_update_uvd_dpm(rdev, gate);
  1636.         }
  1637. }
  1638.  
  1639. static void kv_dpm_powergate_vce(struct radeon_device *rdev, bool gate)
  1640. {
  1641.         struct kv_power_info *pi = kv_get_pi(rdev);
  1642.  
  1643.         if (pi->vce_power_gated == gate)
  1644.                 return;
  1645.  
  1646.         pi->vce_power_gated = gate;
  1647.  
  1648.         if (gate) {
  1649.                 if (pi->caps_vce_pg) {
  1650.                         /* XXX do we need a vce_v1_0_stop() ?  */
  1651.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerOFF);
  1652.                 }
  1653.         } else {
  1654.                 if (pi->caps_vce_pg) {
  1655.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_VCEPowerON);
  1656.                         vce_v2_0_resume(rdev);
  1657.                         vce_v1_0_start(rdev);
  1658.                 }
  1659.         }
  1660. }
  1661.  
  1662. static void kv_dpm_powergate_samu(struct radeon_device *rdev, bool gate)
  1663. {
  1664.         struct kv_power_info *pi = kv_get_pi(rdev);
  1665.  
  1666.         if (pi->samu_power_gated == gate)
  1667.                 return;
  1668.  
  1669.         pi->samu_power_gated = gate;
  1670.  
  1671.         if (gate) {
  1672.                 kv_update_samu_dpm(rdev, true);
  1673.                 if (pi->caps_samu_pg)
  1674.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_SAMPowerOFF);
  1675.         } else {
  1676.                 if (pi->caps_samu_pg)
  1677.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_SAMPowerON);
  1678.                 kv_update_samu_dpm(rdev, false);
  1679.         }
  1680. }
  1681.  
  1682. static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate)
  1683. {
  1684.         struct kv_power_info *pi = kv_get_pi(rdev);
  1685.  
  1686.         if (pi->acp_power_gated == gate)
  1687.                 return;
  1688.  
  1689.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  1690.                 return;
  1691.  
  1692.         pi->acp_power_gated = gate;
  1693.  
  1694.         if (gate) {
  1695.                 kv_update_acp_dpm(rdev, true);
  1696.                 if (pi->caps_acp_pg)
  1697.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_ACPPowerOFF);
  1698.         } else {
  1699.                 if (pi->caps_acp_pg)
  1700.                         kv_notify_message_to_smu(rdev, PPSMC_MSG_ACPPowerON);
  1701.                 kv_update_acp_dpm(rdev, false);
  1702.         }
  1703. }
  1704.  
  1705. static void kv_set_valid_clock_range(struct radeon_device *rdev,
  1706.                                      struct radeon_ps *new_rps)
  1707. {
  1708.         struct kv_ps *new_ps = kv_get_ps(new_rps);
  1709.         struct kv_power_info *pi = kv_get_pi(rdev);
  1710.         u32 i;
  1711.         struct radeon_clock_voltage_dependency_table *table =
  1712.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  1713.  
  1714.         if (table && table->count) {
  1715.                 for (i = 0; i < pi->graphics_dpm_level_count; i++) {
  1716.                         if ((table->entries[i].clk >= new_ps->levels[0].sclk) ||
  1717.                             (i == (pi->graphics_dpm_level_count - 1))) {
  1718.                                 pi->lowest_valid = i;
  1719.                                 break;
  1720.                         }
  1721.                 }
  1722.  
  1723.                 for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
  1724.                         if (table->entries[i].clk <= new_ps->levels[new_ps->num_levels - 1].sclk)
  1725.                                 break;
  1726.                 }
  1727.                 pi->highest_valid = i;
  1728.  
  1729.                 if (pi->lowest_valid > pi->highest_valid) {
  1730.                         if ((new_ps->levels[0].sclk - table->entries[pi->highest_valid].clk) >
  1731.                             (table->entries[pi->lowest_valid].clk - new_ps->levels[new_ps->num_levels - 1].sclk))
  1732.                                 pi->highest_valid = pi->lowest_valid;
  1733.                         else
  1734.                                 pi->lowest_valid =  pi->highest_valid;
  1735.                 }
  1736.         } else {
  1737.                 struct sumo_sclk_voltage_mapping_table *table =
  1738.                         &pi->sys_info.sclk_voltage_mapping_table;
  1739.  
  1740.                 for (i = 0; i < (int)pi->graphics_dpm_level_count; i++) {
  1741.                         if (table->entries[i].sclk_frequency >= new_ps->levels[0].sclk ||
  1742.                             i == (int)(pi->graphics_dpm_level_count - 1)) {
  1743.                                 pi->lowest_valid = i;
  1744.                                 break;
  1745.                         }
  1746.                 }
  1747.  
  1748.                 for (i = pi->graphics_dpm_level_count - 1; i > 0; i--) {
  1749.                         if (table->entries[i].sclk_frequency <=
  1750.                             new_ps->levels[new_ps->num_levels - 1].sclk)
  1751.                                 break;
  1752.                 }
  1753.                 pi->highest_valid = i;
  1754.  
  1755.                 if (pi->lowest_valid > pi->highest_valid) {
  1756.                         if ((new_ps->levels[0].sclk -
  1757.                              table->entries[pi->highest_valid].sclk_frequency) >
  1758.                             (table->entries[pi->lowest_valid].sclk_frequency -
  1759.                              new_ps->levels[new_ps->num_levels -1].sclk))
  1760.                                 pi->highest_valid = pi->lowest_valid;
  1761.                         else
  1762.                                 pi->lowest_valid =  pi->highest_valid;
  1763.                 }
  1764.         }
  1765. }
  1766.  
  1767. static int kv_update_dfs_bypass_settings(struct radeon_device *rdev,
  1768.                                          struct radeon_ps *new_rps)
  1769. {
  1770.         struct kv_ps *new_ps = kv_get_ps(new_rps);
  1771.         struct kv_power_info *pi = kv_get_pi(rdev);
  1772.         int ret = 0;
  1773.         u8 clk_bypass_cntl;
  1774.  
  1775.         if (pi->caps_enable_dfs_bypass) {
  1776.                 clk_bypass_cntl = new_ps->need_dfs_bypass ?
  1777.                         pi->graphics_level[pi->graphics_boot_level].ClkBypassCntl : 0;
  1778.                 ret = kv_copy_bytes_to_smc(rdev,
  1779.                                            (pi->dpm_table_start +
  1780.                                             offsetof(SMU7_Fusion_DpmTable, GraphicsLevel) +
  1781.                                             (pi->graphics_boot_level * sizeof(SMU7_Fusion_GraphicsLevel)) +
  1782.                                             offsetof(SMU7_Fusion_GraphicsLevel, ClkBypassCntl)),
  1783.                                            &clk_bypass_cntl,
  1784.                                            sizeof(u8), pi->sram_end);
  1785.         }
  1786.  
  1787.         return ret;
  1788. }
  1789.  
  1790. static int kv_enable_nb_dpm(struct radeon_device *rdev,
  1791.                             bool enable)
  1792. {
  1793.         struct kv_power_info *pi = kv_get_pi(rdev);
  1794.         int ret = 0;
  1795.  
  1796.         if (enable) {
  1797.                 if (pi->enable_nb_dpm && !pi->nb_dpm_enabled) {
  1798.                         ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Enable);
  1799.                         if (ret == 0)
  1800.                                 pi->nb_dpm_enabled = true;
  1801.                 }
  1802.         } else {
  1803.                 if (pi->enable_nb_dpm && pi->nb_dpm_enabled) {
  1804.                         ret = kv_notify_message_to_smu(rdev, PPSMC_MSG_NBDPM_Disable);
  1805.                         if (ret == 0)
  1806.                                 pi->nb_dpm_enabled = false;
  1807.                 }
  1808.         }
  1809.  
  1810.         return ret;
  1811. }
  1812.  
  1813. int kv_dpm_force_performance_level(struct radeon_device *rdev,
  1814.                                    enum radeon_dpm_forced_level level)
  1815. {
  1816.         int ret;
  1817.  
  1818.         if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
  1819.                 ret = kv_force_dpm_highest(rdev);
  1820.                 if (ret)
  1821.                         return ret;
  1822.         } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
  1823.                 ret = kv_force_dpm_lowest(rdev);
  1824.                 if (ret)
  1825.                         return ret;
  1826.         } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
  1827.                 ret = kv_unforce_levels(rdev);
  1828.                 if (ret)
  1829.                         return ret;
  1830.         }
  1831.  
  1832.         rdev->pm.dpm.forced_level = level;
  1833.  
  1834.         return 0;
  1835. }
  1836.  
  1837. int kv_dpm_pre_set_power_state(struct radeon_device *rdev)
  1838. {
  1839.         struct kv_power_info *pi = kv_get_pi(rdev);
  1840.         struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
  1841.         struct radeon_ps *new_ps = &requested_ps;
  1842.  
  1843.         kv_update_requested_ps(rdev, new_ps);
  1844.  
  1845.         kv_apply_state_adjust_rules(rdev,
  1846.                                     &pi->requested_rps,
  1847.                                     &pi->current_rps);
  1848.  
  1849.         return 0;
  1850. }
  1851.  
  1852. int kv_dpm_set_power_state(struct radeon_device *rdev)
  1853. {
  1854.         struct kv_power_info *pi = kv_get_pi(rdev);
  1855.         struct radeon_ps *new_ps = &pi->requested_rps;
  1856.         struct radeon_ps *old_ps = &pi->current_rps;
  1857.         int ret;
  1858.  
  1859.         if (pi->bapm_enable) {
  1860.                 ret = kv_smc_bapm_enable(rdev, rdev->pm.dpm.ac_power);
  1861.                 if (ret) {
  1862.                         DRM_ERROR("kv_smc_bapm_enable failed\n");
  1863.                         return ret;
  1864.                 }
  1865.         }
  1866.  
  1867.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
  1868.                 if (pi->enable_dpm) {
  1869.                         kv_set_valid_clock_range(rdev, new_ps);
  1870.                         kv_update_dfs_bypass_settings(rdev, new_ps);
  1871.                         ret = kv_calculate_ds_divider(rdev);
  1872.                         if (ret) {
  1873.                                 DRM_ERROR("kv_calculate_ds_divider failed\n");
  1874.                                 return ret;
  1875.                         }
  1876.                         kv_calculate_nbps_level_settings(rdev);
  1877.                         kv_calculate_dpm_settings(rdev);
  1878.                         kv_force_lowest_valid(rdev);
  1879.                         kv_enable_new_levels(rdev);
  1880.                         kv_upload_dpm_settings(rdev);
  1881.                         kv_program_nbps_index_settings(rdev, new_ps);
  1882.                         kv_unforce_levels(rdev);
  1883.                         kv_set_enabled_levels(rdev);
  1884.                         kv_force_lowest_valid(rdev);
  1885.                         kv_unforce_levels(rdev);
  1886.  
  1887.                         ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
  1888.                         if (ret) {
  1889.                                 DRM_ERROR("kv_update_vce_dpm failed\n");
  1890.                                 return ret;
  1891.                         }
  1892.                         kv_update_sclk_t(rdev);
  1893.                         if (rdev->family == CHIP_MULLINS)
  1894.                                 kv_enable_nb_dpm(rdev, true);
  1895.                 }
  1896.         } else {
  1897.                 if (pi->enable_dpm) {
  1898.                         kv_set_valid_clock_range(rdev, new_ps);
  1899.                         kv_update_dfs_bypass_settings(rdev, new_ps);
  1900.                         ret = kv_calculate_ds_divider(rdev);
  1901.                         if (ret) {
  1902.                                 DRM_ERROR("kv_calculate_ds_divider failed\n");
  1903.                                 return ret;
  1904.                         }
  1905.                         kv_calculate_nbps_level_settings(rdev);
  1906.                         kv_calculate_dpm_settings(rdev);
  1907.                         kv_freeze_sclk_dpm(rdev, true);
  1908.                         kv_upload_dpm_settings(rdev);
  1909.                         kv_program_nbps_index_settings(rdev, new_ps);
  1910.                         kv_freeze_sclk_dpm(rdev, false);
  1911.                         kv_set_enabled_levels(rdev);
  1912.                         ret = kv_update_vce_dpm(rdev, new_ps, old_ps);
  1913.                         if (ret) {
  1914.                                 DRM_ERROR("kv_update_vce_dpm failed\n");
  1915.                                 return ret;
  1916.                         }
  1917.                         kv_update_acp_boot_level(rdev);
  1918.                         kv_update_sclk_t(rdev);
  1919.                         kv_enable_nb_dpm(rdev, true);
  1920.                 }
  1921.         }
  1922.  
  1923.         return 0;
  1924. }
  1925.  
  1926. void kv_dpm_post_set_power_state(struct radeon_device *rdev)
  1927. {
  1928.         struct kv_power_info *pi = kv_get_pi(rdev);
  1929.         struct radeon_ps *new_ps = &pi->requested_rps;
  1930.  
  1931.         kv_update_current_ps(rdev, new_ps);
  1932. }
  1933.  
  1934. void kv_dpm_setup_asic(struct radeon_device *rdev)
  1935. {
  1936.         sumo_take_smu_control(rdev, true);
  1937.         kv_init_powergate_state(rdev);
  1938.         kv_init_sclk_t(rdev);
  1939. }
  1940.  
  1941. #if 0
  1942. void kv_dpm_reset_asic(struct radeon_device *rdev)
  1943. {
  1944.         struct kv_power_info *pi = kv_get_pi(rdev);
  1945.  
  1946.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
  1947.                 kv_force_lowest_valid(rdev);
  1948.                 kv_init_graphics_levels(rdev);
  1949.                 kv_program_bootup_state(rdev);
  1950.                 kv_upload_dpm_settings(rdev);
  1951.                 kv_force_lowest_valid(rdev);
  1952.                 kv_unforce_levels(rdev);
  1953.         } else {
  1954.                 kv_init_graphics_levels(rdev);
  1955.                 kv_program_bootup_state(rdev);
  1956.                 kv_freeze_sclk_dpm(rdev, true);
  1957.                 kv_upload_dpm_settings(rdev);
  1958.                 kv_freeze_sclk_dpm(rdev, false);
  1959.                 kv_set_enabled_level(rdev, pi->graphics_boot_level);
  1960.         }
  1961. }
  1962. #endif
  1963.  
  1964. //XXX use sumo_dpm_display_configuration_changed
  1965.  
  1966. static void kv_construct_max_power_limits_table(struct radeon_device *rdev,
  1967.                                                 struct radeon_clock_and_voltage_limits *table)
  1968. {
  1969.         struct kv_power_info *pi = kv_get_pi(rdev);
  1970.  
  1971.         if (pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries > 0) {
  1972.                 int idx = pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries - 1;
  1973.                 table->sclk =
  1974.                         pi->sys_info.sclk_voltage_mapping_table.entries[idx].sclk_frequency;
  1975.                 table->vddc =
  1976.                         kv_convert_2bit_index_to_voltage(rdev,
  1977.                                                          pi->sys_info.sclk_voltage_mapping_table.entries[idx].vid_2bit);
  1978.         }
  1979.  
  1980.         table->mclk = pi->sys_info.nbp_memory_clock[0];
  1981. }
  1982.  
  1983. static void kv_patch_voltage_values(struct radeon_device *rdev)
  1984. {
  1985.         int i;
  1986.         struct radeon_uvd_clock_voltage_dependency_table *uvd_table =
  1987.                 &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table;
  1988.         struct radeon_vce_clock_voltage_dependency_table *vce_table =
  1989.                 &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
  1990.         struct radeon_clock_voltage_dependency_table *samu_table =
  1991.                 &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table;
  1992.         struct radeon_clock_voltage_dependency_table *acp_table =
  1993.                 &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table;
  1994.  
  1995.         if (uvd_table->count) {
  1996.                 for (i = 0; i < uvd_table->count; i++)
  1997.                         uvd_table->entries[i].v =
  1998.                                 kv_convert_8bit_index_to_voltage(rdev,
  1999.                                                                  uvd_table->entries[i].v);
  2000.         }
  2001.  
  2002.         if (vce_table->count) {
  2003.                 for (i = 0; i < vce_table->count; i++)
  2004.                         vce_table->entries[i].v =
  2005.                                 kv_convert_8bit_index_to_voltage(rdev,
  2006.                                                                  vce_table->entries[i].v);
  2007.         }
  2008.  
  2009.         if (samu_table->count) {
  2010.                 for (i = 0; i < samu_table->count; i++)
  2011.                         samu_table->entries[i].v =
  2012.                                 kv_convert_8bit_index_to_voltage(rdev,
  2013.                                                                  samu_table->entries[i].v);
  2014.         }
  2015.  
  2016.         if (acp_table->count) {
  2017.                 for (i = 0; i < acp_table->count; i++)
  2018.                         acp_table->entries[i].v =
  2019.                                 kv_convert_8bit_index_to_voltage(rdev,
  2020.                                                                  acp_table->entries[i].v);
  2021.         }
  2022.  
  2023. }
  2024.  
  2025. static void kv_construct_boot_state(struct radeon_device *rdev)
  2026. {
  2027.         struct kv_power_info *pi = kv_get_pi(rdev);
  2028.  
  2029.         pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
  2030.         pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
  2031.         pi->boot_pl.ds_divider_index = 0;
  2032.         pi->boot_pl.ss_divider_index = 0;
  2033.         pi->boot_pl.allow_gnb_slow = 1;
  2034.         pi->boot_pl.force_nbp_state = 0;
  2035.         pi->boot_pl.display_wm = 0;
  2036.         pi->boot_pl.vce_wm = 0;
  2037. }
  2038.  
  2039. static int kv_force_dpm_highest(struct radeon_device *rdev)
  2040. {
  2041.         int ret;
  2042.         u32 enable_mask, i;
  2043.  
  2044.         ret = kv_dpm_get_enable_mask(rdev, &enable_mask);
  2045.         if (ret)
  2046.                 return ret;
  2047.  
  2048.         for (i = SMU7_MAX_LEVELS_GRAPHICS - 1; i > 0; i--) {
  2049.                 if (enable_mask & (1 << i))
  2050.                         break;
  2051.         }
  2052.  
  2053.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  2054.                 return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
  2055.         else
  2056.                 return kv_set_enabled_level(rdev, i);
  2057. }
  2058.  
  2059. static int kv_force_dpm_lowest(struct radeon_device *rdev)
  2060. {
  2061.         int ret;
  2062.         u32 enable_mask, i;
  2063.  
  2064.         ret = kv_dpm_get_enable_mask(rdev, &enable_mask);
  2065.         if (ret)
  2066.                 return ret;
  2067.  
  2068.         for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) {
  2069.                 if (enable_mask & (1 << i))
  2070.                         break;
  2071.         }
  2072.  
  2073.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  2074.                 return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i);
  2075.         else
  2076.                 return kv_set_enabled_level(rdev, i);
  2077. }
  2078.  
  2079. static u8 kv_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
  2080.                                              u32 sclk, u32 min_sclk_in_sr)
  2081. {
  2082.         struct kv_power_info *pi = kv_get_pi(rdev);
  2083.         u32 i;
  2084.         u32 temp;
  2085.         u32 min = (min_sclk_in_sr > KV_MINIMUM_ENGINE_CLOCK) ?
  2086.                 min_sclk_in_sr : KV_MINIMUM_ENGINE_CLOCK;
  2087.  
  2088.         if (sclk < min)
  2089.                 return 0;
  2090.  
  2091.         if (!pi->caps_sclk_ds)
  2092.                 return 0;
  2093.  
  2094.         for (i = KV_MAX_DEEPSLEEP_DIVIDER_ID; i > 0; i--) {
  2095.                 temp = sclk / sumo_get_sleep_divider_from_id(i);
  2096.                 if (temp >= min)
  2097.                         break;
  2098.         }
  2099.  
  2100.         return (u8)i;
  2101. }
  2102.  
  2103. static int kv_get_high_voltage_limit(struct radeon_device *rdev, int *limit)
  2104. {
  2105.         struct kv_power_info *pi = kv_get_pi(rdev);
  2106.         struct radeon_clock_voltage_dependency_table *table =
  2107.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  2108.         int i;
  2109.  
  2110.         if (table && table->count) {
  2111.                 for (i = table->count - 1; i >= 0; i--) {
  2112.                         if (pi->high_voltage_t &&
  2113.                             (kv_convert_8bit_index_to_voltage(rdev, table->entries[i].v) <=
  2114.                              pi->high_voltage_t)) {
  2115.                                 *limit = i;
  2116.                                 return 0;
  2117.                         }
  2118.                 }
  2119.         } else {
  2120.                 struct sumo_sclk_voltage_mapping_table *table =
  2121.                         &pi->sys_info.sclk_voltage_mapping_table;
  2122.  
  2123.                 for (i = table->num_max_dpm_entries - 1; i >= 0; i--) {
  2124.                         if (pi->high_voltage_t &&
  2125.                             (kv_convert_2bit_index_to_voltage(rdev, table->entries[i].vid_2bit) <=
  2126.                              pi->high_voltage_t)) {
  2127.                                 *limit = i;
  2128.                                 return 0;
  2129.                         }
  2130.                 }
  2131.         }
  2132.  
  2133.         *limit = 0;
  2134.         return 0;
  2135. }
  2136.  
  2137. static void kv_apply_state_adjust_rules(struct radeon_device *rdev,
  2138.                                         struct radeon_ps *new_rps,
  2139.                                         struct radeon_ps *old_rps)
  2140. {
  2141.         struct kv_ps *ps = kv_get_ps(new_rps);
  2142.         struct kv_power_info *pi = kv_get_pi(rdev);
  2143.         u32 min_sclk = 10000; /* ??? */
  2144.         u32 sclk, mclk = 0;
  2145.         int i, limit;
  2146.         bool force_high;
  2147.         struct radeon_clock_voltage_dependency_table *table =
  2148.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  2149.         u32 stable_p_state_sclk = 0;
  2150.         struct radeon_clock_and_voltage_limits *max_limits =
  2151.                 &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
  2152.  
  2153.         if (new_rps->vce_active) {
  2154.                 new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
  2155.                 new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
  2156.         } else {
  2157.                 new_rps->evclk = 0;
  2158.                 new_rps->ecclk = 0;
  2159.         }
  2160.  
  2161.         mclk = max_limits->mclk;
  2162.         sclk = min_sclk;
  2163.  
  2164.         if (pi->caps_stable_p_state) {
  2165.                 stable_p_state_sclk = (max_limits->sclk * 75) / 100;
  2166.  
  2167.                 for (i = table->count - 1; i >= 0; i++) {
  2168.                         if (stable_p_state_sclk >= table->entries[i].clk) {
  2169.                                 stable_p_state_sclk = table->entries[i].clk;
  2170.                                 break;
  2171.                         }
  2172.                 }
  2173.  
  2174.                 if (i > 0)
  2175.                         stable_p_state_sclk = table->entries[0].clk;
  2176.  
  2177.                 sclk = stable_p_state_sclk;
  2178.         }
  2179.  
  2180.         if (new_rps->vce_active) {
  2181.                 if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
  2182.                         sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
  2183.         }
  2184.  
  2185.         ps->need_dfs_bypass = true;
  2186.  
  2187.         for (i = 0; i < ps->num_levels; i++) {
  2188.                 if (ps->levels[i].sclk < sclk)
  2189.                         ps->levels[i].sclk = sclk;
  2190.         }
  2191.  
  2192.         if (table && table->count) {
  2193.                 for (i = 0; i < ps->num_levels; i++) {
  2194.                         if (pi->high_voltage_t &&
  2195.                             (pi->high_voltage_t <
  2196.                              kv_convert_8bit_index_to_voltage(rdev, ps->levels[i].vddc_index))) {
  2197.                                 kv_get_high_voltage_limit(rdev, &limit);
  2198.                                 ps->levels[i].sclk = table->entries[limit].clk;
  2199.                         }
  2200.                 }
  2201.         } else {
  2202.                 struct sumo_sclk_voltage_mapping_table *table =
  2203.                         &pi->sys_info.sclk_voltage_mapping_table;
  2204.  
  2205.                 for (i = 0; i < ps->num_levels; i++) {
  2206.                         if (pi->high_voltage_t &&
  2207.                             (pi->high_voltage_t <
  2208.                              kv_convert_8bit_index_to_voltage(rdev, ps->levels[i].vddc_index))) {
  2209.                                 kv_get_high_voltage_limit(rdev, &limit);
  2210.                                 ps->levels[i].sclk = table->entries[limit].sclk_frequency;
  2211.                         }
  2212.                 }
  2213.         }
  2214.  
  2215.         if (pi->caps_stable_p_state) {
  2216.                 for (i = 0; i < ps->num_levels; i++) {
  2217.                         ps->levels[i].sclk = stable_p_state_sclk;
  2218.                 }
  2219.         }
  2220.  
  2221.         pi->video_start = new_rps->dclk || new_rps->vclk ||
  2222.                 new_rps->evclk || new_rps->ecclk;
  2223.  
  2224.         if ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
  2225.             ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)
  2226.                 pi->battery_state = true;
  2227.         else
  2228.                 pi->battery_state = false;
  2229.  
  2230.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
  2231.                 ps->dpm0_pg_nb_ps_lo = 0x1;
  2232.                 ps->dpm0_pg_nb_ps_hi = 0x0;
  2233.                 ps->dpmx_nb_ps_lo = 0x1;
  2234.                 ps->dpmx_nb_ps_hi = 0x0;
  2235.         } else {
  2236.                 ps->dpm0_pg_nb_ps_lo = 0x3;
  2237.                 ps->dpm0_pg_nb_ps_hi = 0x0;
  2238.                 ps->dpmx_nb_ps_lo = 0x3;
  2239.                 ps->dpmx_nb_ps_hi = 0x0;
  2240.  
  2241.                 if (pi->sys_info.nb_dpm_enable) {
  2242.                         force_high = (mclk >= pi->sys_info.nbp_memory_clock[3]) ||
  2243.                                 pi->video_start || (rdev->pm.dpm.new_active_crtc_count >= 3) ||
  2244.                                 pi->disable_nb_ps3_in_battery;
  2245.                         ps->dpm0_pg_nb_ps_lo = force_high ? 0x2 : 0x3;
  2246.                         ps->dpm0_pg_nb_ps_hi = 0x2;
  2247.                         ps->dpmx_nb_ps_lo = force_high ? 0x2 : 0x3;
  2248.                         ps->dpmx_nb_ps_hi = 0x2;
  2249.                 }
  2250.         }
  2251. }
  2252.  
  2253. static void kv_dpm_power_level_enabled_for_throttle(struct radeon_device *rdev,
  2254.                                                     u32 index, bool enable)
  2255. {
  2256.         struct kv_power_info *pi = kv_get_pi(rdev);
  2257.  
  2258.         pi->graphics_level[index].EnabledForThrottle = enable ? 1 : 0;
  2259. }
  2260.  
  2261. static int kv_calculate_ds_divider(struct radeon_device *rdev)
  2262. {
  2263.         struct kv_power_info *pi = kv_get_pi(rdev);
  2264.         u32 sclk_in_sr = 10000; /* ??? */
  2265.         u32 i;
  2266.  
  2267.         if (pi->lowest_valid > pi->highest_valid)
  2268.                 return -EINVAL;
  2269.  
  2270.         for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
  2271.                 pi->graphics_level[i].DeepSleepDivId =
  2272.                         kv_get_sleep_divider_id_from_clock(rdev,
  2273.                                                            be32_to_cpu(pi->graphics_level[i].SclkFrequency),
  2274.                                                            sclk_in_sr);
  2275.         }
  2276.         return 0;
  2277. }
  2278.  
  2279. static int kv_calculate_nbps_level_settings(struct radeon_device *rdev)
  2280. {
  2281.         struct kv_power_info *pi = kv_get_pi(rdev);
  2282.         u32 i;
  2283.         bool force_high;
  2284.         struct radeon_clock_and_voltage_limits *max_limits =
  2285.                 &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
  2286.         u32 mclk = max_limits->mclk;
  2287.  
  2288.         if (pi->lowest_valid > pi->highest_valid)
  2289.                 return -EINVAL;
  2290.  
  2291.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) {
  2292.                 for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
  2293.                         pi->graphics_level[i].GnbSlow = 1;
  2294.                         pi->graphics_level[i].ForceNbPs1 = 0;
  2295.                         pi->graphics_level[i].UpH = 0;
  2296.                 }
  2297.  
  2298.                 if (!pi->sys_info.nb_dpm_enable)
  2299.                         return 0;
  2300.  
  2301.                 force_high = ((mclk >= pi->sys_info.nbp_memory_clock[3]) ||
  2302.                               (rdev->pm.dpm.new_active_crtc_count >= 3) || pi->video_start);
  2303.  
  2304.                 if (force_high) {
  2305.                         for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
  2306.                                 pi->graphics_level[i].GnbSlow = 0;
  2307.                 } else {
  2308.                         if (pi->battery_state)
  2309.                                 pi->graphics_level[0].ForceNbPs1 = 1;
  2310.  
  2311.                         pi->graphics_level[1].GnbSlow = 0;
  2312.                         pi->graphics_level[2].GnbSlow = 0;
  2313.                         pi->graphics_level[3].GnbSlow = 0;
  2314.                         pi->graphics_level[4].GnbSlow = 0;
  2315.                 }
  2316.         } else {
  2317.                 for (i = pi->lowest_valid; i <= pi->highest_valid; i++) {
  2318.                         pi->graphics_level[i].GnbSlow = 1;
  2319.                         pi->graphics_level[i].ForceNbPs1 = 0;
  2320.                         pi->graphics_level[i].UpH = 0;
  2321.                 }
  2322.  
  2323.                 if (pi->sys_info.nb_dpm_enable && pi->battery_state) {
  2324.                         pi->graphics_level[pi->lowest_valid].UpH = 0x28;
  2325.                         pi->graphics_level[pi->lowest_valid].GnbSlow = 0;
  2326.                         if (pi->lowest_valid != pi->highest_valid)
  2327.                                 pi->graphics_level[pi->lowest_valid].ForceNbPs1 = 1;
  2328.                 }
  2329.         }
  2330.         return 0;
  2331. }
  2332.  
  2333. static int kv_calculate_dpm_settings(struct radeon_device *rdev)
  2334. {
  2335.         struct kv_power_info *pi = kv_get_pi(rdev);
  2336.         u32 i;
  2337.  
  2338.         if (pi->lowest_valid > pi->highest_valid)
  2339.                 return -EINVAL;
  2340.  
  2341.         for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
  2342.                 pi->graphics_level[i].DisplayWatermark = (i == pi->highest_valid) ? 1 : 0;
  2343.  
  2344.         return 0;
  2345. }
  2346.  
  2347. static void kv_init_graphics_levels(struct radeon_device *rdev)
  2348. {
  2349.         struct kv_power_info *pi = kv_get_pi(rdev);
  2350.         u32 i;
  2351.         struct radeon_clock_voltage_dependency_table *table =
  2352.                 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk;
  2353.  
  2354.         if (table && table->count) {
  2355.                 u32 vid_2bit;
  2356.  
  2357.                 pi->graphics_dpm_level_count = 0;
  2358.                 for (i = 0; i < table->count; i++) {
  2359.                         if (pi->high_voltage_t &&
  2360.                             (pi->high_voltage_t <
  2361.                              kv_convert_8bit_index_to_voltage(rdev, table->entries[i].v)))
  2362.                                 break;
  2363.  
  2364.                         kv_set_divider_value(rdev, i, table->entries[i].clk);
  2365.                         vid_2bit = kv_convert_vid7_to_vid2(rdev,
  2366.                                                            &pi->sys_info.vid_mapping_table,
  2367.                                                            table->entries[i].v);
  2368.                         kv_set_vid(rdev, i, vid_2bit);
  2369.                         kv_set_at(rdev, i, pi->at[i]);
  2370.                         kv_dpm_power_level_enabled_for_throttle(rdev, i, true);
  2371.                         pi->graphics_dpm_level_count++;
  2372.                 }
  2373.         } else {
  2374.                 struct sumo_sclk_voltage_mapping_table *table =
  2375.                         &pi->sys_info.sclk_voltage_mapping_table;
  2376.  
  2377.                 pi->graphics_dpm_level_count = 0;
  2378.                 for (i = 0; i < table->num_max_dpm_entries; i++) {
  2379.                         if (pi->high_voltage_t &&
  2380.                             pi->high_voltage_t <
  2381.                             kv_convert_2bit_index_to_voltage(rdev, table->entries[i].vid_2bit))
  2382.                                 break;
  2383.  
  2384.                         kv_set_divider_value(rdev, i, table->entries[i].sclk_frequency);
  2385.                         kv_set_vid(rdev, i, table->entries[i].vid_2bit);
  2386.                         kv_set_at(rdev, i, pi->at[i]);
  2387.                         kv_dpm_power_level_enabled_for_throttle(rdev, i, true);
  2388.                         pi->graphics_dpm_level_count++;
  2389.                 }
  2390.         }
  2391.  
  2392.         for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++)
  2393.                 kv_dpm_power_level_enable(rdev, i, false);
  2394. }
  2395.  
  2396. static void kv_enable_new_levels(struct radeon_device *rdev)
  2397. {
  2398.         struct kv_power_info *pi = kv_get_pi(rdev);
  2399.         u32 i;
  2400.  
  2401.         for (i = 0; i < SMU7_MAX_LEVELS_GRAPHICS; i++) {
  2402.                 if (i >= pi->lowest_valid && i <= pi->highest_valid)
  2403.                         kv_dpm_power_level_enable(rdev, i, true);
  2404.         }
  2405. }
  2406.  
  2407. static int kv_set_enabled_level(struct radeon_device *rdev, u32 level)
  2408. {
  2409.         u32 new_mask = (1 << level);
  2410.  
  2411.         return kv_send_msg_to_smc_with_parameter(rdev,
  2412.                                                  PPSMC_MSG_SCLKDPM_SetEnabledMask,
  2413.                                                  new_mask);
  2414. }
  2415.  
  2416. static int kv_set_enabled_levels(struct radeon_device *rdev)
  2417. {
  2418.         struct kv_power_info *pi = kv_get_pi(rdev);
  2419.         u32 i, new_mask = 0;
  2420.  
  2421.         for (i = pi->lowest_valid; i <= pi->highest_valid; i++)
  2422.                 new_mask |= (1 << i);
  2423.  
  2424.         return kv_send_msg_to_smc_with_parameter(rdev,
  2425.                                                  PPSMC_MSG_SCLKDPM_SetEnabledMask,
  2426.                                                  new_mask);
  2427. }
  2428.  
  2429. static void kv_program_nbps_index_settings(struct radeon_device *rdev,
  2430.                                            struct radeon_ps *new_rps)
  2431. {
  2432.         struct kv_ps *new_ps = kv_get_ps(new_rps);
  2433.         struct kv_power_info *pi = kv_get_pi(rdev);
  2434.         u32 nbdpmconfig1;
  2435.  
  2436.         if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  2437.                 return;
  2438.  
  2439.         if (pi->sys_info.nb_dpm_enable) {
  2440.                 nbdpmconfig1 = RREG32_SMC(NB_DPM_CONFIG_1);
  2441.                 nbdpmconfig1 &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK |
  2442.                                   DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
  2443.                 nbdpmconfig1 |= (Dpm0PgNbPsLo(new_ps->dpm0_pg_nb_ps_lo) |
  2444.                                  Dpm0PgNbPsHi(new_ps->dpm0_pg_nb_ps_hi) |
  2445.                                  DpmXNbPsLo(new_ps->dpmx_nb_ps_lo) |
  2446.                                  DpmXNbPsHi(new_ps->dpmx_nb_ps_hi));
  2447.                 WREG32_SMC(NB_DPM_CONFIG_1, nbdpmconfig1);
  2448.         }
  2449. }
  2450.  
  2451. static int kv_set_thermal_temperature_range(struct radeon_device *rdev,
  2452.                                             int min_temp, int max_temp)
  2453. {
  2454.         int low_temp = 0 * 1000;
  2455.         int high_temp = 255 * 1000;
  2456.         u32 tmp;
  2457.  
  2458.         if (low_temp < min_temp)
  2459.                 low_temp = min_temp;
  2460.         if (high_temp > max_temp)
  2461.                 high_temp = max_temp;
  2462.         if (high_temp < low_temp) {
  2463.                 DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
  2464.                 return -EINVAL;
  2465.         }
  2466.  
  2467.         tmp = RREG32_SMC(CG_THERMAL_INT_CTRL);
  2468.         tmp &= ~(DIG_THERM_INTH_MASK | DIG_THERM_INTL_MASK);
  2469.         tmp |= (DIG_THERM_INTH(49 + (high_temp / 1000)) |
  2470.                 DIG_THERM_INTL(49 + (low_temp / 1000)));
  2471.         WREG32_SMC(CG_THERMAL_INT_CTRL, tmp);
  2472.  
  2473.         rdev->pm.dpm.thermal.min_temp = low_temp;
  2474.         rdev->pm.dpm.thermal.max_temp = high_temp;
  2475.  
  2476.         return 0;
  2477. }
  2478.  
  2479. union igp_info {
  2480.         struct _ATOM_INTEGRATED_SYSTEM_INFO info;
  2481.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
  2482.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
  2483.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
  2484.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
  2485.         struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8 info_8;
  2486. };
  2487.  
  2488. static int kv_parse_sys_info_table(struct radeon_device *rdev)
  2489. {
  2490.         struct kv_power_info *pi = kv_get_pi(rdev);
  2491.         struct radeon_mode_info *mode_info = &rdev->mode_info;
  2492.         int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
  2493.         union igp_info *igp_info;
  2494.         u8 frev, crev;
  2495.         u16 data_offset;
  2496.         int i;
  2497.  
  2498.         if (atom_parse_data_header(mode_info->atom_context, index, NULL,
  2499.                                    &frev, &crev, &data_offset)) {
  2500.                 igp_info = (union igp_info *)(mode_info->atom_context->bios +
  2501.                                               data_offset);
  2502.  
  2503.                 if (crev != 8) {
  2504.                         DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
  2505.                         return -EINVAL;
  2506.                 }
  2507.                 pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_8.ulBootUpEngineClock);
  2508.                 pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_8.ulBootUpUMAClock);
  2509.                 pi->sys_info.bootup_nb_voltage_index =
  2510.                         le16_to_cpu(igp_info->info_8.usBootUpNBVoltage);
  2511.                 if (igp_info->info_8.ucHtcTmpLmt == 0)
  2512.                         pi->sys_info.htc_tmp_lmt = 203;
  2513.                 else
  2514.                         pi->sys_info.htc_tmp_lmt = igp_info->info_8.ucHtcTmpLmt;
  2515.                 if (igp_info->info_8.ucHtcHystLmt == 0)
  2516.                         pi->sys_info.htc_hyst_lmt = 5;
  2517.                 else
  2518.                         pi->sys_info.htc_hyst_lmt = igp_info->info_8.ucHtcHystLmt;
  2519.                 if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
  2520.                         DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
  2521.                 }
  2522.  
  2523.                 if (le32_to_cpu(igp_info->info_8.ulSystemConfig) & (1 << 3))
  2524.                         pi->sys_info.nb_dpm_enable = true;
  2525.                 else
  2526.                         pi->sys_info.nb_dpm_enable = false;
  2527.  
  2528.                 for (i = 0; i < KV_NUM_NBPSTATES; i++) {
  2529.                         pi->sys_info.nbp_memory_clock[i] =
  2530.                                 le32_to_cpu(igp_info->info_8.ulNbpStateMemclkFreq[i]);
  2531.                         pi->sys_info.nbp_n_clock[i] =
  2532.                                 le32_to_cpu(igp_info->info_8.ulNbpStateNClkFreq[i]);
  2533.                 }
  2534.                 if (le32_to_cpu(igp_info->info_8.ulGPUCapInfo) &
  2535.                     SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS)
  2536.                         pi->caps_enable_dfs_bypass = true;
  2537.  
  2538.                 sumo_construct_sclk_voltage_mapping_table(rdev,
  2539.                                                           &pi->sys_info.sclk_voltage_mapping_table,
  2540.                                                           igp_info->info_8.sAvail_SCLK);
  2541.  
  2542.                 sumo_construct_vid_mapping_table(rdev,
  2543.                                                  &pi->sys_info.vid_mapping_table,
  2544.                                                  igp_info->info_8.sAvail_SCLK);
  2545.  
  2546.                 kv_construct_max_power_limits_table(rdev,
  2547.                                                     &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac);
  2548.         }
  2549.         return 0;
  2550. }
  2551.  
  2552. union power_info {
  2553.         struct _ATOM_POWERPLAY_INFO info;
  2554.         struct _ATOM_POWERPLAY_INFO_V2 info_2;
  2555.         struct _ATOM_POWERPLAY_INFO_V3 info_3;
  2556.         struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
  2557.         struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
  2558.         struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
  2559. };
  2560.  
  2561. union pplib_clock_info {
  2562.         struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
  2563.         struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
  2564.         struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
  2565.         struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
  2566. };
  2567.  
  2568. union pplib_power_state {
  2569.         struct _ATOM_PPLIB_STATE v1;
  2570.         struct _ATOM_PPLIB_STATE_V2 v2;
  2571. };
  2572.  
  2573. static void kv_patch_boot_state(struct radeon_device *rdev,
  2574.                                 struct kv_ps *ps)
  2575. {
  2576.         struct kv_power_info *pi = kv_get_pi(rdev);
  2577.  
  2578.         ps->num_levels = 1;
  2579.         ps->levels[0] = pi->boot_pl;
  2580. }
  2581.  
  2582. static void kv_parse_pplib_non_clock_info(struct radeon_device *rdev,
  2583.                                           struct radeon_ps *rps,
  2584.                                           struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
  2585.                                           u8 table_rev)
  2586. {
  2587.         struct kv_ps *ps = kv_get_ps(rps);
  2588.  
  2589.         rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
  2590.         rps->class = le16_to_cpu(non_clock_info->usClassification);
  2591.         rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
  2592.  
  2593.         if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
  2594.                 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
  2595.                 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
  2596.         } else {
  2597.                 rps->vclk = 0;
  2598.                 rps->dclk = 0;
  2599.         }
  2600.  
  2601.         if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
  2602.                 rdev->pm.dpm.boot_ps = rps;
  2603.                 kv_patch_boot_state(rdev, ps);
  2604.         }
  2605.         if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
  2606.                 rdev->pm.dpm.uvd_ps = rps;
  2607. }
  2608.  
  2609. static void kv_parse_pplib_clock_info(struct radeon_device *rdev,
  2610.                                       struct radeon_ps *rps, int index,
  2611.                                         union pplib_clock_info *clock_info)
  2612. {
  2613.         struct kv_power_info *pi = kv_get_pi(rdev);
  2614.         struct kv_ps *ps = kv_get_ps(rps);
  2615.         struct kv_pl *pl = &ps->levels[index];
  2616.         u32 sclk;
  2617.  
  2618.         sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
  2619.         sclk |= clock_info->sumo.ucEngineClockHigh << 16;
  2620.         pl->sclk = sclk;
  2621.         pl->vddc_index = clock_info->sumo.vddcIndex;
  2622.  
  2623.         ps->num_levels = index + 1;
  2624.  
  2625.         if (pi->caps_sclk_ds) {
  2626.                 pl->ds_divider_index = 5;
  2627.                 pl->ss_divider_index = 5;
  2628.         }
  2629. }
  2630.  
  2631. static int kv_parse_power_table(struct radeon_device *rdev)
  2632. {
  2633.         struct radeon_mode_info *mode_info = &rdev->mode_info;
  2634.         struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
  2635.         union pplib_power_state *power_state;
  2636.         int i, j, k, non_clock_array_index, clock_array_index;
  2637.         union pplib_clock_info *clock_info;
  2638.         struct _StateArray *state_array;
  2639.         struct _ClockInfoArray *clock_info_array;
  2640.         struct _NonClockInfoArray *non_clock_info_array;
  2641.         union power_info *power_info;
  2642.         int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
  2643.         u16 data_offset;
  2644.         u8 frev, crev;
  2645.         u8 *power_state_offset;
  2646.         struct kv_ps *ps;
  2647.  
  2648.         if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
  2649.                                    &frev, &crev, &data_offset))
  2650.                 return -EINVAL;
  2651.         power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
  2652.  
  2653.         state_array = (struct _StateArray *)
  2654.                 (mode_info->atom_context->bios + data_offset +
  2655.                  le16_to_cpu(power_info->pplib.usStateArrayOffset));
  2656.         clock_info_array = (struct _ClockInfoArray *)
  2657.                 (mode_info->atom_context->bios + data_offset +
  2658.                  le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
  2659.         non_clock_info_array = (struct _NonClockInfoArray *)
  2660.                 (mode_info->atom_context->bios + data_offset +
  2661.                  le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
  2662.  
  2663.         rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
  2664.                                   state_array->ucNumEntries, GFP_KERNEL);
  2665.         if (!rdev->pm.dpm.ps)
  2666.                 return -ENOMEM;
  2667.         power_state_offset = (u8 *)state_array->states;
  2668.         for (i = 0; i < state_array->ucNumEntries; i++) {
  2669.                 u8 *idx;
  2670.                 power_state = (union pplib_power_state *)power_state_offset;
  2671.                 non_clock_array_index = power_state->v2.nonClockInfoIndex;
  2672.                 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
  2673.                         &non_clock_info_array->nonClockInfo[non_clock_array_index];
  2674.                 if (!rdev->pm.power_state[i].clock_info)
  2675.                         return -EINVAL;
  2676.                 ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL);
  2677.                 if (ps == NULL) {
  2678.                         kfree(rdev->pm.dpm.ps);
  2679.                         return -ENOMEM;
  2680.                 }
  2681.                 rdev->pm.dpm.ps[i].ps_priv = ps;
  2682.                 k = 0;
  2683.                 idx = (u8 *)&power_state->v2.clockInfoIndex[0];
  2684.                 for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
  2685.                         clock_array_index = idx[j];
  2686.                         if (clock_array_index >= clock_info_array->ucNumEntries)
  2687.                                 continue;
  2688.                         if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
  2689.                                 break;
  2690.                         clock_info = (union pplib_clock_info *)
  2691.                                 ((u8 *)&clock_info_array->clockInfo[0] +
  2692.                                  (clock_array_index * clock_info_array->ucEntrySize));
  2693.                         kv_parse_pplib_clock_info(rdev,
  2694.                                                   &rdev->pm.dpm.ps[i], k,
  2695.                                                   clock_info);
  2696.                         k++;
  2697.                 }
  2698.                 kv_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
  2699.                                               non_clock_info,
  2700.                                               non_clock_info_array->ucEntrySize);
  2701.                 power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
  2702.         }
  2703.         rdev->pm.dpm.num_ps = state_array->ucNumEntries;
  2704.  
  2705.         /* fill in the vce power states */
  2706.         for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
  2707.                 u32 sclk;
  2708.                 clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
  2709.                 clock_info = (union pplib_clock_info *)
  2710.                         &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
  2711.                 sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
  2712.                 sclk |= clock_info->sumo.ucEngineClockHigh << 16;
  2713.                 rdev->pm.dpm.vce_states[i].sclk = sclk;
  2714.                 rdev->pm.dpm.vce_states[i].mclk = 0;
  2715.         }
  2716.  
  2717.         return 0;
  2718. }
  2719.  
  2720. int kv_dpm_init(struct radeon_device *rdev)
  2721. {
  2722.         struct kv_power_info *pi;
  2723.         int ret, i;
  2724.  
  2725.         pi = kzalloc(sizeof(struct kv_power_info), GFP_KERNEL);
  2726.         if (pi == NULL)
  2727.                 return -ENOMEM;
  2728.         rdev->pm.dpm.priv = pi;
  2729.  
  2730.         ret = r600_get_platform_caps(rdev);
  2731.         if (ret)
  2732.                 return ret;
  2733.  
  2734.         ret = r600_parse_extended_power_table(rdev);
  2735.         if (ret)
  2736.                 return ret;
  2737.  
  2738.         for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
  2739.                 pi->at[i] = TRINITY_AT_DFLT;
  2740.  
  2741.         pi->sram_end = SMC_RAM_END;
  2742.  
  2743.         /* Enabling nb dpm on an asrock system prevents dpm from working */
  2744.         if (rdev->pdev->subsystem_vendor == 0x1849)
  2745.                 pi->enable_nb_dpm = false;
  2746.         else
  2747.                 pi->enable_nb_dpm = true;
  2748.  
  2749.         pi->caps_power_containment = true;
  2750.         pi->caps_cac = true;
  2751.         pi->enable_didt = false;
  2752.         if (pi->enable_didt) {
  2753.                 pi->caps_sq_ramping = true;
  2754.                 pi->caps_db_ramping = true;
  2755.                 pi->caps_td_ramping = true;
  2756.                 pi->caps_tcp_ramping = true;
  2757.         }
  2758.  
  2759.         pi->caps_sclk_ds = true;
  2760.         pi->enable_auto_thermal_throttling = true;
  2761.         pi->disable_nb_ps3_in_battery = false;
  2762.         if (radeon_bapm == -1) {
  2763.                 /* only enable bapm on KB, ML by default */
  2764.                 if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
  2765.                         pi->bapm_enable = true;
  2766.                 else
  2767.                         pi->bapm_enable = false;
  2768.         } else if (radeon_bapm == 0) {
  2769.                 pi->bapm_enable = false;
  2770.         } else {
  2771.                 pi->bapm_enable = true;
  2772.         }
  2773.         pi->voltage_drop_t = 0;
  2774.         pi->caps_sclk_throttle_low_notification = false;
  2775.         pi->caps_fps = false; /* true? */
  2776.         pi->caps_uvd_pg = true;
  2777.         pi->caps_uvd_dpm = true;
  2778.         pi->caps_vce_pg = false; /* XXX true */
  2779.         pi->caps_samu_pg = false;
  2780.         pi->caps_acp_pg = false;
  2781.         pi->caps_stable_p_state = false;
  2782.  
  2783.         ret = kv_parse_sys_info_table(rdev);
  2784.         if (ret)
  2785.                 return ret;
  2786.  
  2787.         kv_patch_voltage_values(rdev);
  2788.         kv_construct_boot_state(rdev);
  2789.  
  2790.         ret = kv_parse_power_table(rdev);
  2791.         if (ret)
  2792.                 return ret;
  2793.  
  2794.         pi->enable_dpm = true;
  2795.  
  2796.         return 0;
  2797. }
  2798.  
  2799. void kv_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
  2800.                                                     struct seq_file *m)
  2801. {
  2802.         struct kv_power_info *pi = kv_get_pi(rdev);
  2803.         u32 current_index =
  2804.                 (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_SCLK_INDEX_MASK) >>
  2805.                 CURR_SCLK_INDEX_SHIFT;
  2806.         u32 sclk, tmp;
  2807.         u16 vddc;
  2808.  
  2809.         if (current_index >= SMU__NUM_SCLK_DPM_STATE) {
  2810.                 seq_printf(m, "invalid dpm profile %d\n", current_index);
  2811.         } else {
  2812.                 sclk = be32_to_cpu(pi->graphics_level[current_index].SclkFrequency);
  2813.                 tmp = (RREG32_SMC(SMU_VOLTAGE_STATUS) & SMU_VOLTAGE_CURRENT_LEVEL_MASK) >>
  2814.                         SMU_VOLTAGE_CURRENT_LEVEL_SHIFT;
  2815.                 vddc = kv_convert_8bit_index_to_voltage(rdev, (u16)tmp);
  2816.                 seq_printf(m, "uvd    %sabled\n", pi->uvd_power_gated ? "dis" : "en");
  2817.                 seq_printf(m, "vce    %sabled\n", pi->vce_power_gated ? "dis" : "en");
  2818.                 seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
  2819.                            current_index, sclk, vddc);
  2820.         }
  2821. }
  2822.  
  2823. u32 kv_dpm_get_current_sclk(struct radeon_device *rdev)
  2824. {
  2825.         struct kv_power_info *pi = kv_get_pi(rdev);
  2826.         u32 current_index =
  2827.                 (RREG32_SMC(TARGET_AND_CURRENT_PROFILE_INDEX) & CURR_SCLK_INDEX_MASK) >>
  2828.                 CURR_SCLK_INDEX_SHIFT;
  2829.         u32 sclk;
  2830.  
  2831.         if (current_index >= SMU__NUM_SCLK_DPM_STATE) {
  2832.                 return 0;
  2833.         } else {
  2834.                 sclk = be32_to_cpu(pi->graphics_level[current_index].SclkFrequency);
  2835.                 return sclk;
  2836.         }
  2837. }
  2838.  
  2839. u32 kv_dpm_get_current_mclk(struct radeon_device *rdev)
  2840. {
  2841.         struct kv_power_info *pi = kv_get_pi(rdev);
  2842.  
  2843.         return pi->sys_info.bootup_uma_clk;
  2844. }
  2845.  
  2846. void kv_dpm_print_power_state(struct radeon_device *rdev,
  2847.                               struct radeon_ps *rps)
  2848. {
  2849.         int i;
  2850.         struct kv_ps *ps = kv_get_ps(rps);
  2851.  
  2852.         r600_dpm_print_class_info(rps->class, rps->class2);
  2853.         r600_dpm_print_cap_info(rps->caps);
  2854.         printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
  2855.         for (i = 0; i < ps->num_levels; i++) {
  2856.                 struct kv_pl *pl = &ps->levels[i];
  2857.                 printk("\t\tpower level %d    sclk: %u vddc: %u\n",
  2858.                        i, pl->sclk,
  2859.                        kv_convert_8bit_index_to_voltage(rdev, pl->vddc_index));
  2860.         }
  2861.         r600_dpm_print_ps_status(rdev, rps);
  2862. }
  2863.  
  2864. void kv_dpm_fini(struct radeon_device *rdev)
  2865. {
  2866.         int i;
  2867.  
  2868.         for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
  2869.                 kfree(rdev->pm.dpm.ps[i].ps_priv);
  2870.         }
  2871.         kfree(rdev->pm.dpm.ps);
  2872.         kfree(rdev->pm.dpm.priv);
  2873.         r600_free_extended_power_table(rdev);
  2874. }
  2875.  
  2876. void kv_dpm_display_configuration_changed(struct radeon_device *rdev)
  2877. {
  2878.  
  2879. }
  2880.  
  2881. u32 kv_dpm_get_sclk(struct radeon_device *rdev, bool low)
  2882. {
  2883.         struct kv_power_info *pi = kv_get_pi(rdev);
  2884.         struct kv_ps *requested_state = kv_get_ps(&pi->requested_rps);
  2885.  
  2886.         if (low)
  2887.                 return requested_state->levels[0].sclk;
  2888.         else
  2889.                 return requested_state->levels[requested_state->num_levels - 1].sclk;
  2890. }
  2891.  
  2892. u32 kv_dpm_get_mclk(struct radeon_device *rdev, bool low)
  2893. {
  2894.         struct kv_power_info *pi = kv_get_pi(rdev);
  2895.  
  2896.         return pi->sys_info.bootup_uma_clk;
  2897. }
  2898.  
  2899.