On 7/30/19 12:09 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 <[email protected]>
> ---
>   .../drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c   | 17 +++++++++++++++
>   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, 54 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..5b4323b 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,22 @@ 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)

[kevin]:

please take care of code format.

> +{
> +     const struct dc_context *ctx = pp->dm;
> +     struct amdgpu_device *adev = ctx->driver_context;
> +     struct smu_context *smu = &adev->smu;
> +
> +     if (!smu->ppt_funcs)
> +             return PP_SMU_RESULT_UNSUPPORTED;
> +
> +     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 +933,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..642a1b1 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)) : 0)

[kevin]:

could you replace 0 with -EINVAL as default return value. if so, you can 
call this function directly, and not check "!smu->ppt_funct".

>   #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, min_memory_clock, 
> 0);
> +
> +     if(!ret)
> +             smu->disable_uclk_switch = disable_memory_clock_switch;
> +
> +     return ret;
> +}
> +
>   static const struct pptable_funcs navi10_ppt_funcs = {
>       .tables_init = navi10_tables_init,
>       .alloc_dpm_context = navi10_allocate_dpm_context,
> @@ -1693,6 +1717,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
>       .set_ppfeature_status = navi10_set_ppfeature_status,
>       .set_performance_level = navi10_set_performance_level,
>       .get_thermal_temperature_range = navi10_get_thermal_temperature_range,
> +     .display_disable_memory_clock_switch = 
> navi10_display_disable_memory_clock_switch,
>   };
>   
>   void navi10_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 745b35a..202b9d6 100644
> --- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> +++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
> @@ -1346,16 +1346,23 @@ smu_v11_0_display_clock_voltage_request(struct 
> smu_context *smu,
>               if (ret)
>                       goto failed;
>   
> +             if (clk_select == SMU_UCLK && smu->disable_uclk_switch)
> +                     return 0;
> +
>               clk_id = smu_clk_get_index(smu, clk_select);
>               if (clk_id < 0) {
>                       ret = -EINVAL;
>                       goto failed;
>               }
>   
> +
>               mutex_lock(&smu->mutex);
>               ret = smu_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
>                       (clk_id << 16) | clk_freq);
>               mutex_unlock(&smu->mutex);
> +
> +             if(clk_select == SMU_UCLK)
> +                     smu->hard_min_uclk_req_from_dal = clk_freq;
>       }
>   
>   failed:
_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to