mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-04 16:25:34 +00:00
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 <kenneth.feng@amd.com> Reviewed-by: Kevin Wang <kevin1.wang@amd.com> Reviewed-by: Evan Quan <evan.quan@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c74dbe44ea
commit
6e92e156aa
4 changed files with 51 additions and 0 deletions
|
@ -801,6 +801,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 = &adev->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)
|
||||
{
|
||||
|
@ -916,6 +929,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:
|
||||
|
|
|
@ -365,6 +365,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];
|
||||
|
@ -446,6 +448,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
|
||||
|
@ -695,6 +698,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) \
|
||||
|
|
|
@ -1493,6 +1493,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,
|
||||
|
@ -1529,6 +1553,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
|
|||
.get_uclk_dpm_states = navi10_get_uclk_dpm_states,
|
||||
.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)
|
||||
|
|
|
@ -1313,16 +1313,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:
|
||||
|
|
Loading…
Add table
Reference in a new issue