[PATCH 4/4] drm/amd/powerplay: Fix PG/CG for UVD

Tom St Denis tstdenis82 at gmail.com
Wed Jul 27 16:21:02 UTC 2016


This patch removes the enable_clock_power_gatings_tasks
task from the initialize sequence which would have powered
off the UVD (and other) blocks before init.

The patch also fixes the power up order to set the clockgating
after ungating power.

Finally, the patch enables UVD PG with powerplay enabled.

Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h                |  5 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c            |  5 -----
 drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c              |  4 ++--
 drivers/gpu/drm/amd/amdgpu/vi.c                    | 12 ++++--------
 .../drm/amd/powerplay/eventmgr/eventactionchains.c |  1 -
 .../drm/amd/powerplay/hwmgr/cz_clockpowergating.c  | 22 ++++++++++++++++++----
 6 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index d0460ea2f85b..46d30100c41b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2518,5 +2518,10 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev );
 static inline int amdgpu_dm_display_resume(struct amdgpu_device *adev) { return 0; }
 #endif
 
+struct amdgpu_cgs_device {
+	struct cgs_device base;
+	struct amdgpu_device *adev;
+};
+
 #include "amdgpu_object.h"
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index ee95e950a19b..d553e399a835 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -33,11 +33,6 @@
 #include "atom.h"
 #include "amdgpu_ucode.h"
 
-struct amdgpu_cgs_device {
-	struct cgs_device base;
-	struct amdgpu_device *adev;
-};
-
 #define CGS_FUNC_ADEV							\
 	struct amdgpu_device *adev =					\
 		((struct amdgpu_cgs_device *)cgs_device)->adev
diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
index 422d5300b92e..a73d8199c486 100644
--- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
@@ -389,9 +389,9 @@ static int uvd_v6_0_start(struct amdgpu_device *adev)
 	uint32_t mp_swap_cntl;
 	int i, j, r;
 
-	/* is power gated? then we can't start (TODO: re-enable power) */
+	/* is power gated? then we can't start but don't return an error */
 	if (adev->uvd.pg_state)
-		return -EINVAL;
+		return 0;
 
 	/* set CG state to -1 for unset */
 	adev->uvd.cg_state = -1;
diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
index 3af4f204810f..a89aa8a266c3 100644
--- a/drivers/gpu/drm/amd/amdgpu/vi.c
+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -1583,10 +1583,8 @@ static int vi_common_early_init(void *handle)
 		if (adev->rev_id != 0x00) {
 			adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
 				AMD_PG_SUPPORT_GFX_SMG |
-				AMD_PG_SUPPORT_GFX_PIPELINE;
-			/* powerplay UVD PG doesn't work yet */
-			if (!amdgpu_powerplay)
-				adev->pg_flags |= AMD_PG_SUPPORT_UVD;
+				AMD_PG_SUPPORT_GFX_PIPELINE |
+				AMD_PG_SUPPORT_UVD;
 		}
 		adev->external_rev_id = adev->rev_id + 0x1;
 		break;
@@ -1608,10 +1606,8 @@ static int vi_common_early_init(void *handle)
 			AMD_CG_SUPPORT_SDMA_LS;
 		adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
 			AMD_PG_SUPPORT_GFX_SMG |
-			AMD_PG_SUPPORT_GFX_PIPELINE;
-		/* powerplay UVD PG doesn't work yet */
-		if (!amdgpu_powerplay)
-			adev->pg_flags |= AMD_PG_SUPPORT_UVD;
+			AMD_PG_SUPPORT_GFX_PIPELINE |
+			AMD_PG_SUPPORT_UVD;
 		adev->external_rev_id = adev->rev_id + 0x1;
 		break;
 	default:
diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
index d6635cc4b0fc..a42090a608e7 100644
--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
+++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
@@ -30,7 +30,6 @@ static const pem_event_action * const initialize_event[] = {
 	system_config_tasks,
 	setup_asic_tasks,
 	enable_dynamic_state_management_tasks,
-	enable_clock_power_gatings_tasks,
 	get_2d_performance_state_tasks,
 	set_performance_state_tasks,
 	initialize_thermal_controller_tasks,
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c
index 2da548f6337e..1f0190a5b00f 100644
--- a/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c
+++ b/drivers/gpu/drm/amd/powerplay/hwmgr/cz_clockpowergating.c
@@ -21,9 +21,13 @@
  *
  */
 
+#include "amdgpu.h"
 #include "hwmgr.h"
 #include "cz_clockpowergating.h"
 #include "cz_ppsmc.h"
+#include "cgs_linux.h"
+#include "uvd/uvd_6_0_d.h"
+#include "uvd/uvd_6_0_sh_mask.h"
 
 /* PhyID -> Status Mapping in DDI_PHY_GEN_STATUS
     0    GFX0L (3:0),                  (27:24),
@@ -160,12 +164,21 @@ int cz_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
 int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
 {
 	struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
+	struct amdgpu_cgs_device *cgs_dev = hwmgr->device;
+	struct amdgpu_device *adev = cgs_dev->adev;
 
-	if (cz_hwmgr->uvd_power_gated == bgate)
+	mutex_lock(&adev->uvd.pg_lock);
+
+	if (cz_hwmgr->uvd_power_gated == bgate) {
+		mutex_unlock(&adev->uvd.pg_lock);
 		return 0;
+	}
 
+	adev->uvd.pg_state = bgate;
 	cz_hwmgr->uvd_power_gated = bgate;
 
+	WREG32(mmUVD_POWER_STATUS, UVD_POWER_STATUS__UVD_PG_EN_MASK);
+
 	if (bgate) {
 		cgs_set_clockgating_state(hwmgr->device,
 						AMD_IP_BLOCK_TYPE_UVD,
@@ -177,14 +190,15 @@ int cz_dpm_powergate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
 		cz_dpm_powerdown_uvd(hwmgr);
 	} else {
 		cz_dpm_powerup_uvd(hwmgr);
-		cgs_set_clockgating_state(hwmgr->device,
-						AMD_IP_BLOCK_TYPE_UVD,
-						AMD_PG_STATE_GATE);
 		cgs_set_powergating_state(hwmgr->device,
 						AMD_IP_BLOCK_TYPE_UVD,
 						AMD_CG_STATE_UNGATE);
+		cgs_set_clockgating_state(hwmgr->device,
+						AMD_IP_BLOCK_TYPE_UVD,
+						AMD_PG_STATE_GATE);
 		cz_dpm_update_uvd_dpm(hwmgr, false);
 	}
+	mutex_unlock(&adev->uvd.pg_lock);
 
 	return 0;
 }
-- 
2.9.2



More information about the amd-gfx mailing list