aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch228
1 files changed, 228 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch
new file mode 100644
index 00000000..b93b29d3
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1400-drm-amd-powerplay-add-get_max_sustainable_clock-func.patch
@@ -0,0 +1,228 @@
+From f41763ce29bf15cc7e9a947ce41bd7243a919860 Mon Sep 17 00:00:00 2001
+From: Huang Rui <ray.huang@amd.com>
+Date: Tue, 25 Dec 2018 16:34:39 +0800
+Subject: [PATCH 1400/2940] drm/amd/powerplay: add get_max_sustainable_clock
+ function
+
+This patch adds get_max_sustainable_clock function for smu11.
+
+Signed-off-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/powerplay/amdgpu_smu.c | 9 ++
+ .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 4 +
+ drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h | 8 ++
+ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 114 ++++++++++++++++++
+ 4 files changed, 135 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+index b225cf876a91..cd04369c652b 100644
+--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+@@ -393,6 +393,10 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
+ if (ret)
+ return ret;
+
++ ret = smu_init_max_sustainable_clocks(smu);
++ if (ret)
++ return ret;
++
+ ret = smu_populate_umd_state_clk(smu);
+ if (ret)
+ return ret;
+@@ -539,6 +543,11 @@ static int smu_hw_fini(void *handle)
+ return -EINVAL;
+ kfree(table_context->driver_pptable);
+
++ if (table_context->max_sustainable_clocks) {
++ kfree(table_context->max_sustainable_clocks);
++ table_context->max_sustainable_clocks = NULL;
++ }
++
+ ret = smu_fini_fb_allocations(smu);
+ if (ret)
+ return ret;
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+index a3c8b736af84..a68519ea6dc8 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+@@ -158,6 +158,7 @@ struct smu_table_context
+ void *power_play_table;
+ uint32_t power_play_table_size;
+
++ void *max_sustainable_clocks;
+ struct smu_bios_boot_up_values boot_values;
+ void *driver_pptable;
+ struct smu_table *tables;
+@@ -253,6 +254,7 @@ struct smu_funcs
+ int (*notify_display_change)(struct smu_context *smu);
+ int (*get_power_limit)(struct smu_context *smu);
+ int (*get_current_clk_freq)(struct smu_context *smu, uint32_t clk_id, uint32_t *value);
++ int (*init_max_sustainable_clocks)(struct smu_context *smu);
+ };
+
+ #define smu_init_microcode(smu) \
+@@ -297,6 +299,8 @@ struct smu_funcs
+ ((smu)->funcs->set_last_dcef_min_deep_sleep_clk ? (smu)->funcs->set_last_dcef_min_deep_sleep_clk((smu)) : 0)
+ #define smu_system_features_control(smu, en) \
+ ((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
++#define smu_init_max_sustainable_clocks(smu) \
++ ((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
+ #define smu_send_smc_msg(smu, msg) \
+ ((smu)->funcs->send_smc_msg? (smu)->funcs->send_smc_msg((smu), (msg)) : 0)
+ #define smu_send_smc_msg_with_param(smu, msg, param) \
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+index 2853ab717d80..aa8d81f4111e 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/smu_v11_0.h
+@@ -36,6 +36,14 @@
+ #define smnMP0_FW_INTF 0x30101c0
+ #define smnMP1_PUB_CTRL 0x3010b14
+
++struct smu_11_0_max_sustainable_clocks {
++ uint32_t display_clock;
++ uint32_t phy_clock;
++ uint32_t pixel_clock;
++ uint32_t uclock;
++ uint32_t dcef_clock;
++ uint32_t soc_clock;
++};
+
+ struct smu_11_0_dpm_table {
+ uint32_t min; /* MHz */
+diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+index def64f5a967d..129d2b1c1487 100644
+--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+@@ -738,6 +738,119 @@ static int smu_v11_0_notify_display_change(struct smu_context *smu)
+ return ret;
+ }
+
++static int
++smu_v11_0_get_max_sustainable_clock(struct smu_context *smu, uint32_t *clock,
++ PPCLK_e clock_select)
++{
++ int ret = 0;
++
++ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetDcModeMaxDpmFreq,
++ clock_select << 16);
++ if (ret) {
++ pr_err("[GetMaxSustainableClock] Failed to get max DC clock from SMC!");
++ return ret;
++ }
++
++ ret = smu_read_smc_arg(smu, clock);
++ if (ret)
++ return ret;
++
++ if (*clock != 0)
++ return 0;
++
++ /* if DC limit is zero, return AC limit */
++ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq,
++ clock_select << 16);
++ if (ret) {
++ pr_err("[GetMaxSustainableClock] failed to get max AC clock from SMC!");
++ return ret;
++ }
++
++ ret = smu_read_smc_arg(smu, clock);
++
++ return ret;
++}
++
++static int smu_v11_0_init_max_sustainable_clocks(struct smu_context *smu)
++{
++ struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks;
++ int ret = 0;
++
++ max_sustainable_clocks = kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks),
++ GFP_KERNEL);
++ smu->smu_table.max_sustainable_clocks = (void *)max_sustainable_clocks;
++
++ max_sustainable_clocks->uclock = smu->smu_table.boot_values.uclk / 100;
++ max_sustainable_clocks->soc_clock = smu->smu_table.boot_values.socclk / 100;
++ max_sustainable_clocks->dcef_clock = smu->smu_table.boot_values.dcefclk / 100;
++ max_sustainable_clocks->display_clock = 0xFFFFFFFF;
++ max_sustainable_clocks->phy_clock = 0xFFFFFFFF;
++ max_sustainable_clocks->pixel_clock = 0xFFFFFFFF;
++
++ if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->uclock),
++ PPCLK_UCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max UCLK from SMC!",
++ __func__);
++ return ret;
++ }
++ }
++
++ if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->soc_clock),
++ PPCLK_SOCCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max SOCCLK from SMC!",
++ __func__);
++ return ret;
++ }
++ }
++
++ if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->dcef_clock),
++ PPCLK_DCEFCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max DCEFCLK from SMC!",
++ __func__);
++ return ret;
++ }
++
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->display_clock),
++ PPCLK_DISPCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max DISPCLK from SMC!",
++ __func__);
++ return ret;
++ }
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->phy_clock),
++ PPCLK_PHYCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max PHYCLK from SMC!",
++ __func__);
++ return ret;
++ }
++ ret = smu_v11_0_get_max_sustainable_clock(smu,
++ &(max_sustainable_clocks->pixel_clock),
++ PPCLK_PIXCLK);
++ if (ret) {
++ pr_err("[%s] failed to get max PIXCLK from SMC!",
++ __func__);
++ return ret;
++ }
++ }
++
++ if (max_sustainable_clocks->soc_clock < max_sustainable_clocks->uclock)
++ max_sustainable_clocks->uclock = max_sustainable_clocks->soc_clock;
++
++ return 0;
++}
++
+ static int smu_v11_0_get_power_limit(struct smu_context *smu)
+ {
+ int ret;
+@@ -810,6 +923,7 @@ static const struct smu_funcs smu_v11_0_funcs = {
+ .notify_display_change = smu_v11_0_notify_display_change,
+ .get_power_limit = smu_v11_0_get_power_limit,
+ .get_current_clk_freq = smu_v11_0_get_current_clk_freq,
++ .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
+ };
+
+ void smu_v11_0_set_smu_funcs(struct smu_context *smu)
+--
+2.17.1
+