[PATCH 16/26] drm/amd/powerplay: add suspend and resume function for smu

Huang Rui ray.huang at amd.com
Mon Feb 25 12:12:22 UTC 2019


From: Likun Gao <Likun.Gao at amd.com>

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: Likun Gao <Likun.Gao at amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng at amd.com>
---
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c     | 156 ++++++++++++-------------
 drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h |   7 +-
 drivers/gpu/drm/amd/powerplay/smu_v11_0.c      |  27 +++--
 3 files changed, 93 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
index fa0af71..f6e659e 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -533,7 +533,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;
 
@@ -545,54 +546,56 @@ static int smu_smc_table_hw_init(struct smu_context *smu)
 	if (ret)
 		return ret;
 
-	ret = smu_read_pptable_from_vbios(smu);
-	if (ret)
-		return ret;
+	if (initialize) {
+		ret = smu_read_pptable_from_vbios(smu);
+		if (ret)
+			return ret;
 
-	/* get boot_values from vbios to set revision, gfxclk, and etc. */
-	ret = smu_get_vbios_bootup_values(smu);
-	if (ret)
-		return ret;
+		/* get boot_values from vbios to set revision, gfxclk, and etc. */
+		ret = smu_get_vbios_bootup_values(smu);
+		if (ret)
+			return ret;
 
-	ret = smu_get_clk_info_from_vbios(smu);
-	if (ret)
-		return ret;
+		ret = smu_get_clk_info_from_vbios(smu);
+		if (ret)
+			return ret;
 
-	/*
-	 * check if the format_revision in vbios is up to pptable header
-	 * version, and the structure size is not 0.
-	 */
-	ret = smu_get_clk_info_from_vbios(smu);
-	if (ret)
-		return ret;
+		/*
+		 * check if the format_revision in vbios is up to pptable header
+		 * version, and the structure size is not 0.
+		 */
+		ret = smu_get_clk_info_from_vbios(smu);
+		if (ret)
+			return ret;
 
-	ret = smu_check_pptable(smu);
-	if (ret)
-		return ret;
+		ret = smu_check_pptable(smu);
+		if (ret)
+			return ret;
 
-	/*
-	 * allocate vram bos to store smc table contents.
-	 */
-	ret = smu_init_fb_allocations(smu);
-	if (ret)
-		return ret;
+		/*
+		 * allocate vram bos to store smc table contents.
+		 */
+		ret = smu_init_fb_allocations(smu);
+		if (ret)
+			return ret;
 
-	/*
-	 * Parse pptable format and fill PPTable_t smc_pptable to
-	 * smu_table_context structure. And read the smc_dpm_table from vbios,
-	 * then fill it into smc_pptable.
-	 */
-	ret = smu_parse_pptable(smu);
-	if (ret)
-		return ret;
+		/*
+		 * Parse pptable format and fill PPTable_t smc_pptable to
+		 * smu_table_context structure. And read the smc_dpm_table from vbios,
+		 * then fill it into smc_pptable.
+		 */
+		ret = smu_parse_pptable(smu);
+		if (ret)
+			return ret;
 
-	/*
-	 * Send msg GetDriverIfVersion to check if the return value is equal
-	 * with DRIVER_IF_VERSION of smc header.
-	 */
-	ret = smu_check_fw_version(smu);
-	if (ret)
-		return ret;
+		/*
+		 * Send msg GetDriverIfVersion to check if the return value is equal
+		 * with DRIVER_IF_VERSION of smc header.
+		 */
+		ret = smu_check_fw_version(smu);
+		if (ret)
+			return ret;
+	}
 
 	/*
 	 * Copy pptable bo in the vram to smc with SMU MSGs such as
@@ -628,25 +631,29 @@ 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.
 	 */
-	ret = smu_populate_smc_pptable(smu);
-	if (ret)
-		return ret;
+	if (initialize) {
+		ret = smu_populate_smc_pptable(smu);
+		if (ret)
+			return ret;
 
-	ret = smu_init_max_sustainable_clocks(smu);
-	if (ret)
-		return ret;
+		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;
 
-	ret = smu_populate_umd_state_clk(smu);
-	if (ret)
-		return ret;
+	if (initialize) {
+		ret = smu_populate_umd_state_clk(smu);
+		if (ret)
+			return ret;
 
-	ret = smu_get_power_limit(smu, &smu->default_power_limit, false);
-	if (ret)
-		return ret;
+		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.
@@ -718,6 +725,7 @@ static int smu_free_memory_pool(struct smu_context *smu)
 
 	return ret;
 }
+
 static int smu_hw_init(void *handle)
 {
 	int ret;
@@ -745,7 +753,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;
 
@@ -838,11 +846,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;
 }
 
@@ -857,37 +873,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);
-	if (ret)
-		goto failed;
-
-	ret = smu_write_pptable(smu);
+	ret = smu_smc_table_hw_init(smu, false);
 	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;
 
diff --git a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
index dde3c93..87d3320 100644
--- a/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
@@ -523,7 +523,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);
@@ -592,8 +593,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) \
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
index ea5de6e..3faf8fa 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v11_0.c
@@ -1437,26 +1437,29 @@ 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 (table_context->overdrive_table)
-		 return -EINVAL;
+	if (initialize) {
+		if (table_context->overdrive_table)
+			return -EINVAL;
 
-	table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
+		table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
 
-	if (!table_context->overdrive_table)
-		return -ENOMEM;
+		if (!table_context->overdrive_table)
+			return -ENOMEM;
 
-	ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
-	if (ret) {
-		pr_err("Failed to export over drive table!\n");
-		return ret;
-	}
+		ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, false);
+		if (ret) {
+			pr_err("Failed to export over drive table!\n");
+			return ret;
+		}
 
-	smu_set_default_od8_settings(smu);
+		smu_set_default_od8_settings(smu);
+	}
 
 	ret = smu_update_table(smu, TABLE_OVERDRIVE, table_context->overdrive_table, true);
 	if (ret) {
-- 
2.7.4



More information about the amd-gfx mailing list