[PATCH v3 4/4] drm/amd: Validate gfxoff state for smu13

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



GFXOFF may be flushed at suspend entry and it may be important
to ensure it reaches desired target state. In SMU13 designs that
use IMU, validate the state is reached.

This mirrors the implementation done for SMU10 and SMU12.

Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_imu.h       |  1 +
 drivers/gpu/drm/amd/amdgpu/imu_v11_0.c        | 10 +++++
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c    | 42 ++++++++++++++-----
 3 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_imu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_imu.h
index 484e936812e4..cd9c4b77e026 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_imu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_imu.h
@@ -36,6 +36,7 @@ struct amdgpu_imu_funcs {
     int (*start_imu)(struct amdgpu_device *adev);
     void (*program_rlc_ram)(struct amdgpu_device *adev);
     int (*wait_for_reset_status)(struct amdgpu_device *adev);
+    int (*get_gfxoff_status)(struct amdgpu_device *adev);
 };
 
 struct imu_rlc_ram_golden {
diff --git a/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c b/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c
index 4ab90c7852c3..719c4e5c2243 100644
--- a/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c
@@ -375,6 +375,15 @@ static void imu_v11_0_program_rlc_ram(struct amdgpu_device *adev)
 	WREG32_SOC15(GC, 0, regGFX_IMU_RLC_RAM_INDEX, reg_data);
 }
 
+#define GFX_OFF_STATUS_SHIFT		1
+#define GFX_OFF_STATUS_MASK		0x6
+int imu_v11_0_get_gfxoff_status(struct amdgpu_device *adev)
+{
+	uint32_t reg = RREG32_SOC15(GC, 0, regGFX_IMU_MSG_FLAGS);
+
+	return (reg & GFX_OFF_STATUS_MASK) >> GFX_OFF_STATUS_SHIFT;
+}
+
 const struct amdgpu_imu_funcs gfx_v11_0_imu_funcs = {
 	.init_microcode = imu_v11_0_init_microcode,
 	.load_microcode = imu_v11_0_load_microcode,
@@ -382,4 +391,5 @@ const struct amdgpu_imu_funcs gfx_v11_0_imu_funcs = {
 	.start_imu = imu_v11_0_start,
 	.program_rlc_ram = imu_v11_0_program_rlc_ram,
 	.wait_for_reset_status = imu_v11_0_wait_for_reset_status,
+	.get_gfxoff_status = imu_v11_0_get_gfxoff_status,
 };
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
index b24c8549d0b1..31797d629379 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -789,10 +789,16 @@ int smu_v13_0_set_allowed_mask(struct smu_context *smu)
 
 int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable)
 {
-	int ret = 0;
+	int ret = 0, timeout = 500;
 	struct amdgpu_device *adev = smu->adev;
+	int target;
+
+	if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
+		return 0;
 
 	switch (adev->ip_versions[MP1_HWIP][0]) {
+	default:
+		return 0;
 	case IP_VERSION(13, 0, 0):
 	case IP_VERSION(13, 0, 1):
 	case IP_VERSION(13, 0, 3):
@@ -802,18 +808,34 @@ int smu_v13_0_gfx_off_control(struct smu_context *smu, bool enable)
 	case IP_VERSION(13, 0, 8):
 	case IP_VERSION(13, 0, 10):
 	case IP_VERSION(13, 0, 11):
-		if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
-			return 0;
-		if (enable)
-			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL);
-		else
-			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL);
-		break;
-	default:
 		break;
 	}
 
-	return ret;
+	if (enable) {
+		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL);
+		target = 0;
+	} else {
+		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL);
+		target = 3;
+	}
+
+	if (ret)
+		return ret;
+
+	/* confirm gfx is back to intended state, timeout is 0.5 second */
+	if (!adev->gfx.imu.funcs || !adev->gfx.imu.funcs->get_gfxoff_status)
+		return 0;
+
+	while ((adev->gfx.imu.funcs->get_gfxoff_status(adev) != target)) {
+		msleep(1);
+		timeout--;
+		if (timeout == 0) {
+			DRM_ERROR("%s gfxoff timeout and failed!\n", enable ? "enable" : "disable");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
 }
 
 int smu_v13_0_system_features_control(struct smu_context *smu,
-- 
2.34.1




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux