drm/radeon: implement tn_set_vce_clocks
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 11 May 2015 20:01:50 +0000 (22:01 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 May 2015 14:31:21 +0000 (10:31 -0400)
This implements the function to set the vce clocks
on TN hardware.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/ni.c
drivers/gpu/drm/radeon/nid.h
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h

index aba2f428c0a895380a4a3251e51c6484fba4b3be..a6d940fc44e807ff7ebd63059f96e688766953db 100644 (file)
@@ -2554,3 +2554,34 @@ void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
        radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
        radeon_ring_write(ring, 0x0);
 }
+
+int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
+{
+       struct atom_clock_dividers dividers;
+       int r, i;
+
+        r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                          ecclk, false, &dividers);
+       if (r)
+               return r;
+
+       for (i = 0; i < 100; i++) {
+               if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
+                       break;
+               mdelay(10);
+       }
+       if (i == 100)
+               return -ETIMEDOUT;
+
+       WREG32_P(CG_ECLK_CNTL, dividers.post_div, ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK));
+
+       for (i = 0; i < 100; i++) {
+               if (RREG32(CG_ECLK_STATUS) & ECLK_STATUS)
+                       break;
+               mdelay(10);
+       }
+       if (i == 100)
+               return -ETIMEDOUT;
+
+       return 0;
+}
index 3b290838918cfc3d04910616c25fd20df810fa89..47eb49b77d326ac88d2cfb3ec1de0c4632412257 100644 (file)
 
 #define DMIF_ADDR_CONFIG                               0xBD4
 
+/* fusion vce clocks */
+#define CG_ECLK_CNTL                                    0x620
+#       define ECLK_DIVIDER_MASK                        0x7f
+#       define ECLK_DIR_CNTL_EN                         (1 << 8)
+#define CG_ECLK_STATUS                                  0x624
+#       define ECLK_STATUS                              (1 << 0)
+
 /* DCE6 only */
 #define DMIF_ADDR_CALC                                 0xC00
 
index 4227b30b5ce6a3c2161e47f450bc48eab8179f2d..b37b22bdf57904530bde5b2d66bcfcfc8e2e9434 100644 (file)
@@ -1838,6 +1838,7 @@ static struct radeon_asic trinity_asic = {
                .set_pcie_lanes = NULL,
                .set_clock_gating = NULL,
                .set_uvd_clocks = &sumo_set_uvd_clocks,
+               .set_vce_clocks = &tn_set_vce_clocks,
                .get_temperature = &tn_get_temp,
        },
        .dpm = {
index 0469d440764b2eea5e4b5b268a97420d34a2eeb8..629f2910a33e18fa5ae20fd0797f2d0ecc8a0f9e 100644 (file)
@@ -694,6 +694,7 @@ int trinity_dpm_force_performance_level(struct radeon_device *rdev,
 void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable);
 u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev);
 u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev);
+int tn_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk);
 
 /* DCE6 - SI */
 void dce6_bandwidth_update(struct radeon_device *rdev);