diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 141 |
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 | ||
42 | static void vce_v3_0_mc_resume(struct amdgpu_device *adev); | 46 | static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx); |
43 | static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); | 47 | static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev); |
44 | static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev); | 48 | static 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) | |||
104 | static int vce_v3_0_start(struct amdgpu_device *adev) | 108 | static 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 | ||
295 | static void vce_v3_0_mc_resume(struct amdgpu_device *adev) | 318 | static 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 | ||