aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch205
1 files changed, 205 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch
new file mode 100644
index 00000000..35cc81ec
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3225-drm-amd-pp-Implement-edit_dpm_table-on-smu7.patch
@@ -0,0 +1,205 @@
+From fe4c94bc67f52aba126bd8e46099f6ca2ebcfdce Mon Sep 17 00:00:00 2001
+From: Rex Zhu <Rex.Zhu@amd.com>
+Date: Tue, 16 Jan 2018 16:04:43 +0800
+Subject: [PATCH 3225/4131] drm/amd/pp: Implement edit_dpm_table on smu7
+
+v2: - check clk against OverDrive limits from VBIOS
+ - set OD flag when user commit the setting.
+
+Change-Id: I940324de6205ff210a26e530881131f0509b7011
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 165 ++++++++++++++++++++++-
+ 1 file changed, 164 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 a64a7c2..288669a 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
+@@ -4804,6 +4804,169 @@ 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 PP_OD_DPM_TABLE_COMMAND type,
++ uint32_t clk,
++ uint32_t voltage)
++{
++ struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
++
++ struct phm_ppt_v1_information *table_info =
++ (struct phm_ppt_v1_information *)(hwmgr->pptable);
++ uint32_t min_vddc;
++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_sclk_table;
++
++ if (table_info == NULL)
++ return -EINVAL;
++
++ dep_sclk_table = table_info->vdd_dep_on_sclk;
++ min_vddc = dep_sclk_table->entries[0].vddc;
++
++ if (voltage < min_vddc || voltage > 2000) {
++ pr_info("OD voltage is out of range [%d - 2000] mV\n", min_vddc);
++ return false;
++ }
++
++ if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
++ if (data->vbios_boot_state.sclk_bootup_value > clk ||
++ hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
++ pr_info("OD engine clock is out of range [%d - %d] MHz\n",
++ data->vbios_boot_state.sclk_bootup_value,
++ hwmgr->platform_descriptor.overdriveLimit.engineClock / 100);
++ return false;
++ }
++ } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
++ if (data->vbios_boot_state.mclk_bootup_value > clk ||
++ hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
++ pr_info("OD memory clock is out of range [%d - %d] MHz\n",
++ data->vbios_boot_state.mclk_bootup_value/100,
++ hwmgr->platform_descriptor.overdriveLimit.memoryClock / 100);
++ return false;
++ }
++ } else {
++ return false;
++ }
++
++ return true;
++}
++
++static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
++{
++ struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
++ struct smu7_odn_dpm_table *odn_table = &(data->odn_dpm_table);
++ struct phm_ppt_v1_information *table_info =
++ (struct phm_ppt_v1_information *)(hwmgr->pptable);
++ uint32_t i;
++
++ struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;
++ struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;
++
++ if (table_info == NULL)
++ return;
++
++ for (i=0; i<data->dpm_table.sclk_table.count; i++) {
++ if (odn_table->odn_core_clock_dpm_levels.entries[i].clock !=
++ data->dpm_table.sclk_table.dpm_levels[i].value) {
++ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
++ break;
++ }
++ }
++
++ for (i=0; i<data->dpm_table.sclk_table.count; i++) {
++ if (odn_table->odn_memory_clock_dpm_levels.entries[i].clock !=
++ data->dpm_table.mclk_table.dpm_levels[i].value) {
++ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
++ break;
++ }
++ }
++
++ dep_table = table_info->vdd_dep_on_mclk;
++ odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_mclk);
++
++ for (i=0; i<dep_table->count; i++) {
++ if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
++ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
++ return;
++ }
++ }
++
++ dep_table = table_info->vdd_dep_on_sclk;
++ odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
++ for (i=0; i<dep_table->count; i++) {
++ if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
++ data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
++ return;
++ }
++ }
++}
++
++static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
++ enum PP_OD_DPM_TABLE_COMMAND type,
++ long *input, uint32_t size)
++{
++ uint32_t i;
++ 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);
++
++ 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 (!hwmgr->od_enabled) {
++ pr_info("OverDrive feature not enabled\n");
++ return -EINVAL;
++ }
++
++ if (PP_OD_EDIT_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);
++ } else if (PP_OD_EDIT_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);
++ } else if (PP_OD_RESTORE_DEFAULT_TABLE == type) {
++ smu7_odn_initial_default_setting(hwmgr);
++ return 0;
++ } else if (PP_OD_COMMIT_DPM_TABLE == type) {
++ smu7_check_dpm_table_updated(hwmgr);
++ return 0;
++ } else {
++ return -EINVAL;
++ }
++
++ for (i = 0; i < size; i += 3) {
++ 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 {
++ return -EINVAL;
++ }
++ }
++
++ return 0;
++}
++
++
+ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
+ .backend_init = &smu7_hwmgr_backend_init,
+ .backend_fini = &smu7_hwmgr_backend_fini,
+@@ -4858,6 +5021,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
+ .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,
+@@ -4889,4 +5053,3 @@ int smu7_init_function_pointers(struct pp_hwmgr *hwmgr)
+
+ return ret;
+ }
+-
+--
+2.7.4
+