summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_pp_smu.c14
-rw-r--r--drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h5
-rw-r--r--drivers/gpu/drm/amd/powerplay/navi10_ppt.c25
-rw-r--r--drivers/gpu/drm/amd/powerplay/smu_v11_0.c7
4 files changed, 51 insertions, 0 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 592fa499c9f8..e4d0b5b845c5 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
@@ -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:
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index ac9e9d5d8a5c..fcd0db362977 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -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) \
diff --git a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
index 5a0b14f1c4f7..b92e109ed46d 100644
--- a/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
+++ b/drivers/gpu/drm/amd/powerplay/navi10_ppt.c
@@ -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)
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index be93b3b9fd58..89f4c9e19642 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -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: