diff options
author | Christian König <christian.koenig@amd.com> | 2013-05-23 06:10:04 -0400 |
---|---|---|
committer | Christian König <christian.koenig@amd.com> | 2014-02-18 10:11:22 -0500 |
commit | d93f79376f210e0b19da57a3dc841ba332daa9d0 (patch) | |
tree | 2fe1ee891972b9da1d6d3b743ddc0198e17fab8c /drivers/gpu/drm/radeon/vce_v1_0.c | |
parent | 1c61eae469e0d1d2fb9d7b77f51ca50c1f8f3ce9 (diff) |
drm/radeon: initial VCE support v4
Only VCE 2.0 support so far.
v2: squashing multiple patches into this one
v3: add IRQ support for CIK, major cleanups,
basic code documentation
v4: remove HAINAN from chipset list
Signed-off-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/vce_v1_0.c')
-rw-r--r-- | drivers/gpu/drm/radeon/vce_v1_0.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/vce_v1_0.c b/drivers/gpu/drm/radeon/vce_v1_0.c new file mode 100644 index 000000000000..e0c3534356a1 --- /dev/null +++ b/drivers/gpu/drm/radeon/vce_v1_0.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Copyright 2013 Advanced Micro Devices, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the | ||
7 | * "Software"), to deal in the Software without restriction, including | ||
8 | * without limitation the rights to use, copy, modify, merge, publish, | ||
9 | * distribute, sub license, and/or sell copies of the Software, and to | ||
10 | * permit persons to whom the Software is furnished to do so, subject to | ||
11 | * the following conditions: | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | ||
16 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | ||
17 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
18 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
19 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
20 | * | ||
21 | * The above copyright notice and this permission notice (including the | ||
22 | * next paragraph) shall be included in all copies or substantial portions | ||
23 | * of the Software. | ||
24 | * | ||
25 | * Authors: Christian König <christian.koenig@amd.com> | ||
26 | */ | ||
27 | |||
28 | #include <linux/firmware.h> | ||
29 | #include <drm/drmP.h> | ||
30 | #include "radeon.h" | ||
31 | #include "radeon_asic.h" | ||
32 | #include "sid.h" | ||
33 | |||
34 | /** | ||
35 | * vce_v1_0_get_rptr - get read pointer | ||
36 | * | ||
37 | * @rdev: radeon_device pointer | ||
38 | * @ring: radeon_ring pointer | ||
39 | * | ||
40 | * Returns the current hardware read pointer | ||
41 | */ | ||
42 | uint32_t vce_v1_0_get_rptr(struct radeon_device *rdev, | ||
43 | struct radeon_ring *ring) | ||
44 | { | ||
45 | if (ring->idx == TN_RING_TYPE_VCE1_INDEX) | ||
46 | return RREG32(VCE_RB_RPTR); | ||
47 | else | ||
48 | return RREG32(VCE_RB_RPTR2); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * vce_v1_0_get_wptr - get write pointer | ||
53 | * | ||
54 | * @rdev: radeon_device pointer | ||
55 | * @ring: radeon_ring pointer | ||
56 | * | ||
57 | * Returns the current hardware write pointer | ||
58 | */ | ||
59 | uint32_t vce_v1_0_get_wptr(struct radeon_device *rdev, | ||
60 | struct radeon_ring *ring) | ||
61 | { | ||
62 | if (ring->idx == TN_RING_TYPE_VCE1_INDEX) | ||
63 | return RREG32(VCE_RB_WPTR); | ||
64 | else | ||
65 | return RREG32(VCE_RB_WPTR2); | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * vce_v1_0_set_wptr - set write pointer | ||
70 | * | ||
71 | * @rdev: radeon_device pointer | ||
72 | * @ring: radeon_ring pointer | ||
73 | * | ||
74 | * Commits the write pointer to the hardware | ||
75 | */ | ||
76 | void vce_v1_0_set_wptr(struct radeon_device *rdev, | ||
77 | struct radeon_ring *ring) | ||
78 | { | ||
79 | if (ring->idx == TN_RING_TYPE_VCE1_INDEX) | ||
80 | WREG32(VCE_RB_WPTR, ring->wptr); | ||
81 | else | ||
82 | WREG32(VCE_RB_WPTR2, ring->wptr); | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * vce_v1_0_start - start VCE block | ||
87 | * | ||
88 | * @rdev: radeon_device pointer | ||
89 | * | ||
90 | * Setup and start the VCE block | ||
91 | */ | ||
92 | int vce_v1_0_start(struct radeon_device *rdev) | ||
93 | { | ||
94 | struct radeon_ring *ring; | ||
95 | int i, j, r; | ||
96 | |||
97 | /* set BUSY flag */ | ||
98 | WREG32_P(VCE_STATUS, 1, ~1); | ||
99 | |||
100 | ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; | ||
101 | WREG32(VCE_RB_RPTR, ring->rptr); | ||
102 | WREG32(VCE_RB_WPTR, ring->wptr); | ||
103 | WREG32(VCE_RB_BASE_LO, ring->gpu_addr); | ||
104 | WREG32(VCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); | ||
105 | WREG32(VCE_RB_SIZE, ring->ring_size / 4); | ||
106 | |||
107 | ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; | ||
108 | WREG32(VCE_RB_RPTR2, ring->rptr); | ||
109 | WREG32(VCE_RB_WPTR2, ring->wptr); | ||
110 | WREG32(VCE_RB_BASE_LO2, ring->gpu_addr); | ||
111 | WREG32(VCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); | ||
112 | WREG32(VCE_RB_SIZE2, ring->ring_size / 4); | ||
113 | |||
114 | WREG32_P(VCE_VCPU_CNTL, VCE_CLK_EN, ~VCE_CLK_EN); | ||
115 | |||
116 | WREG32_P(VCE_SOFT_RESET, | ||
117 | VCE_ECPU_SOFT_RESET | | ||
118 | VCE_FME_SOFT_RESET, ~( | ||
119 | VCE_ECPU_SOFT_RESET | | ||
120 | VCE_FME_SOFT_RESET)); | ||
121 | |||
122 | mdelay(100); | ||
123 | |||
124 | WREG32_P(VCE_SOFT_RESET, 0, ~( | ||
125 | VCE_ECPU_SOFT_RESET | | ||
126 | VCE_FME_SOFT_RESET)); | ||
127 | |||
128 | for (i = 0; i < 10; ++i) { | ||
129 | uint32_t status; | ||
130 | for (j = 0; j < 100; ++j) { | ||
131 | status = RREG32(VCE_STATUS); | ||
132 | if (status & 2) | ||
133 | break; | ||
134 | mdelay(10); | ||
135 | } | ||
136 | r = 0; | ||
137 | if (status & 2) | ||
138 | break; | ||
139 | |||
140 | DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n"); | ||
141 | WREG32_P(VCE_SOFT_RESET, VCE_ECPU_SOFT_RESET, ~VCE_ECPU_SOFT_RESET); | ||
142 | mdelay(10); | ||
143 | WREG32_P(VCE_SOFT_RESET, 0, ~VCE_ECPU_SOFT_RESET); | ||
144 | mdelay(10); | ||
145 | r = -1; | ||
146 | } | ||
147 | |||
148 | /* clear BUSY flag */ | ||
149 | WREG32_P(VCE_STATUS, 0, ~1); | ||
150 | |||
151 | if (r) { | ||
152 | DRM_ERROR("VCE not responding, giving up!!!\n"); | ||
153 | return r; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | int vce_v1_0_init(struct radeon_device *rdev) | ||
160 | { | ||
161 | struct radeon_ring *ring; | ||
162 | int r; | ||
163 | |||
164 | r = vce_v1_0_start(rdev); | ||
165 | if (r) | ||
166 | return r; | ||
167 | |||
168 | ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; | ||
169 | ring->ready = true; | ||
170 | r = radeon_ring_test(rdev, TN_RING_TYPE_VCE1_INDEX, ring); | ||
171 | if (r) { | ||
172 | ring->ready = false; | ||
173 | return r; | ||
174 | } | ||
175 | |||
176 | ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; | ||
177 | ring->ready = true; | ||
178 | r = radeon_ring_test(rdev, TN_RING_TYPE_VCE2_INDEX, ring); | ||
179 | if (r) { | ||
180 | ring->ready = false; | ||
181 | return r; | ||
182 | } | ||
183 | |||
184 | DRM_INFO("VCE initialized successfully.\n"); | ||
185 | |||
186 | return 0; | ||
187 | } | ||