diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3630-drm-amd-powerplay-add-the-interface-for-getting-ulti.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3630-drm-amd-powerplay-add-the-interface-for-getting-ulti.patch | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3630-drm-amd-powerplay-add-the-interface-for-getting-ulti.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3630-drm-amd-powerplay-add-the-interface-for-getting-ulti.patch new file mode 100644 index 00000000..3ace8410 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3630-drm-amd-powerplay-add-the-interface-for-getting-ulti.patch @@ -0,0 +1,301 @@ +From 1eefdc5b5a8a6f8d30f00c26b4a2a6850fd966c3 Mon Sep 17 00:00:00 2001 +From: Prike Liang <Prike.Liang@amd.com> +Date: Thu, 15 Aug 2019 16:53:08 +0800 +Subject: [PATCH 3630/4256] drm/amd/powerplay: add the interface for getting + ultimate frequency v3 + +add the get_dpm_ultimate_freq for supporting different swSMU. +-v2: + Handle the unsupported clock type and read smc message failed case and return error code. + Move the smu12 uclk frequency retrieved logic to renoir ppt. +-v3: + Use goto clause to handle invalidate clk index. + Add the limited tag for smu_get_dpm_uclk to avoid other likewise interface introduced. + +Signed-off-by: Prike Liang <Prike.Liang@amd.com> +Reviewed-by: Evan Quan <evan.quan@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 38 ++---------- + .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 10 ++- + drivers/gpu/drm/amd/powerplay/renoir_ppt.c | 22 +++++++ + drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 38 ++++++++++++ + drivers/gpu/drm/amd/powerplay/smu_v12_0.c | 62 +++++++++++++++++++ + 5 files changed, 137 insertions(+), 33 deletions(-) + +diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +index 8c61778f8f74..a65c9297e7bd 100644 +--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c ++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c +@@ -231,9 +231,8 @@ int smu_set_hard_freq_range(struct smu_context *smu, enum smu_clk_type clk_type, + int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type, + uint32_t *min, uint32_t *max) + { +- int ret = 0, clk_id = 0; +- uint32_t param = 0; + uint32_t clock_limit; ++ int ret = 0; + + if (!min && !max) + return -EINVAL; +@@ -264,36 +263,11 @@ int smu_get_dpm_freq_range(struct smu_context *smu, enum smu_clk_type clk_type, + + return 0; + } +- +- mutex_lock(&smu->mutex); +- clk_id = smu_clk_get_index(smu, clk_type); +- if (clk_id < 0) { +- ret = -EINVAL; +- goto failed; +- } +- +- param = (clk_id & 0xffff) << 16; +- +- if (max) { +- ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, param); +- if (ret) +- goto failed; +- ret = smu_read_smc_arg(smu, max); +- if (ret) +- goto failed; +- } +- +- if (min) { +- ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param); +- if (ret) +- goto failed; +- ret = smu_read_smc_arg(smu, min); +- if (ret) +- goto failed; +- } +- +-failed: +- mutex_unlock(&smu->mutex); ++ /* ++ * Todo: Use each asic(ASIC_ppt funcs) control the callbacks exposed to the ++ * core driver and then have helpers for stuff that is common(SMU_v11_x | SMU_v12_x funcs). ++ */ ++ ret = smu_get_dpm_ultimate_freq(smu, clk_type, min, max); + 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 c42691a9afd3..320ac20146fd 100644 +--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h ++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +@@ -458,6 +458,7 @@ struct pptable_funcs { + int (*display_disable_memory_clock_switch)(struct smu_context *smu, bool disable_memory_clock_switch); + void (*dump_pptable)(struct smu_context *smu); + int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, bool asic_default); ++ int (*get_dpm_uclk_limited)(struct smu_context *smu, uint32_t *clock, bool max); + }; + + struct smu_funcs +@@ -536,7 +537,7 @@ struct smu_funcs + enum smu_baco_state (*baco_get_state)(struct smu_context *smu); + int (*baco_set_state)(struct smu_context *smu, enum smu_baco_state state); + int (*baco_reset)(struct smu_context *smu); +- ++ int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max); + }; + + #define smu_init_microcode(smu) \ +@@ -745,6 +746,10 @@ struct smu_funcs + ((smu)->funcs->register_irq_handler ? (smu)->funcs->register_irq_handler(smu) : 0) + #define smu_set_azalia_d3_pme(smu) \ + ((smu)->funcs->set_azalia_d3_pme ? (smu)->funcs->set_azalia_d3_pme((smu)) : 0) ++#define smu_get_dpm_ultimate_freq(smu, param, min, max) \ ++ ((smu)->funcs->get_dpm_ultimate_freq ? (smu)->funcs->get_dpm_ultimate_freq((smu), (param), (min), (max)) : 0) ++#define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \ ++ ((smu)->ppt_funcs->get_uclk_dpm_states ? (smu)->ppt_funcs->get_uclk_dpm_states((smu), (clocks_in_khz), (num_states)) : 0) + #define smu_get_max_sustainable_clocks_by_dc(smu, max_clocks) \ + ((smu)->funcs->get_max_sustainable_clocks_by_dc ? (smu)->funcs->get_max_sustainable_clocks_by_dc((smu), (max_clocks)) : 0) + #define smu_get_uclk_dpm_states(smu, clocks_in_khz, num_states) \ +@@ -759,6 +764,9 @@ struct smu_funcs + ((smu)->ppt_funcs->set_performance_level? (smu)->ppt_funcs->set_performance_level((smu), (level)) : -EINVAL); + #define smu_dump_pptable(smu) \ + ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0) ++#define smu_get_dpm_uclk_limited(smu, clock, max) \ ++ ((smu)->ppt_funcs->get_dpm_uclk_limited ? (smu)->ppt_funcs->get_dpm_uclk_limited((smu), (clock), (max)) : -EINVAL) ++ + + extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table, + uint16_t *size, uint8_t *frev, uint8_t *crev, +diff --git a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c +index de43159564a5..2a6da546fb55 100644 +--- a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c ++++ b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c +@@ -156,11 +156,33 @@ static int renoir_tables_init(struct smu_context *smu, struct smu_table *tables) + return 0; + } + ++/** ++ * This interface just for getting uclk ultimate freq and should't introduce ++ * other likewise function result in overmuch callback. ++ */ ++static int renoir_get_dpm_uclk_limited(struct smu_context *smu, uint32_t *clock, bool max) ++{ ++ ++ DpmClocks_t *table = smu->smu_table.clocks_table; ++ ++ if (!clock || !table) ++ return -EINVAL; ++ ++ if (max) ++ *clock = table->FClocks[NUM_FCLK_DPM_LEVELS-1].Freq; ++ else ++ *clock = table->FClocks[0].Freq; ++ ++ return 0; ++ ++} ++ + static const struct pptable_funcs renoir_ppt_funcs = { + .get_smu_msg_index = renoir_get_smu_msg_index, + .get_smu_table_index = renoir_get_smu_table_index, + .tables_init = renoir_tables_init, + .set_power_state = NULL, ++ .get_dpm_uclk_limited = renoir_get_dpm_uclk_limited, + }; + + void renoir_set_ppt_funcs(struct smu_context *smu) +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +index deca9f85764c..117988eb7557 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c +@@ -1717,6 +1717,43 @@ static int smu_v11_0_baco_reset(struct smu_context *smu) + return ret; + } + ++static int smu_v11_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, ++ uint32_t *min, uint32_t *max) ++{ ++ int ret = 0, clk_id = 0; ++ uint32_t param = 0; ++ ++ mutex_lock(&smu->mutex); ++ clk_id = smu_clk_get_index(smu, clk_type); ++ if (clk_id < 0) { ++ ret = -EINVAL; ++ goto failed; ++ } ++ param = (clk_id & 0xffff) << 16; ++ ++ if (max) { ++ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMaxDpmFreq, param); ++ if (ret) ++ goto failed; ++ ret = smu_read_smc_arg(smu, max); ++ if (ret) ++ goto failed; ++ } ++ ++ if (min) { ++ ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param); ++ if (ret) ++ goto failed; ++ ret = smu_read_smc_arg(smu, min); ++ if (ret) ++ goto failed; ++ } ++ ++failed: ++ mutex_unlock(&smu->mutex); ++ return ret; ++} ++ + static const struct smu_funcs smu_v11_0_funcs = { + .init_microcode = smu_v11_0_init_microcode, + .load_microcode = smu_v11_0_load_microcode, +@@ -1766,6 +1803,7 @@ static const struct smu_funcs smu_v11_0_funcs = { + .baco_get_state = smu_v11_0_baco_get_state, + .baco_set_state = smu_v11_0_baco_set_state, + .baco_reset = smu_v11_0_baco_reset, ++ .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, + }; + + void smu_v11_0_set_smu_funcs(struct smu_context *smu) +diff --git a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c +index 0f5d08ae71ae..9d2280ca1f4b 100644 +--- a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c ++++ b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c +@@ -319,6 +319,67 @@ static int smu_v12_0_populate_smc_tables(struct smu_context *smu) + return smu_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, smu_table->clocks_table, false); + } + ++static int smu_v12_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type, ++ uint32_t *min, uint32_t *max) ++{ ++ int ret = 0; ++ ++ mutex_lock(&smu->mutex); ++ ++ if (max) { ++ switch (clk_type) { ++ case SMU_GFXCLK: ++ case SMU_SCLK: ++ ret = smu_send_smc_msg(smu, SMU_MSG_GetMaxGfxclkFrequency); ++ if (ret) { ++ pr_err("Attempt to get max GX frequency from SMC Failed !\n"); ++ goto failed; ++ } ++ ret = smu_read_smc_arg(smu, max); ++ if (ret) ++ goto failed; ++ break; ++ case SMU_UCLK: ++ ret = smu_get_dpm_uclk_limited(smu, max, true); ++ if (ret) ++ goto failed; ++ break; ++ default: ++ ret = -EINVAL; ++ goto failed; ++ ++ } ++ } ++ ++ if (min) { ++ switch (clk_type) { ++ case SMU_GFXCLK: ++ case SMU_SCLK: ++ ret = smu_send_smc_msg(smu, SMU_MSG_GetMinGfxclkFrequency); ++ if (ret) { ++ pr_err("Attempt to get min GX frequency from SMC Failed !\n"); ++ goto failed; ++ } ++ ret = smu_read_smc_arg(smu, min); ++ if (ret) ++ goto failed; ++ break; ++ case SMU_UCLK: ++ ret = smu_get_dpm_uclk_limited(smu, min, false); ++ if (ret) ++ goto failed; ++ break; ++ default: ++ ret = -EINVAL; ++ goto failed; ++ } ++ ++ } ++failed: ++ mutex_unlock(&smu->mutex); ++ return ret; ++} ++ + static const struct smu_funcs smu_v12_0_funcs = { + .check_fw_status = smu_v12_0_check_fw_status, + .check_fw_version = smu_v12_0_check_fw_version, +@@ -332,6 +393,7 @@ static const struct smu_funcs smu_v12_0_funcs = { + .init_smc_tables = smu_v12_0_init_smc_tables, + .fini_smc_tables = smu_v12_0_fini_smc_tables, + .populate_smc_tables = smu_v12_0_populate_smc_tables, ++ .get_dpm_ultimate_freq = smu_v12_0_get_dpm_ultimate_freq, + }; + + void smu_v12_0_set_smu_funcs(struct smu_context *smu) +-- +2.17.1 + |