> -----Original Message----- > From: amd-gfx <amd-gfx-bounces@xxxxxxxxxxxxxxxxxxxxx> On Behalf Of > Hersen Wu > Sent: Thursday, October 10, 2019 10:58 PM > To: amd-gfx@xxxxxxxxxxxxxxxxxxxxx > Cc: Wu, Hersen <hersenxs.wu@xxxxxxx>; Wang, Kevin(Yang) > <Kevin1.Wang@xxxxxxx>; Wentland, Harry <Harry.Wentland@xxxxxxx> > Subject: [PATCH] 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@xxxxxxx> > --- > .../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 f4cfa0caeba8..95564b8de3ce 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 > @@ -589,10 +589,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) @@ -665,7 +664,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; > @@ -708,15 +706,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 c9266ea70331..1b71c38cdf96 100644 > --- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > +++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c > @@ -1834,6 +1834,41 @@ int smu_set_mp1_state(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 ccf711c327c8..1469146da1aa 100644 > --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > @@ -468,6 +468,7 @@ struct pptable_funcs { > int (*get_power_limit)(struct smu_context *smu, uint32_t *limit, > bool asic_default); > int (*get_dpm_clk_limited)(struct smu_context *smu, enum > smu_clk_type clk_type, > uint32_t dpm_level, uint32_t *freq); > + int (*get_dpm_clock_table)(struct smu_context *smu, struct > dpm_clocks > +*clock_table); > }; > > struct smu_funcs > @@ -493,7 +494,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); @@ - > 531,8 +531,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); @@ -596,9 +594,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) \ @@ -738,8 +733,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) \ @@ -778,9 +771,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) > > extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t > table, > uint16_t *size, uint8_t *frev, uint8_t *crev, > @@ -814,6 +808,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; > + } > + [Prike] 1)How DC gets the DCF dpm level ? Why the DC DCF dpm level is different from smu12_driver_if.h defined DCF dpm level? 2)Would you like use the CONFIG_DRM_AMD_DC_DCN2_1 guard the interface, otherwise when the driver not enable AMD_DC_DCN2_1 will compile failed. > + 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 c9e90d59a6b8..eff7faa7944e 100644 > --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c > +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c > @@ -770,23 +770,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; > @@ -1336,26 +1319,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; > @@ -1812,7 +1775,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, @@ -1828,7 > +1790,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 > > _______________________________________________ > amd-gfx mailing list > amd-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/amd-gfx _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx