Re: [PATCH v2] drm/amdgpu/powerplay: provide the interface to disable uclk switch for DAL

2019-07-30 Thread Kevin Wang
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

2019-07-30 Thread Kenneth Feng
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,