linux/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c

/*
 * Copyright 2013 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#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)
{}

/* get temperature in millidegrees */
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)
{}