aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-09-05 15:14:28 -0400
committerChristian König <christian.koenig@amd.com>2014-02-18 10:11:44 -0500
commitb9fa18837610483b09a07f1419e6b9f333c46023 (patch)
tree0d40df0dd4b25b15fb91c7291217f1be45b8e80e /drivers/gpu/drm/radeon
parent44493ba959cfaa7506498441397f83d180e4a509 (diff)
drm/radeon: add support for vce 2.0 clock gating
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/cikd.h10
-rw-r--r--drivers/gpu/drm/radeon/vce_v2_0.c111
2 files changed, 121 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h
index ee16380ceba8..213873270d5f 100644
--- a/drivers/gpu/drm/radeon/cikd.h
+++ b/drivers/gpu/drm/radeon/cikd.h
@@ -2029,8 +2029,18 @@
2029#define VCE_RB_RPTR 0x2018c 2029#define VCE_RB_RPTR 0x2018c
2030#define VCE_RB_WPTR 0x20190 2030#define VCE_RB_WPTR 0x20190
2031#define VCE_CLOCK_GATING_A 0x202f8 2031#define VCE_CLOCK_GATING_A 0x202f8
2032# define CGC_CLK_GATE_DLY_TIMER_MASK (0xf << 0)
2033# define CGC_CLK_GATE_DLY_TIMER(x) ((x) << 0)
2034# define CGC_CLK_GATER_OFF_DLY_TIMER_MASK (0xff << 4)
2035# define CGC_CLK_GATER_OFF_DLY_TIMER(x) ((x) << 4)
2036# define CGC_UENC_WAIT_AWAKE (1 << 18)
2032#define VCE_CLOCK_GATING_B 0x202fc 2037#define VCE_CLOCK_GATING_B 0x202fc
2038#define VCE_CGTT_CLK_OVERRIDE 0x207a0
2033#define VCE_UENC_CLOCK_GATING 0x207bc 2039#define VCE_UENC_CLOCK_GATING 0x207bc
2040# define CLOCK_ON_DELAY_MASK (0xf << 0)
2041# define CLOCK_ON_DELAY(x) ((x) << 0)
2042# define CLOCK_OFF_DELAY_MASK (0xff << 4)
2043# define CLOCK_OFF_DELAY(x) ((x) << 4)
2034#define VCE_UENC_REG_CLOCK_GATING 0x207c0 2044#define VCE_UENC_REG_CLOCK_GATING 0x207c0
2035#define VCE_SYS_INT_EN 0x21300 2045#define VCE_SYS_INT_EN 0x21300
2036# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3) 2046# define VCE_SYS_INT_TRAP_INTERRUPT_EN (1 << 3)
diff --git a/drivers/gpu/drm/radeon/vce_v2_0.c b/drivers/gpu/drm/radeon/vce_v2_0.c
index 4911d1b00e3b..1ac7bb825a1b 100644
--- a/drivers/gpu/drm/radeon/vce_v2_0.c
+++ b/drivers/gpu/drm/radeon/vce_v2_0.c
@@ -31,6 +31,115 @@
31#include "radeon_asic.h" 31#include "radeon_asic.h"
32#include "cikd.h" 32#include "cikd.h"
33 33
34static void vce_v2_0_set_sw_cg(struct radeon_device *rdev, bool gated)
35{
36 u32 tmp;
37
38 if (gated) {
39 tmp = RREG32(VCE_CLOCK_GATING_B);
40 tmp |= 0xe70000;
41 WREG32(VCE_CLOCK_GATING_B, tmp);
42
43 tmp = RREG32(VCE_UENC_CLOCK_GATING);
44 tmp |= 0xff000000;
45 WREG32(VCE_UENC_CLOCK_GATING, tmp);
46
47 tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
48 tmp &= ~0x3fc;
49 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
50
51 WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
52 } else {
53 tmp = RREG32(VCE_CLOCK_GATING_B);
54 tmp |= 0xe7;
55 tmp &= ~0xe70000;
56 WREG32(VCE_CLOCK_GATING_B, tmp);
57
58 tmp = RREG32(VCE_UENC_CLOCK_GATING);
59 tmp |= 0x1fe000;
60 tmp &= ~0xff000000;
61 WREG32(VCE_UENC_CLOCK_GATING, tmp);
62
63 tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
64 tmp |= 0x3fc;
65 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
66 }
67}
68
69static void vce_v2_0_set_dyn_cg(struct radeon_device *rdev, bool gated)
70{
71 u32 orig, tmp;
72
73 tmp = RREG32(VCE_CLOCK_GATING_B);
74 tmp &= ~0x00060006;
75 if (gated) {
76 tmp |= 0xe10000;
77 } else {
78 tmp |= 0xe1;
79 tmp &= ~0xe10000;
80 }
81 WREG32(VCE_CLOCK_GATING_B, tmp);
82
83 orig = tmp = RREG32(VCE_UENC_CLOCK_GATING);
84 tmp &= ~0x1fe000;
85 tmp &= ~0xff000000;
86 if (tmp != orig)
87 WREG32(VCE_UENC_CLOCK_GATING, tmp);
88
89 orig = tmp = RREG32(VCE_UENC_REG_CLOCK_GATING);
90 tmp &= ~0x3fc;
91 if (tmp != orig)
92 WREG32(VCE_UENC_REG_CLOCK_GATING, tmp);
93
94 if (gated)
95 WREG32(VCE_CGTT_CLK_OVERRIDE, 0);
96}
97
98static void vce_v2_0_disable_cg(struct radeon_device *rdev)
99{
100 WREG32(VCE_CGTT_CLK_OVERRIDE, 7);
101}
102
103void vce_v2_0_enable_mgcg(struct radeon_device *rdev, bool enable)
104{
105 bool sw_cg = false;
106
107 if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_VCE_MGCG)) {
108 if (sw_cg)
109 vce_v2_0_set_sw_cg(rdev, true);
110 else
111 vce_v2_0_set_dyn_cg(rdev, true);
112 } else {
113 vce_v2_0_disable_cg(rdev);
114
115 if (sw_cg)
116 vce_v2_0_set_sw_cg(rdev, false);
117 else
118 vce_v2_0_set_dyn_cg(rdev, false);
119 }
120}
121
122static void vce_v2_0_init_cg(struct radeon_device *rdev)
123{
124 u32 tmp;
125
126 tmp = RREG32(VCE_CLOCK_GATING_A);
127 tmp &= ~(CGC_CLK_GATE_DLY_TIMER_MASK | CGC_CLK_GATER_OFF_DLY_TIMER_MASK);
128 tmp |= (CGC_CLK_GATE_DLY_TIMER(0) | CGC_CLK_GATER_OFF_DLY_TIMER(4));
129 tmp |= CGC_UENC_WAIT_AWAKE;
130 WREG32(VCE_CLOCK_GATING_A, tmp);
131
132 tmp = RREG32(VCE_UENC_CLOCK_GATING);
133 tmp &= ~(CLOCK_ON_DELAY_MASK | CLOCK_OFF_DELAY_MASK);
134 tmp |= (CLOCK_ON_DELAY(0) | CLOCK_OFF_DELAY(4));
135 WREG32(VCE_UENC_CLOCK_GATING, tmp);
136
137 tmp = RREG32(VCE_CLOCK_GATING_B);
138 tmp |= 0x10;
139 tmp &= ~0x100000;
140 WREG32(VCE_CLOCK_GATING_B, tmp);
141}
142
34int vce_v2_0_resume(struct radeon_device *rdev) 143int vce_v2_0_resume(struct radeon_device *rdev)
35{ 144{
36 uint64_t addr = rdev->vce.gpu_addr; 145 uint64_t addr = rdev->vce.gpu_addr;
@@ -66,5 +175,7 @@ int vce_v2_0_resume(struct radeon_device *rdev)
66 WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 175 WREG32_P(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN,
67 ~VCE_SYS_INT_TRAP_INTERRUPT_EN); 176 ~VCE_SYS_INT_TRAP_INTERRUPT_EN);
68 177
178 vce_v2_0_init_cg(rdev);
179
69 return 0; 180 return 0;
70} 181}