drm/radeon: add support for vce 1.0 clock gating
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 11 May 2015 20:01:54 +0000 (22:01 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 May 2015 14:31:24 +0000 (10:31 -0400)
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/sid.h
drivers/gpu/drm/radeon/vce_v1_0.c

index eaf909e7feb3825674da6606294501e8ab549e1a..f2421bc3e901904d8fbe92deffb9e98d033de62b 100644 (file)
@@ -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:
index 4823a075f0c38c109fdde3ef4781ea2bd8a77c1b..4c4a7218a3bd63c11f7f9c8d6b96583bef27368b 100644 (file)
 #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
index 81dd39b8de1c4074194b31d802f2e9517b95b15a..07a0d378e122b1b206b8aceb1a97234254d00e74 100644 (file)
@@ -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;
 }