aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch376
1 files changed, 376 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch
new file mode 100644
index 00000000..034871d6
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/4138-drm-amdgpu-powerplay-add-renoir-funcs-to-support-dc.patch
@@ -0,0 +1,376 @@
+From c96339fb3bc2f93450f7df258c119580584619f1 Mon Sep 17 00:00:00 2001
+From: Hersen Wu <hersenxs.wu@amd.com>
+Date: Wed, 18 Sep 2019 09:53:30 -0400
+Subject: [PATCH 4138/4736] drm/amdgpu/powerplay: add renoir funcs to support
+ dc
+
+there are two paths for renoir dc access smu.
+one dc access smu directly using bios smc
+interface: set disply, dprefclk, etc.
+another goes through pplib for get dpm clock
+table and set watermmark.
+
+Signed-off-by: Hersen Wu <hersenxs.wu@amd.com>
+Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
+---
+ .../amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 16 +---
+ drivers/gpu/drm/amd/powerplay/amdgpu_smu.c | 35 +++++++
+ .../gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 16 ++--
+ drivers/gpu/drm/amd/powerplay/renoir_ppt.c | 96 +++++++++++++++++++
+ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 39 --------
+ 5 files changed, 141 insertions(+), 61 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+index 33564c707051..8a5eedb6a37a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c
+@@ -590,10 +590,9 @@ void pp_rv_set_wm_ranges(struct pp_smu *pp,
+ if (pp_funcs && pp_funcs->set_watermarks_for_clocks_ranges)
+ pp_funcs->set_watermarks_for_clocks_ranges(pp_handle,
+ &wm_with_clock_ranges);
+- else if (adev->smu.funcs &&
+- adev->smu.funcs->set_watermarks_for_clock_ranges)
++ else
+ smu_set_watermarks_for_clock_ranges(&adev->smu,
+- &wm_with_clock_ranges);
++ &wm_with_clock_ranges);
+ }
+
+ void pp_rv_set_pme_wa_enable(struct pp_smu *pp)
+@@ -666,7 +665,6 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
+ {
+ const struct dc_context *ctx = pp->dm;
+ struct amdgpu_device *adev = ctx->driver_context;
+- struct smu_context *smu = &adev->smu;
+ struct dm_pp_wm_sets_with_clock_ranges_soc15 wm_with_clock_ranges;
+ struct dm_pp_clock_range_for_dmif_wm_set_soc15 *wm_dce_clocks =
+ wm_with_clock_ranges.wm_dmif_clocks_ranges;
+@@ -709,15 +707,7 @@ enum pp_smu_status pp_nv_set_wm_ranges(struct pp_smu *pp,
+ ranges->writer_wm_sets[i].min_drain_clk_mhz * 1000;
+ }
+
+- if (!smu->funcs)
+- return PP_SMU_RESULT_UNSUPPORTED;
+-
+- /* 0: successful or smu.funcs->set_watermarks_for_clock_ranges = NULL;
+- * 1: fail
+- */
+- if (smu_set_watermarks_for_clock_ranges(&adev->smu,
+- &wm_with_clock_ranges))
+- return PP_SMU_RESULT_UNSUPPORTED;
++ smu_set_watermarks_for_clock_ranges(&adev->smu, &wm_with_clock_ranges);
+
+ return PP_SMU_RESULT_OK;
+ }
+diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+index 26cacc899dfe..a5255116785b 100644
+--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
++++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+@@ -1813,6 +1813,41 @@ int smu_set_df_cstate(struct smu_context *smu,
+ return ret;
+ }
+
++int smu_write_watermarks_table(struct smu_context *smu)
++{
++ int ret = 0;
++ struct smu_table_context *smu_table = &smu->smu_table;
++ struct smu_table *table = NULL;
++
++ table = &smu_table->tables[SMU_TABLE_WATERMARKS];
++
++ if (!table->cpu_addr)
++ return -EINVAL;
++
++ ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr,
++ true);
++
++ return ret;
++}
++
++int smu_set_watermarks_for_clock_ranges(struct smu_context *smu,
++ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges)
++{
++ int ret = 0;
++ struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS];
++ void *table = watermarks->cpu_addr;
++
++ if (!smu->disable_watermark &&
++ smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
++ smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
++ smu_set_watermarks_table(smu, table, clock_ranges);
++ smu->watermarks_bitmap |= WATERMARKS_EXIST;
++ smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
++ }
++
++ return ret;
++}
++
+ const struct amd_ip_funcs smu_ip_funcs = {
+ .name = "smu",
+ .early_init = smu_early_init,
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+index cdb845f5f23e..bf13bf33ba0c 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+@@ -470,6 +470,7 @@ struct pptable_funcs {
+ uint32_t dpm_level, uint32_t *freq);
+ int (*set_df_cstate)(struct smu_context *smu, enum pp_df_cstate state);
+ int (*update_pcie_parameters)(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap);
++ int (*get_dpm_clock_table)(struct smu_context *smu, struct dpm_clocks *clock_table);
+ };
+
+ struct smu_funcs
+@@ -495,7 +496,6 @@ struct smu_funcs
+ int (*set_min_dcef_deep_sleep)(struct smu_context *smu);
+ int (*set_tool_table_location)(struct smu_context *smu);
+ int (*notify_memory_pool_location)(struct smu_context *smu);
+- int (*write_watermarks_table)(struct smu_context *smu);
+ int (*set_last_dcef_min_deep_sleep_clk)(struct smu_context *smu);
+ int (*system_features_control)(struct smu_context *smu, bool en);
+ int (*send_smc_msg)(struct smu_context *smu, uint16_t msg);
+@@ -533,8 +533,6 @@ struct smu_funcs
+ int (*get_current_shallow_sleep_clocks)(struct smu_context *smu,
+ struct smu_clock_info *clocks);
+ int (*notify_smu_enable_pwe)(struct smu_context *smu);
+- int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
+- struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
+ int (*conv_power_profile_to_pplib_workload)(int power_profile);
+ uint32_t (*get_fan_control_mode)(struct smu_context *smu);
+ int (*set_fan_control_mode)(struct smu_context *smu, uint32_t mode);
+@@ -599,9 +597,6 @@ struct smu_funcs
+ ((smu)->funcs->notify_memory_pool_location ? (smu)->funcs->notify_memory_pool_location((smu)) : 0)
+ #define smu_gfx_off_control(smu, enable) \
+ ((smu)->funcs->gfx_off_control ? (smu)->funcs->gfx_off_control((smu), (enable)) : 0)
+-
+-#define smu_write_watermarks_table(smu) \
+- ((smu)->funcs->write_watermarks_table ? (smu)->funcs->write_watermarks_table((smu)) : 0)
+ #define smu_set_last_dcef_min_deep_sleep_clk(smu) \
+ ((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) \
+@@ -741,8 +736,6 @@ struct smu_funcs
+ ((smu)->funcs->get_current_shallow_sleep_clocks ? (smu)->funcs->get_current_shallow_sleep_clocks((smu), (clocks)) : 0)
+ #define smu_notify_smu_enable_pwe(smu) \
+ ((smu)->funcs->notify_smu_enable_pwe ? (smu)->funcs->notify_smu_enable_pwe((smu)) : 0)
+-#define smu_set_watermarks_for_clock_ranges(smu, clock_ranges) \
+- ((smu)->funcs->set_watermarks_for_clock_ranges ? (smu)->funcs->set_watermarks_for_clock_ranges((smu), (clock_ranges)) : 0)
+ #define smu_dpm_set_uvd_enable(smu, enable) \
+ ((smu)->ppt_funcs->dpm_set_uvd_enable ? (smu)->ppt_funcs->dpm_set_uvd_enable((smu), (enable)) : 0)
+ #define smu_dpm_set_vce_enable(smu, enable) \
+@@ -781,9 +774,10 @@ struct smu_funcs
+ ((smu)->ppt_funcs->dump_pptable ? (smu)->ppt_funcs->dump_pptable((smu)) : 0)
+ #define smu_get_dpm_clk_limited(smu, clk_type, dpm_level, freq) \
+ ((smu)->ppt_funcs->get_dpm_clk_limited ? (smu)->ppt_funcs->get_dpm_clk_limited((smu), (clk_type), (dpm_level), (freq)) : -EINVAL)
+-
+ #define smu_set_soft_freq_limited_range(smu, clk_type, min, max) \
+ ((smu)->funcs->set_soft_freq_limited_range ? (smu)->funcs->set_soft_freq_limited_range((smu), (clk_type), (min), (max)) : -EINVAL)
++#define smu_get_dpm_clock_table(smu, clock_table) \
++ ((smu)->ppt_funcs->get_dpm_clock_table ? (smu)->ppt_funcs->get_dpm_clock_table((smu), (clock_table)) : -EINVAL)
+
+ #define smu_override_pcie_parameters(smu) \
+ ((smu)->funcs->override_pcie_parameters ? (smu)->funcs->override_pcie_parameters((smu)) : 0)
+@@ -823,6 +817,10 @@ int smu_sys_get_pp_table(struct smu_context *smu, void **table);
+ int smu_sys_set_pp_table(struct smu_context *smu, void *buf, size_t size);
+ int smu_get_power_num_states(struct smu_context *smu, struct pp_states_info *state_info);
+ enum amd_pm_state_type smu_get_current_power_state(struct smu_context *smu);
++int smu_write_watermarks_table(struct smu_context *smu);
++int smu_set_watermarks_for_clock_ranges(
++ struct smu_context *smu,
++ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
+
+ /* smu to display interface */
+ extern int smu_display_configuration_change(struct smu_context *smu, const
+diff --git a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+index 6aedffd739db..fa314c275a82 100644
+--- a/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
++++ b/drivers/gpu/drm/amd/powerplay/renoir_ppt.c
+@@ -416,6 +416,40 @@ static int renoir_get_profiling_clk_mask(struct smu_context *smu,
+ return 0;
+ }
+
++/**
++ * This interface get dpm clock table for dc
++ */
++static int renoir_get_dpm_clock_table(struct smu_context *smu, struct dpm_clocks *clock_table)
++{
++ DpmClocks_t *table = smu->smu_table.clocks_table;
++ int i;
++
++ if (!clock_table || !table)
++ return -EINVAL;
++
++ for (i = 0; i < PP_SMU_NUM_DCFCLK_DPM_LEVELS; i++) {
++ clock_table->DcfClocks[i].Freq = table->DcfClocks[i].Freq;
++ clock_table->DcfClocks[i].Vol = table->DcfClocks[i].Vol;
++ }
++
++ for (i = 0; i < PP_SMU_NUM_SOCCLK_DPM_LEVELS; i++) {
++ clock_table->SocClocks[i].Freq = table->SocClocks[i].Freq;
++ clock_table->SocClocks[i].Vol = table->SocClocks[i].Vol;
++ }
++
++ for (i = 0; i < PP_SMU_NUM_FCLK_DPM_LEVELS; i++) {
++ clock_table->FClocks[i].Freq = table->FClocks[i].Freq;
++ clock_table->FClocks[i].Vol = table->FClocks[i].Vol;
++ }
++
++ for (i = 0; i< PP_SMU_NUM_MEMCLK_DPM_LEVELS; i++) {
++ clock_table->MemClocks[i].Freq = table->MemClocks[i].Freq;
++ clock_table->MemClocks[i].Vol = table->MemClocks[i].Vol;
++ }
++
++ return 0;
++}
++
+ static int renoir_force_clk_levels(struct smu_context *smu,
+ enum smu_clk_type clk_type, uint32_t mask)
+ {
+@@ -546,6 +580,66 @@ static int renoir_set_performance_level(struct smu_context *smu, enum amd_dpm_fo
+ return ret;
+ }
+
++/* save watermark settings into pplib smu structure,
++ * also pass data to smu controller
++ */
++static int renoir_set_watermarks_table(
++ struct smu_context *smu,
++ void *watermarks,
++ struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges)
++{
++ int i;
++ int ret = 0;
++ Watermarks_t *table = watermarks;
++
++ if (!table || !clock_ranges)
++ return -EINVAL;
++
++ if (clock_ranges->num_wm_dmif_sets > 4 ||
++ clock_ranges->num_wm_mcif_sets > 4)
++ return -EINVAL;
++
++ /* save into smu->smu_table.tables[SMU_TABLE_WATERMARKS]->cpu_addr*/
++ for (i = 0; i < clock_ranges->num_wm_dmif_sets; i++) {
++ table->WatermarkRow[WM_DCFCLK][i].MinClock =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_dcfclk_clk_in_khz));
++ table->WatermarkRow[WM_DCFCLK][i].MaxClock =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_dcfclk_clk_in_khz));
++ table->WatermarkRow[WM_DCFCLK][i].MinMclk =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_dmif_clocks_ranges[i].wm_min_mem_clk_in_khz));
++ table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_dmif_clocks_ranges[i].wm_max_mem_clk_in_khz));
++ table->WatermarkRow[WM_DCFCLK][i].WmSetting = (uint8_t)
++ clock_ranges->wm_dmif_clocks_ranges[i].wm_set_id;
++ }
++
++ for (i = 0; i < clock_ranges->num_wm_mcif_sets; i++) {
++ table->WatermarkRow[WM_SOCCLK][i].MinClock =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_socclk_clk_in_khz));
++ table->WatermarkRow[WM_SOCCLK][i].MaxClock =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_socclk_clk_in_khz));
++ table->WatermarkRow[WM_SOCCLK][i].MinMclk =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_mcif_clocks_ranges[i].wm_min_mem_clk_in_khz));
++ table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
++ cpu_to_le16((uint16_t)
++ (clock_ranges->wm_mcif_clocks_ranges[i].wm_max_mem_clk_in_khz));
++ table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t)
++ clock_ranges->wm_mcif_clocks_ranges[i].wm_set_id;
++ }
++
++ /* pass data to smu controller */
++ ret = smu_write_watermarks_table(smu);
++
++ return ret;
++}
++
+ 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,
+@@ -562,6 +656,8 @@ static const struct pptable_funcs renoir_ppt_funcs = {
+ .force_clk_levels = renoir_force_clk_levels,
+ .set_power_profile_mode = renoir_set_power_profile_mode,
+ .set_performance_level = renoir_set_performance_level,
++ .get_dpm_clock_table = renoir_get_dpm_clock_table,
++ .set_watermarks_table = renoir_set_watermarks_table,
+ };
+
+ 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 df1f2b99fed7..ac02bcd24da0 100644
+--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+@@ -771,23 +771,6 @@ static int smu_v11_0_write_pptable(struct smu_context *smu)
+ return ret;
+ }
+
+-static int smu_v11_0_write_watermarks_table(struct smu_context *smu)
+-{
+- int ret = 0;
+- struct smu_table_context *smu_table = &smu->smu_table;
+- struct smu_table *table = NULL;
+-
+- table = &smu_table->tables[SMU_TABLE_WATERMARKS];
+-
+- if (!table->cpu_addr)
+- return -EINVAL;
+-
+- ret = smu_update_table(smu, SMU_TABLE_WATERMARKS, 0, table->cpu_addr,
+- true);
+-
+- return ret;
+-}
+-
+ static int smu_v11_0_set_deep_sleep_dcefclk(struct smu_context *smu, uint32_t clk)
+ {
+ int ret;
+@@ -1337,26 +1320,6 @@ smu_v11_0_display_clock_voltage_request(struct smu_context *smu,
+ return ret;
+ }
+
+-static int
+-smu_v11_0_set_watermarks_for_clock_ranges(struct smu_context *smu, struct
+- dm_pp_wm_sets_with_clock_ranges_soc15
+- *clock_ranges)
+-{
+- int ret = 0;
+- struct smu_table *watermarks = &smu->smu_table.tables[SMU_TABLE_WATERMARKS];
+- void *table = watermarks->cpu_addr;
+-
+- if (!smu->disable_watermark &&
+- smu_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
+- smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
+- smu_set_watermarks_table(smu, table, clock_ranges);
+- smu->watermarks_bitmap |= WATERMARKS_EXIST;
+- smu->watermarks_bitmap &= ~WATERMARKS_LOADED;
+- }
+-
+- return ret;
+-}
+-
+ static int smu_v11_0_gfx_off_control(struct smu_context *smu, bool enable)
+ {
+ int ret = 0;
+@@ -1854,7 +1817,6 @@ static const struct smu_funcs smu_v11_0_funcs = {
+ .parse_pptable = smu_v11_0_parse_pptable,
+ .populate_smc_tables = smu_v11_0_populate_smc_pptable,
+ .write_pptable = smu_v11_0_write_pptable,
+- .write_watermarks_table = smu_v11_0_write_watermarks_table,
+ .set_min_dcef_deep_sleep = smu_v11_0_set_min_dcef_deep_sleep,
+ .set_tool_table_location = smu_v11_0_set_tool_table_location,
+ .init_display_count = smu_v11_0_init_display_count,
+@@ -1870,7 +1832,6 @@ static const struct smu_funcs smu_v11_0_funcs = {
+ .read_sensor = smu_v11_0_read_sensor,
+ .set_deep_sleep_dcefclk = smu_v11_0_set_deep_sleep_dcefclk,
+ .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
+- .set_watermarks_for_clock_ranges = smu_v11_0_set_watermarks_for_clock_ranges,
+ .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
+ .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
+ .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
+--
+2.17.1
+