[12/37] drm/amdgpu: add and enable gfxoff feature

Submitted by Alex Deucher on Aug. 21, 2019, 10:23 p.m.

Details

Message ID 20190821222359.13578-13-alexander.deucher@amd.com
State New
Headers show
Series "Enable power features for Renoir" ( rev: 1 ) in AMD X.Org drivers

Not browsing as part of any series.

Commit Message

Alex Deucher Aug. 21, 2019, 10:23 p.m.
From: Aaron Liu <aaron.liu@amd.com>

This patch updates gfxoff feature.

Signed-off-by: Aaron Liu <aaron.liu@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Reviewed-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Kevin Wang <kevin1.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/soc15.c         |  5 +++
 drivers/gpu/drm/amd/powerplay/amdgpu_smu.c |  1 -
 drivers/gpu/drm/amd/powerplay/smu_v12_0.c  | 44 ++++++++++++++++++++++
 3 files changed, 49 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c
index b226883039e4..c092be45f5e2 100644
--- a/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ b/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -1157,6 +1157,11 @@  static int soc15_common_early_init(void *handle)
 		adev->cg_flags = 0;
 		adev->pg_flags = 0;
 		adev->external_rev_id = adev->rev_id + 0x91;
+
+		if (adev->pm.pp_feature & PP_GFXOFF_MASK)
+			adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
+				AMD_PG_SUPPORT_CP |
+				AMD_PG_SUPPORT_RLC_SMU_HS;
 		break;
 	default:
 		/* FIXME: not supported yet */
diff --git a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
index 85f52401d5a1..6505690cfa76 100644
--- a/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
+++ b/drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
@@ -737,7 +737,6 @@  static int smu_set_funcs(struct amdgpu_device *adev)
 		smu_v11_0_set_smu_funcs(smu);
 		break;
 	case CHIP_RENOIR:
-		adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
 		if (adev->pm.pp_feature & PP_OVERDRIVE_MASK)
 			smu->od_enabled = true;
 		smu_v12_0_set_smu_funcs(smu);
diff --git a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
index cf523b8b2aeb..7d4e966cc9f0 100644
--- a/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
+++ b/drivers/gpu/drm/amd/powerplay/smu_v12_0.c
@@ -36,6 +36,13 @@ 
 
 #define smnMP1_FIRMWARE_FLAGS                                0x3010024
 
+#define mmPWR_MISC_CNTL_STATUS					0x0183
+#define mmPWR_MISC_CNTL_STATUS_BASE_IDX				0
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT	0x0
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT		0x1
+#define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK		0x00000001L
+#define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK		0x00000006L
+
 static int smu_v12_0_send_msg_without_waiting(struct smu_context *smu,
 					      uint16_t msg)
 {
@@ -207,6 +214,42 @@  static int smu_v12_0_set_gfx_cgpg(struct smu_context *smu, bool enable)
 		SMU_MSG_SetGfxCGPG, enable ? 1 : 0);
 }
 
+static bool smu_v12_0_is_gfx_on(struct smu_context *smu)
+{
+	uint32_t reg;
+	struct amdgpu_device *adev = smu->adev;
+
+	reg = RREG32_SOC15(PWR, 0, mmPWR_MISC_CNTL_STATUS);
+	if ((reg & PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK) ==
+	    (0x2 << PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT))
+		return true;
+
+	return false;
+}
+
+static int smu_v12_0_gfx_off_control(struct smu_context *smu, bool enable)
+{
+	int ret = 0, timeout = 10;
+
+	if (enable) {
+		ret = smu_send_smc_msg(smu, SMU_MSG_AllowGfxOff);
+	} else {
+		ret = smu_send_smc_msg(smu, SMU_MSG_DisallowGfxOff);
+
+		/* confirm gfx is back to "on" state */
+		while (!smu_v12_0_is_gfx_on(smu)) {
+			msleep(1);
+			timeout--;
+			if (timeout == 0) {
+				DRM_ERROR("disable gfxoff timeout and failed!\n");
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
 static const struct smu_funcs smu_v12_0_funcs = {
 	.check_fw_status = smu_v12_0_check_fw_status,
 	.check_fw_version = smu_v12_0_check_fw_version,
@@ -216,6 +259,7 @@  static const struct smu_funcs smu_v12_0_funcs = {
 	.send_smc_msg_with_param = smu_v12_0_send_msg_with_param,
 	.read_smc_arg = smu_v12_0_read_arg,
 	.set_gfx_cgpg = smu_v12_0_set_gfx_cgpg,
+	.gfx_off_control = smu_v12_0_gfx_off_control,
 };
 
 void smu_v12_0_set_smu_funcs(struct smu_context *smu)