aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v3_0.c141
1 files changed, 87 insertions, 54 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
index ee29436f364e..57e0e167c83b 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -34,12 +34,16 @@
34#include "vce/vce_3_0_sh_mask.h" 34#include "vce/vce_3_0_sh_mask.h"
35#include "oss/oss_2_0_d.h" 35#include "oss/oss_2_0_d.h"
36#include "oss/oss_2_0_sh_mask.h" 36#include "oss/oss_2_0_sh_mask.h"
37#include "gca/gfx_8_0_d.h"
38
39#define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04
40#define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10
37 41
38#define VCE_V3_0_FW_SIZE (384 * 1024) 42#define VCE_V3_0_FW_SIZE (384 * 1024)
39#define VCE_V3_0_STACK_SIZE (64 * 1024) 43#define VCE_V3_0_STACK_SIZE (64 * 1024)
40#define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024)) 44#define VCE_V3_0_DATA_SIZE ((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
41 45
42static void vce_v3_0_mc_resume(struct amdgpu_device *adev); 46static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx);
43static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); 47static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev);
44static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); 48static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev);
45 49
@@ -104,12 +108,70 @@ static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
104static int vce_v3_0_start(struct amdgpu_device *adev) 108static int vce_v3_0_start(struct amdgpu_device *adev)
105{ 109{
106 struct amdgpu_ring *ring; 110 struct amdgpu_ring *ring;
107 int i, j, r; 111 int idx, i, j, r;
112
113 mutex_lock(&adev->grbm_idx_mutex);
114 for (idx = 0; idx < 2; ++idx) {
115 if(idx == 0)
116 WREG32_P(mmGRBM_GFX_INDEX, 0,
117 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
118 else
119 WREG32_P(mmGRBM_GFX_INDEX,
120 GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
121 ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
122
123 vce_v3_0_mc_resume(adev, idx);
124
125 /* set BUSY flag */
126 WREG32_P(mmVCE_STATUS, 1, ~1);
127
128 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
129 ~VCE_VCPU_CNTL__CLK_EN_MASK);
130
131 WREG32_P(mmVCE_SOFT_RESET,
132 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
133 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
134
135 mdelay(100);
136
137 WREG32_P(mmVCE_SOFT_RESET, 0,
138 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
139
140 for (i = 0; i < 10; ++i) {
141 uint32_t status;
142 for (j = 0; j < 100; ++j) {
143 status = RREG32(mmVCE_STATUS);
144 if (status & 2)
145 break;
146 mdelay(10);
147 }
148 r = 0;
149 if (status & 2)
150 break;
151
152 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
153 WREG32_P(mmVCE_SOFT_RESET,
154 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
155 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
156 mdelay(10);
157 WREG32_P(mmVCE_SOFT_RESET, 0,
158 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
159 mdelay(10);
160 r = -1;
161 }
162
163 /* clear BUSY flag */
164 WREG32_P(mmVCE_STATUS, 0, ~1);
108 165
109 vce_v3_0_mc_resume(adev); 166 if (r) {
167 DRM_ERROR("VCE not responding, giving up!!!\n");
168 mutex_unlock(&adev->grbm_idx_mutex);
169 return r;
170 }
171 }
110 172
111 /* set BUSY flag */ 173 WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
112 WREG32_P(mmVCE_STATUS, 1, ~1); 174 mutex_unlock(&adev->grbm_idx_mutex);
113 175
114 ring = &adev->vce.ring[0]; 176 ring = &adev->vce.ring[0];
115 WREG32(mmVCE_RB_RPTR, ring->wptr); 177 WREG32(mmVCE_RB_RPTR, ring->wptr);
@@ -125,45 +187,6 @@ static int vce_v3_0_start(struct amdgpu_device *adev)
125 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); 187 WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
126 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4); 188 WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
127 189
128 WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, ~VCE_VCPU_CNTL__CLK_EN_MASK);
129
130 WREG32_P(mmVCE_SOFT_RESET,
131 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
132 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
133
134 mdelay(100);
135
136 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
137
138 for (i = 0; i < 10; ++i) {
139 uint32_t status;
140 for (j = 0; j < 100; ++j) {
141 status = RREG32(mmVCE_STATUS);
142 if (status & 2)
143 break;
144 mdelay(10);
145 }
146 r = 0;
147 if (status & 2)
148 break;
149
150 DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
151 WREG32_P(mmVCE_SOFT_RESET, VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
152 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
153 mdelay(10);
154 WREG32_P(mmVCE_SOFT_RESET, 0, ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
155 mdelay(10);
156 r = -1;
157 }
158
159 /* clear BUSY flag */
160 WREG32_P(mmVCE_STATUS, 0, ~1);
161
162 if (r) {
163 DRM_ERROR("VCE not responding, giving up!!!\n");
164 return r;
165 }
166
167 return 0; 190 return 0;
168} 191}
169 192
@@ -292,7 +315,7 @@ static int vce_v3_0_resume(struct amdgpu_device *adev)
292 return r; 315 return r;
293} 316}
294 317
295static void vce_v3_0_mc_resume(struct amdgpu_device *adev) 318static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
296{ 319{
297 uint32_t offset, size; 320 uint32_t offset, size;
298 321
@@ -313,15 +336,25 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev)
313 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); 336 WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
314 WREG32(mmVCE_VCPU_CACHE_SIZE0, size); 337 WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
315 338
316 offset += size; 339 if (idx == 0) {
317 size = VCE_V3_0_STACK_SIZE; 340 offset += size;
318 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff); 341 size = VCE_V3_0_STACK_SIZE;
319 WREG32(mmVCE_VCPU_CACHE_SIZE1, size); 342 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
320 343 WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
321 offset += size; 344 offset += size;
322 size = VCE_V3_0_DATA_SIZE; 345 size = VCE_V3_0_DATA_SIZE;
323 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff); 346 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
324 WREG32(mmVCE_VCPU_CACHE_SIZE2, size); 347 WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
348 } else {
349 offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE;
350 size = VCE_V3_0_STACK_SIZE;
351 WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff);
352 WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
353 offset += size;
354 size = VCE_V3_0_DATA_SIZE;
355 WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff);
356 WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
357 }
325 358
326 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100); 359 WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
327 360