drm/amd/powerplay: implement power_dpm_state sys interface for SMU11
Add functions to get/set dpm state for SMU11. Signed-off-by: Chengming Gui <Jack.Gui@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Acked-by: Kevin Wang <kevin.wang@amd.com> Reviewd-by: Evan Quan <evan.quan@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
ad88f0517b
commit
8554e67d6e
@ -290,6 +290,12 @@ enum amdgpu_pcie_gen {
|
||||
#define amdgpu_dpm_get_current_power_state(adev) \
|
||||
((adev)->powerplay.pp_funcs->get_current_power_state((adev)->powerplay.pp_handle))
|
||||
|
||||
#define amdgpu_smu_get_current_power_state(adev) \
|
||||
((adev)->smu.ppt_funcs->get_current_power_state(&((adev)->smu)))
|
||||
|
||||
#define amdgpu_smu_set_power_state(adev) \
|
||||
((adev)->smu.ppt_funcs->set_power_state(&((adev)->smu)))
|
||||
|
||||
#define amdgpu_dpm_get_pp_num_states(adev, data) \
|
||||
((adev)->powerplay.pp_funcs->get_pp_num_states((adev)->powerplay.pp_handle, data))
|
||||
|
||||
|
@ -144,7 +144,9 @@ static ssize_t amdgpu_get_dpm_state(struct device *dev,
|
||||
struct amdgpu_device *adev = ddev->dev_private;
|
||||
enum amd_pm_state_type pm;
|
||||
|
||||
if (adev->powerplay.pp_funcs->get_current_power_state)
|
||||
if (adev->smu.ppt_funcs->get_current_power_state)
|
||||
pm = amdgpu_smu_get_current_power_state(adev);
|
||||
else if (adev->powerplay.pp_funcs->get_current_power_state)
|
||||
pm = amdgpu_dpm_get_current_power_state(adev);
|
||||
else
|
||||
pm = adev->pm.dpm.user_state;
|
||||
|
@ -26,6 +26,118 @@
|
||||
#include "kgd_pp_interface.h"
|
||||
#include "dm_pp_interface.h"
|
||||
|
||||
struct smu_hw_power_state {
|
||||
unsigned int magic;
|
||||
};
|
||||
|
||||
struct smu_power_state;
|
||||
|
||||
enum smu_state_ui_label {
|
||||
SMU_STATE_UI_LABEL_NONE,
|
||||
SMU_STATE_UI_LABEL_BATTERY,
|
||||
SMU_STATE_UI_TABEL_MIDDLE_LOW,
|
||||
SMU_STATE_UI_LABEL_BALLANCED,
|
||||
SMU_STATE_UI_LABEL_MIDDLE_HIGHT,
|
||||
SMU_STATE_UI_LABEL_PERFORMANCE,
|
||||
SMU_STATE_UI_LABEL_BACO,
|
||||
};
|
||||
|
||||
enum smu_state_classification_flag {
|
||||
SMU_STATE_CLASSIFICATION_FLAG_BOOT = 0x0001,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_THERMAL = 0x0002,
|
||||
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE = 0x0004,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_RESET = 0x0008,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_FORCED = 0x0010,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE = 0x0020,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE = 0x0040,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE = 0x0080,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE = 0x0100,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_UVD = 0x0200,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW = 0x0400,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_ACPI = 0x0800,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_HD2 = 0x1000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_UVD_HD = 0x2000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_UVD_SD = 0x4000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE = 0x8000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE = 0x10000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_BACO = 0x20000,
|
||||
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2 = 0x40000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_ULV = 0x80000,
|
||||
SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC = 0x100000,
|
||||
};
|
||||
|
||||
struct smu_state_classification_block {
|
||||
enum smu_state_ui_label ui_label;
|
||||
enum smu_state_classification_flag flags;
|
||||
int bios_index;
|
||||
bool temporary_state;
|
||||
bool to_be_deleted;
|
||||
};
|
||||
|
||||
struct smu_state_pcie_block {
|
||||
unsigned int lanes;
|
||||
};
|
||||
|
||||
enum smu_refreshrate_source {
|
||||
SMU_REFRESHRATE_SOURCE_EDID,
|
||||
SMU_REFRESHRATE_SOURCE_EXPLICIT
|
||||
};
|
||||
|
||||
struct smu_state_display_block {
|
||||
bool disable_frame_modulation;
|
||||
bool limit_refreshrate;
|
||||
enum smu_refreshrate_source refreshrate_source;
|
||||
int explicit_refreshrate;
|
||||
int edid_refreshrate_index;
|
||||
bool enable_vari_bright;
|
||||
};
|
||||
|
||||
struct smu_state_memroy_block {
|
||||
bool dll_off;
|
||||
uint8_t m3arb;
|
||||
uint8_t unused[3];
|
||||
};
|
||||
|
||||
struct smu_state_software_algorithm_block {
|
||||
bool disable_load_balancing;
|
||||
bool enable_sleep_for_timestamps;
|
||||
};
|
||||
|
||||
struct smu_temperature_range {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct smu_state_validation_block {
|
||||
bool single_display_only;
|
||||
bool disallow_on_dc;
|
||||
uint8_t supported_power_levels;
|
||||
};
|
||||
|
||||
struct smu_uvd_clocks {
|
||||
uint32_t vclk;
|
||||
uint32_t dclk;
|
||||
};
|
||||
|
||||
/**
|
||||
* Structure to hold a SMU Power State.
|
||||
*/
|
||||
struct smu_power_state {
|
||||
uint32_t id;
|
||||
struct list_head ordered_list;
|
||||
struct list_head all_states_list;
|
||||
|
||||
struct smu_state_classification_block classification;
|
||||
struct smu_state_validation_block validation;
|
||||
struct smu_state_pcie_block pcie;
|
||||
struct smu_state_display_block display;
|
||||
struct smu_state_memroy_block memory;
|
||||
struct smu_temperature_range temperatures;
|
||||
struct smu_state_software_algorithm_block software;
|
||||
struct smu_uvd_clocks uvd_clocks;
|
||||
struct smu_hw_power_state hardware;
|
||||
};
|
||||
|
||||
enum smu_message_type
|
||||
{
|
||||
SMU_MSG_TestMessage = 0,
|
||||
@ -204,6 +316,8 @@ struct smu_dpm_context {
|
||||
uint32_t dpm_context_size;
|
||||
void *dpm_context;
|
||||
void *golden_dpm_context;
|
||||
struct smu_power_state *dpm_request_power_state;
|
||||
struct smu_power_state *dpm_current_power_state;
|
||||
};
|
||||
|
||||
struct smu_power_context {
|
||||
@ -257,7 +371,9 @@ struct pptable_funcs {
|
||||
int (*get_smu_msg_index)(struct smu_context *smu, uint32_t index);
|
||||
int (*run_afll_btc)(struct smu_context *smu);
|
||||
int (*get_unallowed_feature_mask)(struct smu_context *smu, uint32_t *feature_mask, uint32_t num);
|
||||
enum amd_pm_state_type (*get_current_power_state)(struct smu_context *smu);
|
||||
int (*set_default_dpm_table)(struct smu_context *smu);
|
||||
int (*set_power_state)(struct smu_context *smu);
|
||||
int (*populate_umd_state_clk)(struct smu_context *smu);
|
||||
int (*print_clk_levels)(struct smu_context *smu, enum pp_clock_type type, char *buf);
|
||||
int (*force_clk_levels)(struct smu_context *smu, enum pp_clock_type type, uint32_t mask);
|
||||
|
@ -273,9 +273,13 @@ static int smu_v11_0_fini_dpm_context(struct smu_context *smu)
|
||||
|
||||
kfree(smu_dpm->dpm_context);
|
||||
kfree(smu_dpm->golden_dpm_context);
|
||||
kfree(smu_dpm->dpm_current_power_state);
|
||||
kfree(smu_dpm->dpm_request_power_state);
|
||||
smu_dpm->dpm_context = NULL;
|
||||
smu_dpm->golden_dpm_context = NULL;
|
||||
smu_dpm->dpm_context_size = 0;
|
||||
smu_dpm->dpm_current_power_state = NULL;
|
||||
smu_dpm->dpm_request_power_state = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "smu11_driver_if.h"
|
||||
#include "soc15_common.h"
|
||||
#include "atom.h"
|
||||
#include "power_state.h"
|
||||
#include "vega20_ppt.h"
|
||||
#include "vega20_pptable.h"
|
||||
#include "vega20_ppsmc.h"
|
||||
@ -154,6 +155,16 @@ static int vega20_allocate_dpm_context(struct smu_context *smu)
|
||||
|
||||
smu_dpm->dpm_context_size = sizeof(struct vega20_dpm_table);
|
||||
|
||||
smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
|
||||
GFP_KERNEL);
|
||||
if (!smu_dpm->dpm_current_power_state)
|
||||
return -ENOMEM;
|
||||
|
||||
smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
|
||||
GFP_KERNEL);
|
||||
if (!smu_dpm->dpm_request_power_state)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -389,6 +400,39 @@ vega20_get_unallowed_feature_mask(struct smu_context *smu,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum
|
||||
amd_pm_state_type vega20_get_current_power_state(struct smu_context *smu)
|
||||
{
|
||||
enum amd_pm_state_type pm_type;
|
||||
struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
|
||||
|
||||
if (!smu_dpm_ctx->dpm_context ||
|
||||
!smu_dpm_ctx->dpm_current_power_state)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&(smu->mutex));
|
||||
switch (smu_dpm_ctx->dpm_current_power_state->classification.ui_label) {
|
||||
case SMU_STATE_UI_LABEL_BATTERY:
|
||||
pm_type = POWER_STATE_TYPE_BATTERY;
|
||||
break;
|
||||
case SMU_STATE_UI_LABEL_BALLANCED:
|
||||
pm_type = POWER_STATE_TYPE_BALANCED;
|
||||
break;
|
||||
case SMU_STATE_UI_LABEL_PERFORMANCE:
|
||||
pm_type = POWER_STATE_TYPE_PERFORMANCE;
|
||||
break;
|
||||
default:
|
||||
if (smu_dpm_ctx->dpm_current_power_state->classification.flags & SMU_STATE_CLASSIFICATION_FLAG_BOOT)
|
||||
pm_type = POWER_STATE_TYPE_INTERNAL_BOOT;
|
||||
else
|
||||
pm_type = POWER_STATE_TYPE_DEFAULT;
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&(smu->mutex));
|
||||
|
||||
return pm_type;
|
||||
}
|
||||
|
||||
static int
|
||||
vega20_set_single_dpm_table(struct smu_context *smu,
|
||||
struct vega20_single_dpm_table *single_dpm_table,
|
||||
@ -1263,7 +1307,9 @@ static const struct pptable_funcs vega20_ppt_funcs = {
|
||||
.get_smu_msg_index = vega20_get_smu_msg_index,
|
||||
.run_afll_btc = vega20_run_btc_afll,
|
||||
.get_unallowed_feature_mask = vega20_get_unallowed_feature_mask,
|
||||
.get_current_power_state = vega20_get_current_power_state,
|
||||
.set_default_dpm_table = vega20_set_default_dpm_table,
|
||||
.set_power_state = NULL,
|
||||
.populate_umd_state_clk = vega20_populate_umd_state_clk,
|
||||
.print_clk_levels = vega20_print_clk_levels,
|
||||
.force_clk_levels = vega20_force_clk_levels,
|
||||
|
Loading…
Reference in New Issue
Block a user