[PATCH 7/8] drm/amd/pp: Implement edit_dpm_table on smu7
Rex Zhu
Rex.Zhu at amd.com
Tue Jan 16 12:02:54 UTC 2018
Change-Id: I301be04db3c56e16e2c10091016efa5439fbc744
Signed-off-by: Rex Zhu <Rex.Zhu at amd.com>
---
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 104 ++++++++++++++++++++++-
1 file changed, 103 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
index c69749d..8dbec14 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
@@ -4834,6 +4834,108 @@ static int smu7_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
return 0;
}
+static bool smu7_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
+ enum PHM_ODN_DPM_TABLE_TYPE type,
+ uint32_t clk,
+ uint32_t voltage)
+{
+ struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+
+ if (hwmgr->dyn_state.max_clock_voltage_on_ac.vddc * 120 / 100 < voltage)
+ return false;
+
+ if (type == PHM_ODN_SCLK_VDDC_TABLE) {
+ if (data->vbios_boot_state.sclk_bootup_value > clk ||
+ hwmgr->dyn_state.max_clock_voltage_on_ac.sclk * 120 / 100 < clk)
+ return false;
+ } else if (type == PHM_ODN_MCLK_VDDC_TABLE) {
+ if (data->vbios_boot_state.mclk_bootup_value > clk ||
+ hwmgr->dyn_state.max_clock_voltage_on_ac.mclk * 120 / 100 < clk)
+ return false;
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
+ enum PHM_ODN_DPM_TABLE_TYPE type,
+ long *input, uint32_t size)
+{
+ uint32_t i;
+ const phm_ppt_v1_clock_voltage_dependency_table *pgolden_vdd_dep_table = NULL;
+ struct phm_odn_clock_levels *podn_dpm_table_in_backend = NULL;
+ struct smu7_odn_clock_voltage_dependency_table *podn_vdd_dep_in_backend = NULL;
+ struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
+ struct phm_ppt_v1_information *table_info =
+ (struct phm_ppt_v1_information *)hwmgr->pptable;
+ struct smu7_smumgr *smu_data = (struct smu7_smumgr *)(hwmgr->smu_backend);
+ uint32_t input_clk;
+ uint32_t input_vol;
+ uint32_t input_level;
+
+ PP_ASSERT_WITH_CODE(input, "NULL user input for clock and voltage",
+ return -EINVAL);
+
+ if (PHM_ODN_SCLK_VDDC_TABLE == type) {
+ podn_dpm_table_in_backend = &data->odn_dpm_table.odn_core_clock_dpm_levels;
+ podn_vdd_dep_in_backend = &data->odn_dpm_table.vdd_dependency_on_sclk;
+ PP_ASSERT_WITH_CODE((podn_dpm_table_in_backend && podn_vdd_dep_in_backend),
+ "Failed to get ODN SCLK and Voltage tables",
+ return -EINVAL);
+ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
+ } else if (PHM_ODN_MCLK_VDDC_TABLE == type) {
+ podn_dpm_table_in_backend = &data->odn_dpm_table.odn_memory_clock_dpm_levels;
+ podn_vdd_dep_in_backend = &data->odn_dpm_table.vdd_dependency_on_mclk;
+
+ PP_ASSERT_WITH_CODE((podn_dpm_table_in_backend && podn_vdd_dep_in_backend),
+ "Failed to get ODN MCLK and Voltage tables",
+ return -EINVAL);
+ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
+ } else if (PHM_ODN_RESET_DEFAULT_TABLE == type) {
+ smu7_odn_initial_default_setting(hwmgr);
+ data->need_update_smu7_dpm_table |= DPMTABLE_UPDATE_SCLK | DPMTABLE_UPDATE_MCLK;
+ smu_data->avfs.brecalculate_avfs = true;
+ return 0;
+ } else {
+ return -EINVAL;
+ }
+
+ if (hwmgr->pp_table_version == PP_TABLE_V1)
+ pgolden_vdd_dep_table = PHM_ODN_MCLK_VDDC_TABLE == type ?
+ table_info->vdd_dep_on_mclk:
+ table_info->vdd_dep_on_sclk;
+
+ PP_ASSERT_WITH_CODE(pgolden_vdd_dep_table
+ && pgolden_vdd_dep_table->count > 0,
+ "Invalid golden_vdd_dep_table",
+ return -EINVAL);
+
+ for (i = 0; i < size;) {
+ if (i + 3 > size || input[i] >= podn_dpm_table_in_backend->num_of_pl) {
+ pr_info("invalid clock voltage input \n");
+ return 0;
+ }
+ input_level = input[i];
+ input_clk = input[i+1] * 100;
+ input_vol = input[i+2];
+
+ if (smu7_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) {
+ podn_dpm_table_in_backend->entries[input_level].clock = input_clk;
+ podn_vdd_dep_in_backend->entries[input_level].clk = input_clk;
+ podn_dpm_table_in_backend->entries[input_level].vddc = input_vol;
+ podn_vdd_dep_in_backend->entries[input_level].vddc = input_vol;
+ } else {
+ pr_info("invaid input clk/voltage");
+ }
+ i += 3;
+ }
+ smu_data->avfs.brecalculate_avfs = true;
+ return 0;
+}
+
+
static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
.backend_init = &smu7_hwmgr_backend_init,
.backend_fini = &smu7_hwmgr_backend_fini,
@@ -4888,6 +4990,7 @@ static int smu7_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
.notify_cac_buffer_info = smu7_notify_cac_buffer_info,
.get_max_high_clocks = smu7_get_max_high_clocks,
.get_thermal_temperature_range = smu7_get_thermal_temperature_range,
+ .odn_edit_dpm_table = smu7_odn_edit_dpm_table,
};
uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
@@ -4919,4 +5022,3 @@ int smu7_init_function_pointers(struct pp_hwmgr *hwmgr)
return ret;
}
-
--
1.9.1
More information about the amd-gfx
mailing list