diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-05-11 22:01:54 +0200 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-05-26 10:31:24 -0400 |
commit | d55a43a3e9258c01a6cac2f3081b3ceaa8e58020 (patch) | |
tree | 60954b60b921a5076a092fc69f8f66edf8d19f86 | |
parent | a918efab631a5112d9d168700458317ad77f269c (diff) |
drm/radeon: add support for vce 1.0 clock gating
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/sid.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/vce_v1_0.c | 57 |
3 files changed, 60 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index eaf909e7feb3..f2421bc3e901 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -2455,6 +2455,8 @@ int radeon_asic_init(struct radeon_device *rdev) /* set num crtcs */ rdev->num_crtc = 4; rdev->has_uvd = true; + rdev->cg_flags = + RADEON_CG_SUPPORT_VCE_MGCG; break; case CHIP_TAHITI: case CHIP_PITCAIRN: diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 4823a075f0c3..4c4a7218a3bd 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h @@ -1894,6 +1894,7 @@ #define VCE_RB_RPTR 0x2018c #define VCE_RB_WPTR 0x20190 #define VCE_CLOCK_GATING_A 0x202f8 +# define CGC_DYN_CLOCK_MODE (1 << 16) #define VCE_CLOCK_GATING_B 0x202fc #define VCE_UENC_CLOCK_GATING 0x205bc #define VCE_UENC_REG_CLOCK_GATING 0x205c0 diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c index 81dd39b8de1c..07a0d378e122 100644 --- a/drivers/gpu/drm/radeon/vce_v1_0.c +++ b/drivers/gpu/drm/radeon/vce_v1_0.c @@ -99,6 +99,61 @@ void vce_v1_0_set_wptr(struct radeon_device *rdev, WREG32(VCE_RB_WPTR2, ring->wptr); } +void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable) +{ + u32 tmp; + + if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) { + tmp = RREG32(VCE_CLOCK_GATING_A); + tmp |= CGC_DYN_CLOCK_MODE; + WREG32(VCE_CLOCK_GATING_A, tmp); + + tmp = RREG32(VCE_UENC_CLOCK_GATING); + tmp &= ~0x1ff000; + tmp |= 0xff800000; + WREG32(VCE_UENC_CLOCK_GATING, tmp); + + tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); + tmp &= ~0x3ff; + WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); + } else { + tmp = RREG32(VCE_CLOCK_GATING_A); + tmp &= ~CGC_DYN_CLOCK_MODE; + WREG32(VCE_CLOCK_GATING_A, tmp); + + tmp = RREG32(VCE_UENC_CLOCK_GATING); + tmp |= 0x1ff000; + tmp &= ~0xff800000; + WREG32(VCE_UENC_CLOCK_GATING, tmp); + + tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); + tmp |= 0x3ff; + WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); + } +} + +static void vce_v1_0_init_cg(struct radeon_device *rdev) +{ + u32 tmp; + + tmp = RREG32(VCE_CLOCK_GATING_A); + tmp |= CGC_DYN_CLOCK_MODE; + WREG32(VCE_CLOCK_GATING_A, tmp); + + tmp = RREG32(VCE_CLOCK_GATING_B); + tmp |= 0x1e; + tmp &= ~0xe100e1; + WREG32(VCE_CLOCK_GATING_B, tmp); + + tmp = RREG32(VCE_UENC_CLOCK_GATING); + tmp &= ~0xff9ff000; + WREG32(VCE_UENC_CLOCK_GATING, tmp); + + tmp = RREG32(VCE_UENC_REG_CLOCK_GATING); + tmp &= ~0x3ff; + WREG32(VCE_UENC_REG_CLOCK_GATING, tmp); +} + int vce_v1_0_load_fw(struct radeon_device *rdev, uint32_t *data) { struct vce_v1_0_fw_signature *sign = (void*)rdev->vce_fw->data; @@ -219,6 +274,8 @@ int vce_v1_0_resume(struct radeon_device *rdev) if (i == 10) return -ETIMEDOUT; + vce_v1_0_init_cg(rdev); + return 0; } |