diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1457-drm-amd-powerplay-add-sys-interface-for-set-sclk_od-.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1457-drm-amd-powerplay-add-sys-interface-for-set-sclk_od-.patch | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1457-drm-amd-powerplay-add-sys-interface-for-set-sclk_od-.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1457-drm-amd-powerplay-add-sys-interface-for-set-sclk_od-.patch new file mode 100644 index 00000000..a216b8b5 --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1457-drm-amd-powerplay-add-sys-interface-for-set-sclk_od-.patch @@ -0,0 +1,180 @@ +From 75513fc13e96e26494024273e39af196becfdf10 Mon Sep 17 00:00:00 2001 +From: Likun Gao <Likun.Gao@amd.com> +Date: Fri, 18 Jan 2019 16:15:14 +0800 +Subject: [PATCH 1457/2940] drm/amd/powerplay: add sys interface for set + sclk_od/mclk_od for smu + +Add sys interface for set pp_sclk_od and pp_mclk_od for smu. + +Signed-off-by: Likun Gao <Likun.Gao@amd.com> +Reviewed-by: Huang Rui <ray.huang@amd.com> +Reviewed-by: Kevin Wang <kevin1.wang@amd.com> +Acked-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c | 34 ++++++---- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 5 ++ + drivers/gpu/drm/amd/powerplay/vega20_ppt.c | 62 +++++++++++++++++++ + 3 files changed, 89 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +index 52cb63030b9a..eb17ab94e4bf 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c +@@ -1069,14 +1069,19 @@ static ssize_t amdgpu_set_pp_sclk_od(struct device *dev, + count = -EINVAL; + goto fail; + } +- if (adev->powerplay.pp_funcs->set_sclk_od) +- amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); + +- if (adev->powerplay.pp_funcs->dispatch_tasks) { +- amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL); ++ if (is_support_sw_smu(adev)) { ++ value = smu_set_od_percentage(&(adev->smu), OD_SCLK, (uint32_t)value); + } else { +- adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; +- amdgpu_pm_compute_clocks(adev); ++ if (adev->powerplay.pp_funcs->set_sclk_od) ++ amdgpu_dpm_set_sclk_od(adev, (uint32_t)value); ++ ++ if (adev->powerplay.pp_funcs->dispatch_tasks) { ++ amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL); ++ } else { ++ adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; ++ amdgpu_pm_compute_clocks(adev); ++ } + } + + fail: +@@ -1115,14 +1120,19 @@ static ssize_t amdgpu_set_pp_mclk_od(struct device *dev, + count = -EINVAL; + goto fail; + } +- if (adev->powerplay.pp_funcs->set_mclk_od) +- amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); + +- if (adev->powerplay.pp_funcs->dispatch_tasks) { +- amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL); ++ if (is_support_sw_smu(adev)) { ++ value = smu_set_od_percentage(&(adev->smu), OD_MCLK, (uint32_t)value); + } else { +- adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; +- amdgpu_pm_compute_clocks(adev); ++ if (adev->powerplay.pp_funcs->set_mclk_od) ++ amdgpu_dpm_set_mclk_od(adev, (uint32_t)value); ++ ++ if (adev->powerplay.pp_funcs->dispatch_tasks) { ++ amdgpu_dpm_dispatch_task(adev, AMD_PP_TASK_READJUST_POWER_STATE, NULL); ++ } else { ++ adev->pm.dpm.current_ps = adev->pm.dpm.boot_ps; ++ amdgpu_pm_compute_clocks(adev); ++ } + } + + fail: +diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +index d824739f7408..c3bc9a7e3f48 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -414,6 +414,9 @@ struct pptable_funcs { + uint32_t index, + uint32_t value); + int (*get_od_percentage)(struct smu_context *smu, enum pp_clock_type type); ++ int (*set_od_percentage)(struct smu_context *smu, ++ enum pp_clock_type type, ++ uint32_t value); + int (*get_clock_by_type_with_latency)(struct smu_context *smu, + enum amd_pp_clock_type type, + struct +@@ -598,6 +601,8 @@ struct smu_funcs + ((smu)->ppt_funcs->force_clk_levels ? (smu)->ppt_funcs->force_clk_levels((smu), (type), (level)) : 0) + #define smu_get_od_percentage(smu, type) \ + ((smu)->ppt_funcs->get_od_percentage ? (smu)->ppt_funcs->get_od_percentage((smu), (type)) : 0) ++#define smu_set_od_percentage(smu, type, value) \ ++ ((smu)->ppt_funcs->set_od_percentage ? (smu)->ppt_funcs->set_od_percentage((smu), (type), (value)) : 0) + #define smu_start_thermal_control(smu) \ + ((smu)->funcs->start_thermal_control? (smu)->funcs->start_thermal_control((smu)) : 0) + #define smu_read_sensor(smu, sensor, data, size) \ +diff --git a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +index d5469fccfffc..d025f54285ed 100644 +--- a/drivers/gpu/drm/amd/powerplay/vega20_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/vega20_ppt.c +@@ -1924,6 +1924,67 @@ static int vega20_update_specified_od8_value(struct smu_context *smu, + return 0; + } + ++static int vega20_set_od_percentage(struct smu_context *smu, ++ enum pp_clock_type type, ++ uint32_t value) ++{ ++ struct smu_dpm_context *smu_dpm = &smu->smu_dpm; ++ struct vega20_dpm_table *dpm_table = NULL; ++ struct vega20_dpm_table *golden_table = NULL; ++ struct vega20_single_dpm_table *single_dpm_table; ++ struct vega20_single_dpm_table *golden_dpm_table; ++ uint32_t od_clk, index; ++ int ret, feature_enabled; ++ PPCLK_e clk_id; ++ ++ dpm_table = smu_dpm->dpm_context; ++ golden_table = smu_dpm->golden_dpm_context; ++ ++ switch (type) { ++ case OD_SCLK: ++ single_dpm_table = &(dpm_table->gfx_table); ++ golden_dpm_table = &(golden_table->gfx_table); ++ feature_enabled = smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT); ++ clk_id = PPCLK_GFXCLK; ++ index = OD8_SETTING_GFXCLK_FMAX; ++ break; ++ case OD_MCLK: ++ single_dpm_table = &(dpm_table->mem_table); ++ golden_dpm_table = &(golden_table->mem_table); ++ feature_enabled = smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT); ++ clk_id = PPCLK_UCLK; ++ index = OD8_SETTING_UCLK_FMAX; ++ break; ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ od_clk = golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value * value; ++ od_clk /= 100; ++ od_clk += golden_dpm_table->dpm_levels[golden_dpm_table->count - 1].value; ++ ++ ret = smu_update_od8_settings(smu, index, od_clk); ++ if (ret) { ++ pr_err("[Setoverdrive] failed to set od clk!\n"); ++ return ret; ++ } ++ ++ if (feature_enabled) { ++ ret = vega20_set_single_dpm_table(smu, single_dpm_table, ++ clk_id); ++ if (ret) { ++ pr_err("[Setoverdrive] failed to refresh dpm table!\n"); ++ return ret; ++ } ++ } else { ++ single_dpm_table->count = 1; ++ single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100; ++ } ++ ++ return 0; ++} ++ + static const struct pptable_funcs vega20_ppt_funcs = { + .alloc_dpm_context = vega20_allocate_dpm_context, + .store_powerplay_table = vega20_store_powerplay_table, +@@ -1944,6 +2005,7 @@ static const struct pptable_funcs vega20_ppt_funcs = { + .get_performance_level = vega20_get_performance_level, + .force_performance_level = vega20_force_performance_level, + .update_specified_od8_value = vega20_update_specified_od8_value, ++ .set_od_percentage = vega20_set_od_percentage, + }; + + void vega20_set_ppt_funcs(struct smu_context *smu) +-- +2.17.1 + |