Commit 8554e67d authored by Chengming Gui's avatar Chengming Gui Committed by Alex Deucher

drm/amd/powerplay: implement power_dpm_state sys interface for SMU11

Add functions to get/set dpm state for SMU11.
Signed-off-by: default avatarChengming Gui <Jack.Gui@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Acked-by: default avatarKevin Wang <kevin.wang@amd.com>
Reviewd-by: default avatarEvan Quan <evan.quan@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ad88f051
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment