Re: [PATCH v2] drm/amdgpu/powerplay: provide the interface to disable uclk switch for DAL
It's looks fine for me. Reviewed-by: Kevin Wang Best Regards, Kevin On 7/30/19 2:01 PM, Kenneth Feng wrote: > provide the interface for DAL to disable uclk switch on navi10. > in this case, the uclk will be fixed to maximum. > this is a workaround when display configuration causes underflow issue. > > Signed-off-by: Kenneth Feng > --- > .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 14 > drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 5 + > drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 25 > ++ > drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 7 ++ > 4 files changed, 51 insertions(+) > > 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 7bc7abc..583f8fb 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 > @@ -802,6 +802,19 @@ enum pp_smu_status > pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz) > return PP_SMU_RESULT_OK; > } > > +enum pp_smu_status pp_nv_set_pstate_handshake_support( > + struct pp_smu *pp, BOOLEAN pstate_handshake_supported) > +{ > + const struct dc_context *ctx = pp->dm; > + struct amdgpu_device *adev = ctx->driver_context; > + struct smu_context *smu = >smu; > + > + if (smu_display_disable_memory_clock_switch(smu, > !pstate_handshake_supported)) > + return PP_SMU_RESULT_FAIL; > + > + return PP_SMU_RESULT_OK; > +} > + > enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp, > enum pp_smu_nv_clock_id clock_id, int mhz) > { > @@ -917,6 +930,7 @@ void dm_pp_get_funcs( > funcs->nv_funcs.get_maximum_sustainable_clocks = > pp_nv_get_maximum_sustainable_clocks; > /*todo compare data with window driver */ > funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states; > + funcs->nv_funcs.set_pstate_handshake_support = > pp_nv_set_pstate_handshake_support; > break; > #endif > default: > diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > index 33d2d75..8242cd1 100644 > --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h > @@ -549,6 +549,8 @@ struct smu_context > #define WATERMARKS_EXIST(1 << 0) > #define WATERMARKS_LOADED (1 << 1) > uint32_t watermarks_bitmap; > + uint32_t hard_min_uclk_req_from_dal; > + bool disable_uclk_switch; > > uint32_t workload_mask; > uint32_t workload_prority[WORKLOAD_POLICY_MAX]; > @@ -632,6 +634,7 @@ struct pptable_funcs { > int (*get_uclk_dpm_states)(struct smu_context *smu, uint32_t > *clocks_in_khz, uint32_t *num_states); > int (*set_default_od_settings)(struct smu_context *smu, bool > initialize); > int (*set_performance_level)(struct smu_context *smu, enum > amd_dpm_forced_level level); > + int (*display_disable_memory_clock_switch)(struct smu_context *smu, > bool disable_memory_clock_switch); > }; > > struct smu_funcs > @@ -884,6 +887,8 @@ struct smu_funcs > ((smu)->ppt_funcs->get_clock_by_type_with_voltage ? > (smu)->ppt_funcs->get_clock_by_type_with_voltage((smu), (type), (clocks)) : 0) > #define smu_display_clock_voltage_request(smu, clock_req) \ > ((smu)->funcs->display_clock_voltage_request ? > (smu)->funcs->display_clock_voltage_request((smu), (clock_req)) : 0) > +#define smu_display_disable_memory_clock_switch(smu, > disable_memory_clock_switch) \ > + ((smu)->ppt_funcs->display_disable_memory_clock_switch ? > (smu)->ppt_funcs->display_disable_memory_clock_switch((smu), > (disable_memory_clock_switch)) : -EINVAL) > #define smu_get_dal_power_level(smu, clocks) \ > ((smu)->funcs->get_dal_power_level ? > (smu)->funcs->get_dal_power_level((smu), (clocks)) : 0) > #define smu_get_perf_level(smu, designation, level) \ > diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > index c873228..a8c98c4 100644 > --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c > @@ -1655,6 +1655,30 @@ static int navi10_get_thermal_temperature_range(struct > smu_context *smu, > return 0; > } > > +static int navi10_display_disable_memory_clock_switch(struct smu_context > *smu, > + bool > disable_memory_clock_switch) > +{ > + int ret = 0; > + struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks = > + (struct smu_11_0_max_sustainable_clocks *) > + smu->smu_table.max_sustainable_clocks; > + uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal; > + uint32_t max_memory_clock = max_sustainable_clocks->uclock; > + > +
[PATCH v2] drm/amdgpu/powerplay: provide the interface to disable uclk switch for DAL
provide the interface for DAL to disable uclk switch on navi10. in this case, the uclk will be fixed to maximum. this is a workaround when display configuration causes underflow issue. Signed-off-by: Kenneth Feng --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c | 14 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h | 5 + drivers/gpu/drm/amd/powerplay/navi10_ppt.c | 25 ++ drivers/gpu/drm/amd/powerplay/smu_v11_0.c | 7 ++ 4 files changed, 51 insertions(+) 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 7bc7abc..583f8fb 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 @@ -802,6 +802,19 @@ enum pp_smu_status pp_nv_set_hard_min_uclk_by_freq(struct pp_smu *pp, int mhz) return PP_SMU_RESULT_OK; } +enum pp_smu_status pp_nv_set_pstate_handshake_support( + struct pp_smu *pp, BOOLEAN pstate_handshake_supported) +{ + const struct dc_context *ctx = pp->dm; + struct amdgpu_device *adev = ctx->driver_context; + struct smu_context *smu = >smu; + + if (smu_display_disable_memory_clock_switch(smu, !pstate_handshake_supported)) + return PP_SMU_RESULT_FAIL; + + return PP_SMU_RESULT_OK; +} + enum pp_smu_status pp_nv_set_voltage_by_freq(struct pp_smu *pp, enum pp_smu_nv_clock_id clock_id, int mhz) { @@ -917,6 +930,7 @@ void dm_pp_get_funcs( funcs->nv_funcs.get_maximum_sustainable_clocks = pp_nv_get_maximum_sustainable_clocks; /*todo compare data with window driver */ funcs->nv_funcs.get_uclk_dpm_states = pp_nv_get_uclk_dpm_states; + funcs->nv_funcs.set_pstate_handshake_support = pp_nv_set_pstate_handshake_support; break; #endif default: diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h index 33d2d75..8242cd1 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h @@ -549,6 +549,8 @@ struct smu_context #define WATERMARKS_EXIST (1 << 0) #define WATERMARKS_LOADED (1 << 1) uint32_t watermarks_bitmap; + uint32_t hard_min_uclk_req_from_dal; + bool disable_uclk_switch; uint32_t workload_mask; uint32_t workload_prority[WORKLOAD_POLICY_MAX]; @@ -632,6 +634,7 @@ struct pptable_funcs { int (*get_uclk_dpm_states)(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states); int (*set_default_od_settings)(struct smu_context *smu, bool initialize); int (*set_performance_level)(struct smu_context *smu, enum amd_dpm_forced_level level); + int (*display_disable_memory_clock_switch)(struct smu_context *smu, bool disable_memory_clock_switch); }; struct smu_funcs @@ -884,6 +887,8 @@ struct smu_funcs ((smu)->ppt_funcs->get_clock_by_type_with_voltage ? (smu)->ppt_funcs->get_clock_by_type_with_voltage((smu), (type), (clocks)) : 0) #define smu_display_clock_voltage_request(smu, clock_req) \ ((smu)->funcs->display_clock_voltage_request ? (smu)->funcs->display_clock_voltage_request((smu), (clock_req)) : 0) +#define smu_display_disable_memory_clock_switch(smu, disable_memory_clock_switch) \ + ((smu)->ppt_funcs->display_disable_memory_clock_switch ? (smu)->ppt_funcs->display_disable_memory_clock_switch((smu), (disable_memory_clock_switch)) : -EINVAL) #define smu_get_dal_power_level(smu, clocks) \ ((smu)->funcs->get_dal_power_level ? (smu)->funcs->get_dal_power_level((smu), (clocks)) : 0) #define smu_get_perf_level(smu, designation, level) \ diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c index c873228..a8c98c4 100644 --- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c +++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c @@ -1655,6 +1655,30 @@ static int navi10_get_thermal_temperature_range(struct smu_context *smu, return 0; } +static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, + bool disable_memory_clock_switch) +{ + int ret = 0; + struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks = + (struct smu_11_0_max_sustainable_clocks *) + smu->smu_table.max_sustainable_clocks; + uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal; + uint32_t max_memory_clock = max_sustainable_clocks->uclock; + + if(smu->disable_uclk_switch == disable_memory_clock_switch) + return 0; + + if(disable_memory_clock_switch) + ret = smu_set_hard_freq_range(smu, SMU_UCLK, max_memory_clock, 0); + else + ret = smu_set_hard_freq_range(smu, SMU_UCLK,