diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0292-drm-amd-powerplay-retrieve-the-updated-clock-table-a.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0292-drm-amd-powerplay-retrieve-the-updated-clock-table-a.patch | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0292-drm-amd-powerplay-retrieve-the-updated-clock-table-a.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/0292-drm-amd-powerplay-retrieve-the-updated-clock-table-a.patch new file mode 100644 index 00000000..adf6cd67 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/0292-drm-amd-powerplay-retrieve-the-updated-clock-table-a.patch @@ -0,0 +1,246 @@ +From ec2f724db1af5a2814039365dfbea00fd8659959 Mon Sep 17 00:00:00 2001 +From: Evan Quan <evan.quan@amd.com> +Date: Mon, 17 Sep 2018 14:59:54 +0800 +Subject: [PATCH 0292/2940] drm/amd/powerplay: retrieve the updated clock table + after OD + +With OD settings applied, the clock table will be updated accordingly. +We need to retrieve the new clock tables then. + +Change-Id: Iad4e95d3f195a0217456d41e495730578209062b +Signed-off-by: Evan Quan <evan.quan@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +--- + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 114 ++++++++++++++---- + .../drm/amd/powerplay/hwmgr/vega20_hwmgr.h | 2 + + 2 files changed, 90 insertions(+), 26 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +index 4ab7288a0bd9..7dcfc798728f 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +@@ -514,6 +514,47 @@ static int vega20_setup_single_dpm_table(struct pp_hwmgr *hwmgr, + return ret; + } + ++static int vega20_setup_gfxclk_dpm_table(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = ++ (struct vega20_hwmgr *)(hwmgr->backend); ++ struct vega20_single_dpm_table *dpm_table; ++ int ret = 0; ++ ++ dpm_table = &(data->dpm_table.gfx_table); ++ if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { ++ ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", ++ return ret); ++ } else { ++ dpm_table->count = 1; ++ dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100; ++ } ++ ++ return ret; ++} ++ ++static int vega20_setup_memclk_dpm_table(struct pp_hwmgr *hwmgr) ++{ ++ struct vega20_hwmgr *data = ++ (struct vega20_hwmgr *)(hwmgr->backend); ++ struct vega20_single_dpm_table *dpm_table; ++ int ret = 0; ++ ++ dpm_table = &(data->dpm_table.mem_table); ++ if (data->smu_features[GNLD_DPM_UCLK].enabled) { ++ ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); ++ PP_ASSERT_WITH_CODE(!ret, ++ "[SetupDefaultDpmTable] failed to get memclk dpm levels!", ++ return ret); ++ } else { ++ dpm_table->count = 1; ++ dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100; ++ } ++ ++ return ret; ++} + + /* + * This function is to initialize all DPM state tables +@@ -547,28 +588,16 @@ static int vega20_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) + + /* gfxclk */ + dpm_table = &(data->dpm_table.gfx_table); +- if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { +- ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_GFXCLK); +- PP_ASSERT_WITH_CODE(!ret, +- "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!", +- return ret); +- } else { +- dpm_table->count = 1; +- dpm_table->dpm_levels[0].value = data->vbios_boot_state.gfx_clock / 100; +- } ++ ret = vega20_setup_gfxclk_dpm_table(hwmgr); ++ if (ret) ++ return ret; + vega20_init_dpm_state(&(dpm_table->dpm_state)); + + /* memclk */ + dpm_table = &(data->dpm_table.mem_table); +- if (data->smu_features[GNLD_DPM_UCLK].enabled) { +- ret = vega20_setup_single_dpm_table(hwmgr, dpm_table, PPCLK_UCLK); +- PP_ASSERT_WITH_CODE(!ret, +- "[SetupDefaultDpmTable] failed to get memclk dpm levels!", +- return ret); +- } else { +- dpm_table->count = 1; +- dpm_table->dpm_levels[0].value = data->vbios_boot_state.mem_clock / 100; +- } ++ ret = vega20_setup_memclk_dpm_table(hwmgr); ++ if (ret) ++ return ret; + vega20_init_dpm_state(&(dpm_table->dpm_state)); + + /* eclk */ +@@ -1181,6 +1210,9 @@ static int vega20_od8_set_settings( + { + OverDriveTable_t od_table; + int ret = 0; ++ struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); ++ struct vega20_od8_single_setting *od8_settings = ++ data->od8_settings.od8_settings_array; + + ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)(&od_table), TABLE_OVERDRIVE); + PP_ASSERT_WITH_CODE(!ret, +@@ -1192,6 +1224,10 @@ static int vega20_od8_set_settings( + od_table.GfxclkFmin = (uint16_t)value; + break; + case OD8_SETTING_GFXCLK_FMAX: ++ if (value < od8_settings[OD8_SETTING_GFXCLK_FMAX].min_value || ++ value > od8_settings[OD8_SETTING_GFXCLK_FMAX].max_value) ++ return -EINVAL; ++ + od_table.GfxclkFmax = (uint16_t)value; + break; + case OD8_SETTING_GFXCLK_FREQ1: +@@ -1213,6 +1249,9 @@ static int vega20_od8_set_settings( + od_table.GfxclkVolt3 = (uint16_t)value; + break; + case OD8_SETTING_UCLK_FMAX: ++ if (value < od8_settings[OD8_SETTING_UCLK_FMAX].min_value || ++ value > od8_settings[OD8_SETTING_UCLK_FMAX].max_value) ++ return -EINVAL; + od_table.UclkFmax = (uint16_t)value; + break; + case OD8_SETTING_POWER_PERCENTAGE: +@@ -1262,8 +1301,6 @@ static int vega20_set_sclk_od( + struct pp_hwmgr *hwmgr, uint32_t value) + { + struct vega20_hwmgr *data = hwmgr->backend; +- struct vega20_single_dpm_table *sclk_table = +- &(data->dpm_table.gfx_table); + struct vega20_single_dpm_table *golden_sclk_table = + &(data->golden_dpm_table.gfx_table); + uint32_t od_sclk; +@@ -1278,8 +1315,8 @@ static int vega20_set_sclk_od( + "[SetSclkOD] failed to set od gfxclk!", + return ret); + +- /* refresh gfxclk table */ +- ret = vega20_setup_single_dpm_table(hwmgr, sclk_table, PPCLK_GFXCLK); ++ /* retrieve updated gfxclk table */ ++ ret = vega20_setup_gfxclk_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(!ret, + "[SetSclkOD] failed to refresh gfxclk table!", + return ret); +@@ -1309,8 +1346,6 @@ static int vega20_set_mclk_od( + struct pp_hwmgr *hwmgr, uint32_t value) + { + struct vega20_hwmgr *data = hwmgr->backend; +- struct vega20_single_dpm_table *mclk_table = +- &(data->dpm_table.mem_table); + struct vega20_single_dpm_table *golden_mclk_table = + &(data->golden_dpm_table.mem_table); + uint32_t od_mclk; +@@ -1325,8 +1360,8 @@ static int vega20_set_mclk_od( + "[SetMclkOD] failed to set od memclk!", + return ret); + +- /* refresh memclk table */ +- ret = vega20_setup_single_dpm_table(hwmgr, mclk_table, PPCLK_UCLK); ++ /* retrieve updated memclk table */ ++ ret = vega20_setup_memclk_dpm_table(hwmgr); + PP_ASSERT_WITH_CODE(!ret, + "[SetMclkOD] failed to refresh memclk table!", + return ret); +@@ -2451,6 +2486,10 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + return -EINVAL; + } + ++ if ((input_index == 0 && od_table->GfxclkFmin != input_clk) || ++ (input_index == 1 && od_table->GfxclkFmax != input_clk)) ++ data->gfxclk_overdrive = true; ++ + if (input_index == 0) + od_table->GfxclkFmin = input_clk; + else +@@ -2495,6 +2534,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + return -EINVAL; + } + ++ if (input_index == 1 && od_table->UclkFmax != input_clk) ++ data->memclk_overdrive = true; ++ + od_table->UclkFmax = input_clk; + } + +@@ -2567,6 +2609,9 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + break; + + case PP_OD_RESTORE_DEFAULT_TABLE: ++ data->gfxclk_overdrive = false; ++ data->memclk_overdrive = false; ++ + ret = vega20_copy_table_from_smc(hwmgr, + (uint8_t *)od_table, + TABLE_OVERDRIVE); +@@ -2583,6 +2628,23 @@ static int vega20_odn_edit_dpm_table(struct pp_hwmgr *hwmgr, + "Failed to import overdrive table!", + return ret); + ++ /* retrieve updated gfxclk table */ ++ if (data->gfxclk_overdrive) { ++ data->gfxclk_overdrive = false; ++ ++ ret = vega20_setup_gfxclk_dpm_table(hwmgr); ++ if (ret) ++ return ret; ++ } ++ ++ /* retrieve updated memclk table */ ++ if (data->memclk_overdrive) { ++ data->memclk_overdrive = false; ++ ++ ret = vega20_setup_memclk_dpm_table(hwmgr); ++ if (ret) ++ return ret; ++ } + break; + + default: +diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +index b71a5f25c734..56fe6a0d42e8 100644 +--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h ++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h +@@ -502,6 +502,8 @@ struct vega20_hwmgr { + + /* ---- Overdrive next setting ---- */ + struct vega20_odn_data odn_data; ++ bool gfxclk_overdrive; ++ bool memclk_overdrive; + + /* ---- Overdrive8 Setting ---- */ + struct vega20_od8_settings od8_settings; +-- +2.17.1 + |