cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kv_dpm.c (93950B)


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