#include "amdgpu.h"
#include "amdgpu_pm.h"
#include "cikd.h"
#include "atom.h"
#include "amdgpu_atombios.h"
#include "amdgpu_dpm.h"
#include "kv_dpm.h"
#include "gfx_v7_0.h"
#include <linux/seq_file.h>
#include "smu/smu_7_0_0_d.h"
#include "smu/smu_7_0_0_sh_mask.h"
#include "gca/gfx_7_2_d.h"
#include "gca/gfx_7_2_sh_mask.h"
#include "legacy_dpm.h"
#define KV_MAX_DEEPSLEEP_DIVIDER_ID …
#define KV_MINIMUM_ENGINE_CLOCK …
#define SMC_RAM_END …
static const struct amd_pm_funcs kv_dpm_funcs;
static void kv_dpm_set_irq_funcs(struct amdgpu_device *adev);
static int kv_enable_nb_dpm(struct amdgpu_device *adev,
bool enable);
static void kv_init_graphics_levels(struct amdgpu_device *adev);
static int kv_calculate_ds_divider(struct amdgpu_device *adev);
static int kv_calculate_nbps_level_settings(struct amdgpu_device *adev);
static int kv_calculate_dpm_settings(struct amdgpu_device *adev);
static void kv_enable_new_levels(struct amdgpu_device *adev);
static void kv_program_nbps_index_settings(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps);
static int kv_set_enabled_level(struct amdgpu_device *adev, u32 level);
static int kv_set_enabled_levels(struct amdgpu_device *adev);
static int kv_force_dpm_highest(struct amdgpu_device *adev);
static int kv_force_dpm_lowest(struct amdgpu_device *adev);
static void kv_apply_state_adjust_rules(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps,
struct amdgpu_ps *old_rps);
static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,
int min_temp, int max_temp);
static int kv_init_fps_limits(struct amdgpu_device *adev);
static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate);
static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate);
static u32 kv_convert_vid2_to_vid7(struct amdgpu_device *adev,
struct sumo_vid_mapping_table *vid_mapping_table,
u32 vid_2bit)
{ … }
static u32 kv_convert_vid7_to_vid2(struct amdgpu_device *adev,
struct sumo_vid_mapping_table *vid_mapping_table,
u32 vid_7bit)
{ … }
static void sumo_take_smu_control(struct amdgpu_device *adev, bool enable)
{ … }
static void sumo_construct_sclk_voltage_mapping_table(struct amdgpu_device *adev,
struct sumo_sclk_voltage_mapping_table *sclk_voltage_mapping_table,
ATOM_AVAILABLE_SCLK_LIST *table)
{ … }
static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev,
struct sumo_vid_mapping_table *vid_mapping_table,
ATOM_AVAILABLE_SCLK_LIST *table)
{ … }
#if 0
static const struct kv_lcac_config_values sx_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 1, 4, 1 },
{ 2, 5, 1 },
{ 3, 4, 2 },
{ 4, 1, 1 },
{ 5, 5, 2 },
{ 6, 6, 1 },
{ 7, 9, 2 },
{ 0xffffffff }
};
static const struct kv_lcac_config_values mc0_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 0xffffffff }
};
static const struct kv_lcac_config_values mc1_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 0xffffffff }
};
static const struct kv_lcac_config_values mc2_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 0xffffffff }
};
static const struct kv_lcac_config_values mc3_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 0xffffffff }
};
static const struct kv_lcac_config_values cpl_local_cac_cfg_kv[] = {
{ 0, 4, 1 },
{ 1, 4, 1 },
{ 2, 5, 1 },
{ 3, 4, 1 },
{ 4, 1, 1 },
{ 5, 5, 1 },
{ 6, 6, 1 },
{ 7, 9, 1 },
{ 8, 4, 1 },
{ 9, 2, 1 },
{ 10, 3, 1 },
{ 11, 6, 1 },
{ 12, 8, 2 },
{ 13, 1, 1 },
{ 14, 2, 1 },
{ 15, 3, 1 },
{ 16, 1, 1 },
{ 17, 4, 1 },
{ 18, 3, 1 },
{ 19, 1, 1 },
{ 20, 8, 1 },
{ 21, 5, 1 },
{ 22, 1, 1 },
{ 23, 1, 1 },
{ 24, 4, 1 },
{ 27, 6, 1 },
{ 28, 1, 1 },
{ 0xffffffff }
};
static const struct kv_lcac_config_reg sx0_cac_config_reg[] = {
{ 0xc0400d00, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
static const struct kv_lcac_config_reg mc0_cac_config_reg[] = {
{ 0xc0400d30, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
static const struct kv_lcac_config_reg mc1_cac_config_reg[] = {
{ 0xc0400d3c, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
static const struct kv_lcac_config_reg mc2_cac_config_reg[] = {
{ 0xc0400d48, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
static const struct kv_lcac_config_reg mc3_cac_config_reg[] = {
{ 0xc0400d54, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
static const struct kv_lcac_config_reg cpl_cac_config_reg[] = {
{ 0xc0400d80, 0x003e0000, 17, 0x3fc00000, 22, 0x0001fffe, 1, 0x00000001, 0 }
};
#endif
static const struct kv_pt_config_reg didt_config_kv[] = …;
static struct kv_ps *kv_get_ps(struct amdgpu_ps *rps)
{ … }
static struct kv_power_info *kv_get_pi(struct amdgpu_device *adev)
{ … }
#if 0
static void kv_program_local_cac_table(struct amdgpu_device *adev,
const struct kv_lcac_config_values *local_cac_table,
const struct kv_lcac_config_reg *local_cac_reg)
{
u32 i, count, data;
const struct kv_lcac_config_values *values = local_cac_table;
while (values->block_id != 0xffffffff) {
count = values->signal_id;
for (i = 0; i < count; i++) {
data = ((values->block_id << local_cac_reg->block_shift) &
local_cac_reg->block_mask);
data |= ((i << local_cac_reg->signal_shift) &
local_cac_reg->signal_mask);
data |= ((values->t << local_cac_reg->t_shift) &
local_cac_reg->t_mask);
data |= ((1 << local_cac_reg->enable_shift) &
local_cac_reg->enable_mask);
WREG32_SMC(local_cac_reg->cntl, data);
}
values++;
}
}
#endif
static int kv_program_pt_config_registers(struct amdgpu_device *adev,
const struct kv_pt_config_reg *cac_config_regs)
{ … }
static void kv_do_enable_didt(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_enable_didt(struct amdgpu_device *adev, bool enable)
{ … }
#if 0
static void kv_initialize_hardware_cac_manager(struct amdgpu_device *adev)
{
struct kv_power_info *pi = kv_get_pi(adev);
if (pi->caps_cac) {
WREG32_SMC(ixLCAC_SX0_OVR_SEL, 0);
WREG32_SMC(ixLCAC_SX0_OVR_VAL, 0);
kv_program_local_cac_table(adev, sx_local_cac_cfg_kv, sx0_cac_config_reg);
WREG32_SMC(ixLCAC_MC0_OVR_SEL, 0);
WREG32_SMC(ixLCAC_MC0_OVR_VAL, 0);
kv_program_local_cac_table(adev, mc0_local_cac_cfg_kv, mc0_cac_config_reg);
WREG32_SMC(ixLCAC_MC1_OVR_SEL, 0);
WREG32_SMC(ixLCAC_MC1_OVR_VAL, 0);
kv_program_local_cac_table(adev, mc1_local_cac_cfg_kv, mc1_cac_config_reg);
WREG32_SMC(ixLCAC_MC2_OVR_SEL, 0);
WREG32_SMC(ixLCAC_MC2_OVR_VAL, 0);
kv_program_local_cac_table(adev, mc2_local_cac_cfg_kv, mc2_cac_config_reg);
WREG32_SMC(ixLCAC_MC3_OVR_SEL, 0);
WREG32_SMC(ixLCAC_MC3_OVR_VAL, 0);
kv_program_local_cac_table(adev, mc3_local_cac_cfg_kv, mc3_cac_config_reg);
WREG32_SMC(ixLCAC_CPL_OVR_SEL, 0);
WREG32_SMC(ixLCAC_CPL_OVR_VAL, 0);
kv_program_local_cac_table(adev, cpl_local_cac_cfg_kv, cpl_cac_config_reg);
}
}
#endif
static int kv_enable_smc_cac(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_process_firmware_header(struct amdgpu_device *adev)
{ … }
static int kv_enable_dpm_voltage_scaling(struct amdgpu_device *adev)
{ … }
static int kv_set_dpm_interval(struct amdgpu_device *adev)
{ … }
static int kv_set_dpm_boot_state(struct amdgpu_device *adev)
{ … }
static void kv_program_vc(struct amdgpu_device *adev)
{ … }
static void kv_clear_vc(struct amdgpu_device *adev)
{ … }
static int kv_set_divider_value(struct amdgpu_device *adev,
u32 index, u32 sclk)
{ … }
static u16 kv_convert_8bit_index_to_voltage(struct amdgpu_device *adev,
u16 voltage)
{ … }
static u16 kv_convert_2bit_index_to_voltage(struct amdgpu_device *adev,
u32 vid_2bit)
{ … }
static int kv_set_vid(struct amdgpu_device *adev, u32 index, u32 vid)
{ … }
static int kv_set_at(struct amdgpu_device *adev, u32 index, u32 at)
{ … }
static void kv_dpm_power_level_enable(struct amdgpu_device *adev,
u32 index, bool enable)
{ … }
static void kv_start_dpm(struct amdgpu_device *adev)
{ … }
static void kv_stop_dpm(struct amdgpu_device *adev)
{ … }
static void kv_start_am(struct amdgpu_device *adev)
{ … }
static void kv_reset_am(struct amdgpu_device *adev)
{ … }
static int kv_freeze_sclk_dpm(struct amdgpu_device *adev, bool freeze)
{ … }
static int kv_force_lowest_valid(struct amdgpu_device *adev)
{ … }
static int kv_unforce_levels(struct amdgpu_device *adev)
{ … }
static int kv_update_sclk_t(struct amdgpu_device *adev)
{ … }
static int kv_program_bootup_state(struct amdgpu_device *adev)
{ … }
static int kv_enable_auto_thermal_throttling(struct amdgpu_device *adev)
{ … }
static int kv_upload_dpm_settings(struct amdgpu_device *adev)
{ … }
static u32 kv_get_clock_difference(u32 a, u32 b)
{ … }
static u32 kv_get_clk_bypass(struct amdgpu_device *adev, u32 clk)
{ … }
static int kv_populate_uvd_table(struct amdgpu_device *adev)
{ … }
static int kv_populate_vce_table(struct amdgpu_device *adev)
{ … }
static int kv_populate_samu_table(struct amdgpu_device *adev)
{ … }
static int kv_populate_acp_table(struct amdgpu_device *adev)
{ … }
static void kv_calculate_dfs_bypass_settings(struct amdgpu_device *adev)
{ … }
static int kv_enable_ulv(struct amdgpu_device *adev, bool enable)
{ … }
static void kv_reset_acp_boot_level(struct amdgpu_device *adev)
{ … }
static void kv_update_current_ps(struct amdgpu_device *adev,
struct amdgpu_ps *rps)
{ … }
static void kv_update_requested_ps(struct amdgpu_device *adev,
struct amdgpu_ps *rps)
{ … }
static void kv_dpm_enable_bapm(void *handle, bool enable)
{ … }
static bool kv_is_internal_thermal_sensor(enum amdgpu_int_thermal_type sensor)
{ … }
static int kv_dpm_enable(struct amdgpu_device *adev)
{ … }
static void kv_dpm_disable(struct amdgpu_device *adev)
{ … }
#if 0
static int kv_write_smc_soft_register(struct amdgpu_device *adev,
u16 reg_offset, u32 value)
{
struct kv_power_info *pi = kv_get_pi(adev);
return amdgpu_kv_copy_bytes_to_smc(adev, pi->soft_regs_start + reg_offset,
(u8 *)&value, sizeof(u16), pi->sram_end);
}
static int kv_read_smc_soft_register(struct amdgpu_device *adev,
u16 reg_offset, u32 *value)
{
struct kv_power_info *pi = kv_get_pi(adev);
return amdgpu_kv_read_smc_sram_dword(adev, pi->soft_regs_start + reg_offset,
value, pi->sram_end);
}
#endif
static void kv_init_sclk_t(struct amdgpu_device *adev)
{ … }
static int kv_init_fps_limits(struct amdgpu_device *adev)
{ … }
static void kv_init_powergate_state(struct amdgpu_device *adev)
{ … }
static int kv_enable_uvd_dpm(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_enable_vce_dpm(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_enable_samu_dpm(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_enable_acp_dpm(struct amdgpu_device *adev, bool enable)
{ … }
static int kv_update_uvd_dpm(struct amdgpu_device *adev, bool gate)
{ … }
static u8 kv_get_vce_boot_level(struct amdgpu_device *adev, u32 evclk)
{ … }
static int kv_update_vce_dpm(struct amdgpu_device *adev,
struct amdgpu_ps *amdgpu_new_state,
struct amdgpu_ps *amdgpu_current_state)
{ … }
static int kv_update_samu_dpm(struct amdgpu_device *adev, bool gate)
{ … }
static u8 kv_get_acp_boot_level(struct amdgpu_device *adev)
{ … }
static void kv_update_acp_boot_level(struct amdgpu_device *adev)
{ … }
static int kv_update_acp_dpm(struct amdgpu_device *adev, bool gate)
{ … }
static void kv_dpm_powergate_uvd(void *handle, bool gate)
{ … }
static void kv_dpm_powergate_vce(void *handle, bool gate)
{ … }
static void kv_dpm_powergate_samu(struct amdgpu_device *adev, bool gate)
{ … }
static void kv_dpm_powergate_acp(struct amdgpu_device *adev, bool gate)
{ … }
static void kv_set_valid_clock_range(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps)
{ … }
static int kv_update_dfs_bypass_settings(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps)
{ … }
static int kv_enable_nb_dpm(struct amdgpu_device *adev,
bool enable)
{ … }
static int kv_dpm_force_performance_level(void *handle,
enum amd_dpm_forced_level level)
{ … }
static int kv_dpm_pre_set_power_state(void *handle)
{ … }
static int kv_dpm_set_power_state(void *handle)
{ … }
static void kv_dpm_post_set_power_state(void *handle)
{ … }
static void kv_dpm_setup_asic(struct amdgpu_device *adev)
{ … }
#if 0
static void kv_dpm_reset_asic(struct amdgpu_device *adev)
{
struct kv_power_info *pi = kv_get_pi(adev);
if (adev->asic_type == CHIP_KABINI || adev->asic_type == CHIP_MULLINS) {
kv_force_lowest_valid(adev);
kv_init_graphics_levels(adev);
kv_program_bootup_state(adev);
kv_upload_dpm_settings(adev);
kv_force_lowest_valid(adev);
kv_unforce_levels(adev);
} else {
kv_init_graphics_levels(adev);
kv_program_bootup_state(adev);
kv_freeze_sclk_dpm(adev, true);
kv_upload_dpm_settings(adev);
kv_freeze_sclk_dpm(adev, false);
kv_set_enabled_level(adev, pi->graphics_boot_level);
}
}
#endif
static void kv_construct_max_power_limits_table(struct amdgpu_device *adev,
struct amdgpu_clock_and_voltage_limits *table)
{ … }
static void kv_patch_voltage_values(struct amdgpu_device *adev)
{ … }
static void kv_construct_boot_state(struct amdgpu_device *adev)
{ … }
static int kv_force_dpm_highest(struct amdgpu_device *adev)
{ … }
static int kv_force_dpm_lowest(struct amdgpu_device *adev)
{ … }
static u8 kv_get_sleep_divider_id_from_clock(struct amdgpu_device *adev,
u32 sclk, u32 min_sclk_in_sr)
{ … }
static int kv_get_high_voltage_limit(struct amdgpu_device *adev, int *limit)
{ … }
static void kv_apply_state_adjust_rules(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps,
struct amdgpu_ps *old_rps)
{ … }
static void kv_dpm_power_level_enabled_for_throttle(struct amdgpu_device *adev,
u32 index, bool enable)
{ … }
static int kv_calculate_ds_divider(struct amdgpu_device *adev)
{ … }
static int kv_calculate_nbps_level_settings(struct amdgpu_device *adev)
{ … }
static int kv_calculate_dpm_settings(struct amdgpu_device *adev)
{ … }
static void kv_init_graphics_levels(struct amdgpu_device *adev)
{ … }
static void kv_enable_new_levels(struct amdgpu_device *adev)
{ … }
static int kv_set_enabled_level(struct amdgpu_device *adev, u32 level)
{ … }
static int kv_set_enabled_levels(struct amdgpu_device *adev)
{ … }
static void kv_program_nbps_index_settings(struct amdgpu_device *adev,
struct amdgpu_ps *new_rps)
{ … }
static int kv_set_thermal_temperature_range(struct amdgpu_device *adev,
int min_temp, int max_temp)
{ … }
igp_info;
static int kv_parse_sys_info_table(struct amdgpu_device *adev)
{ … }
power_info;
pplib_clock_info;
pplib_power_state;
static void kv_patch_boot_state(struct amdgpu_device *adev,
struct kv_ps *ps)
{ … }
static void kv_parse_pplib_non_clock_info(struct amdgpu_device *adev,
struct amdgpu_ps *rps,
struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
u8 table_rev)
{ … }
static void kv_parse_pplib_clock_info(struct amdgpu_device *adev,
struct amdgpu_ps *rps, int index,
union pplib_clock_info *clock_info)
{ … }
static int kv_parse_power_table(struct amdgpu_device *adev)
{ … }
static int kv_dpm_init(struct amdgpu_device *adev)
{ … }
static void
kv_dpm_debugfs_print_current_performance_level(void *handle,
struct seq_file *m)
{ … }
static void
kv_dpm_print_power_state(void *handle, void *request_ps)
{ … }
static void kv_dpm_fini(struct amdgpu_device *adev)
{ … }
static void kv_dpm_display_configuration_changed(void *handle)
{ … }
static u32 kv_dpm_get_sclk(void *handle, bool low)
{ … }
static u32 kv_dpm_get_mclk(void *handle, bool low)
{ … }
static int kv_dpm_get_temp(void *handle)
{ … }
static int kv_dpm_early_init(void *handle)
{ … }
static int kv_dpm_late_init(void *handle)
{ … }
static int kv_dpm_sw_init(void *handle)
{ … }
static int kv_dpm_sw_fini(void *handle)
{ … }
static int kv_dpm_hw_init(void *handle)
{ … }
static int kv_dpm_hw_fini(void *handle)
{ … }
static int kv_dpm_suspend(void *handle)
{ … }
static int kv_dpm_resume(void *handle)
{ … }
static bool kv_dpm_is_idle(void *handle)
{ … }
static int kv_dpm_wait_for_idle(void *handle)
{ … }
static int kv_dpm_soft_reset(void *handle)
{ … }
static int kv_dpm_set_interrupt_state(struct amdgpu_device *adev,
struct amdgpu_irq_src *src,
unsigned type,
enum amdgpu_interrupt_state state)
{ … }
static int kv_dpm_process_interrupt(struct amdgpu_device *adev,
struct amdgpu_irq_src *source,
struct amdgpu_iv_entry *entry)
{ … }
static int kv_dpm_set_clockgating_state(void *handle,
enum amd_clockgating_state state)
{ … }
static int kv_dpm_set_powergating_state(void *handle,
enum amd_powergating_state state)
{ … }
static inline bool kv_are_power_levels_equal(const struct kv_pl *kv_cpl1,
const struct kv_pl *kv_cpl2)
{ … }
static int kv_check_state_equal(void *handle,
void *current_ps,
void *request_ps,
bool *equal)
{ … }
static int kv_dpm_read_sensor(void *handle, int idx,
void *value, int *size)
{ … }
static int kv_set_powergating_by_smu(void *handle,
uint32_t block_type, bool gate)
{ … }
static const struct amd_ip_funcs kv_dpm_ip_funcs = …;
const struct amdgpu_ip_block_version kv_smu_ip_block = …;
static const struct amd_pm_funcs kv_dpm_funcs = …;
static const struct amdgpu_irq_src_funcs kv_dpm_irq_funcs = …;
static void kv_dpm_set_irq_funcs(struct amdgpu_device *adev)
{ … }