summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2015-05-11 23:01:54 +0300
committerAlex Deucher <alexander.deucher@amd.com>2015-05-26 17:31:24 +0300
commitd55a43a3e9258c01a6cac2f3081b3ceaa8e58020 (patch)
tree60954b60b921a5076a092fc69f8f66edf8d19f86
parenta918efab631a5112d9d168700458317ad77f269c (diff)
downloadlinux-d55a43a3e9258c01a6cac2f3081b3ceaa8e58020.tar.xz
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.c2
-rw-r--r--drivers/gpu/drm/radeon/sid.h1
-rw-r--r--drivers/gpu/drm/radeon/vce_v1_0.c57
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;
}