Commit 4733cc72 authored by Likun Gao's avatar Likun Gao Committed by Alex Deucher
Browse files

drm/amd/powerplay: add suspend and resume function for smu



Functional the function of smu suspend and resume.
Modified the function of smu_smc_table_hw_init to make it useful for smu
resume.

Signed-off-by: default avatarLikun Gao <Likun.Gao@amd.com>
Reviewed-by: default avatarKenneth Feng <kenneth.feng@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9ebbc1bb
Loading
Loading
Loading
Loading
+74 −82
Original line number Diff line number Diff line
@@ -529,7 +529,8 @@ static int smu_fini_fb_allocations(struct smu_context *smu)
	return 0;
}

static int smu_smc_table_hw_init(struct smu_context *smu)
static int smu_smc_table_hw_init(struct smu_context *smu,
				 bool initialize)
{
	int ret;

@@ -541,6 +542,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
	if (ret)
		return ret;

	if (initialize) {
		ret = smu_read_pptable_from_vbios(smu);
		if (ret)
			return ret;
@@ -589,6 +591,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
		ret = smu_check_fw_version(smu);
		if (ret)
			return ret;
	}

	/*
	 * Copy pptable bo in the vram to smc with SMU MSGs such as
@@ -624,6 +627,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
	 * gfxclk, memclk, dcefclk, and etc. And enable the DPM feature for each
	 * type of clks.
	 */
	if (initialize) {
		ret = smu_populate_smc_pptable(smu);
		if (ret)
			return ret;
@@ -631,11 +635,13 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
		ret = smu_init_max_sustainable_clocks(smu);
		if (ret)
			return ret;
	}

	ret = smu_set_od8_default_settings(smu);
	ret = smu_set_od8_default_settings(smu, initialize);
	if (ret)
		return ret;

	if (initialize) {
		ret = smu_populate_umd_state_clk(smu);
		if (ret)
			return ret;
@@ -643,6 +649,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
		ret = smu_get_power_limit(smu, &smu->default_power_limit, false);
		if (ret)
			return ret;
	}

	/*
	 * Set PMSTATUSLOG table bo address with SetToolsDramAddr MSG for tools.
@@ -714,6 +721,7 @@ static int smu_free_memory_pool(struct smu_context *smu)

	return ret;
}

static int smu_hw_init(void *handle)
{
	int ret;
@@ -741,7 +749,7 @@ static int smu_hw_init(void *handle)
	if (ret)
		goto failed;

	ret = smu_smc_table_hw_init(smu);
	ret = smu_smc_table_hw_init(smu, true);
	if (ret)
		goto failed;

@@ -834,11 +842,19 @@ int smu_reset(struct smu_context *smu)

static int smu_suspend(void *handle)
{
	int ret;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct smu_context *smu = &adev->smu;

	if (!is_support_sw_smu(adev))
		return -EINVAL;

	ret = smu_feature_disable_all(smu);
	if (ret)
		return ret;

	smu->watermarks_bitmap &= ~(WATERMARKS_LOADED);

	return 0;
}

@@ -853,37 +869,13 @@ static int smu_resume(void *handle)

	pr_info("SMU is resuming...\n");

	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
		ret = smu_load_microcode(smu);
		if (ret)
			return ret;
	}

	ret = smu_check_fw_status(smu);
	if (ret) {
		pr_err("SMC firmware status is not correct\n");
		return ret;
	}

	mutex_lock(&smu->mutex);

	ret = smu_set_tool_table_location(smu);
	ret = smu_smc_table_hw_init(smu, false);
	if (ret)
		goto failed;

	ret = smu_write_pptable(smu);
	if (ret)
		goto failed;

	ret = smu_write_watermarks_table(smu);
	if (ret)
		goto failed;

	ret = smu_set_last_dcef_min_deep_sleep_clk(smu);
	if (ret)
		goto failed;

	ret = smu_system_features_control(smu, true);
	ret = smu_start_thermal_control(smu);
	if (ret)
		goto failed;

+4 −3
Original line number Diff line number Diff line
@@ -518,7 +518,8 @@ struct smu_funcs
	int (*notify_smu_enable_pwe)(struct smu_context *smu);
	int (*set_watermarks_for_clock_ranges)(struct smu_context *smu,
					       struct dm_pp_wm_sets_with_clock_ranges_soc15 *clock_ranges);
	int (*set_od8_default_settings)(struct smu_context *smu);
	int (*set_od8_default_settings)(struct smu_context *smu,
					bool initialize);
	int (*get_activity_monitor_coeff)(struct smu_context *smu,
				      uint8_t *table,
				      uint16_t workload_type);
@@ -587,8 +588,8 @@ struct smu_funcs
	((smu)->funcs->system_features_control ? (smu)->funcs->system_features_control((smu), (en)) : 0)
#define smu_init_max_sustainable_clocks(smu) \
	((smu)->funcs->init_max_sustainable_clocks ? (smu)->funcs->init_max_sustainable_clocks((smu)) : 0)
#define smu_set_od8_default_settings(smu) \
	((smu)->funcs->set_od8_default_settings ? (smu)->funcs->set_od8_default_settings((smu)) : 0)
#define smu_set_od8_default_settings(smu, initialize) \
	((smu)->funcs->set_od8_default_settings ? (smu)->funcs->set_od8_default_settings((smu), (initialize)) : 0)
#define smu_update_od8_settings(smu, index, value) \
	((smu)->funcs->update_od8_settings ? (smu)->funcs->update_od8_settings((smu), (index), (value)) : 0)
#define smu_get_current_rpm(smu, speed) \
+15 −12
Original line number Diff line number Diff line
@@ -1432,11 +1432,13 @@ static uint32_t smu_v11_0_dpm_get_mclk(struct smu_context *smu, bool low)
	return (mem_clk * 100);
}

static int smu_v11_0_set_od8_default_settings(struct smu_context *smu)
static int smu_v11_0_set_od8_default_settings(struct smu_context *smu,
					      bool initialize)
{
	struct smu_table_context *table_context = &smu->smu_table;
	int ret;

	if (initialize) {
		if (table_context->overdrive_table)
			return -EINVAL;

@@ -1452,6 +1454,7 @@ static int smu_v11_0_set_od8_default_settings(struct smu_context *smu)
		}

		smu_set_default_od8_settings(smu);
	}

	ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
	if (ret) {