xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c (revision e9822622)
1 /*
2  * Copyright 2014 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 "amdgpu.h"
31 #include "amdgpu_vce.h"
32 #include "vid.h"
33 #include "vce/vce_3_0_d.h"
34 #include "vce/vce_3_0_sh_mask.h"
35 #include "oss/oss_2_0_d.h"
36 #include "oss/oss_2_0_sh_mask.h"
37 
38 #define VCE_V3_0_FW_SIZE	(384 * 1024)
39 #define VCE_V3_0_STACK_SIZE	(64 * 1024)
40 #define VCE_V3_0_DATA_SIZE	((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
41 
42 static void vce_v3_0_mc_resume(struct amdgpu_device *adev);
43 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);
45 
46 /**
47  * vce_v3_0_ring_get_rptr - get read pointer
48  *
49  * @ring: amdgpu_ring pointer
50  *
51  * Returns the current hardware read pointer
52  */
53 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
54 {
55 	struct amdgpu_device *adev = ring->adev;
56 
57 	if (ring == &adev->vce.ring[0])
58 		return RREG32(mmVCE_RB_RPTR);
59 	else
60 		return RREG32(mmVCE_RB_RPTR2);
61 }
62 
63 /**
64  * vce_v3_0_ring_get_wptr - get write pointer
65  *
66  * @ring: amdgpu_ring pointer
67  *
68  * Returns the current hardware write pointer
69  */
70 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
71 {
72 	struct amdgpu_device *adev = ring->adev;
73 
74 	if (ring == &adev->vce.ring[0])
75 		return RREG32(mmVCE_RB_WPTR);
76 	else
77 		return RREG32(mmVCE_RB_WPTR2);
78 }
79 
80 /**
81  * vce_v3_0_ring_set_wptr - set write pointer
82  *
83  * @ring: amdgpu_ring pointer
84  *
85  * Commits the write pointer to the hardware
86  */
87 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
88 {
89 	struct amdgpu_device *adev = ring->adev;
90 
91 	if (ring == &adev->vce.ring[0])
92 		WREG32(mmVCE_RB_WPTR, ring->wptr);
93 	else
94 		WREG32(mmVCE_RB_WPTR2, ring->wptr);
95 }
96 
97 /**
98  * vce_v3_0_start - start VCE block
99  *
100  * @adev: amdgpu_device pointer
101  *
102  * Setup and start the VCE block
103  */
104 static int vce_v3_0_start(struct amdgpu_device *adev)
105 {
106 	struct amdgpu_ring *ring;
107 	int i, j, r;
108 
109 	vce_v3_0_mc_resume(adev);
110 
111 	/* set BUSY flag */
112 	WREG32_P(mmVCE_STATUS, 1, ~1);
113 
114 	ring = &adev->vce.ring[0];
115 	WREG32(mmVCE_RB_RPTR, ring->wptr);
116 	WREG32(mmVCE_RB_WPTR, ring->wptr);
117 	WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
118 	WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
119 	WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
120 
121 	ring = &adev->vce.ring[1];
122 	WREG32(mmVCE_RB_RPTR2, ring->wptr);
123 	WREG32(mmVCE_RB_WPTR2, ring->wptr);
124 	WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
125 	WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
126 	WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
127 
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;
168 }
169 
170 static int vce_v3_0_early_init(struct amdgpu_device *adev)
171 {
172 	vce_v3_0_set_ring_funcs(adev);
173 	vce_v3_0_set_irq_funcs(adev);
174 
175 	return 0;
176 }
177 
178 static int vce_v3_0_sw_init(struct amdgpu_device *adev)
179 {
180 	struct amdgpu_ring *ring;
181 	int r;
182 
183 	/* VCE */
184 	r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq);
185 	if (r)
186 		return r;
187 
188 	r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE +
189 		(VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2);
190 	if (r)
191 		return r;
192 
193 	r = amdgpu_vce_resume(adev);
194 	if (r)
195 		return r;
196 
197 	ring = &adev->vce.ring[0];
198 	sprintf(ring->name, "vce0");
199 	r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
200 			     &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
201 	if (r)
202 		return r;
203 
204 	ring = &adev->vce.ring[1];
205 	sprintf(ring->name, "vce1");
206 	r = amdgpu_ring_init(adev, ring, 4096, VCE_CMD_NO_OP, 0xf,
207 			     &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
208 	if (r)
209 		return r;
210 
211 	return r;
212 }
213 
214 static int vce_v3_0_sw_fini(struct amdgpu_device *adev)
215 {
216 	int r;
217 
218 	r = amdgpu_vce_suspend(adev);
219 	if (r)
220 		return r;
221 
222 	r = amdgpu_vce_sw_fini(adev);
223 	if (r)
224 		return r;
225 
226 	return r;
227 }
228 
229 static int vce_v3_0_hw_init(struct amdgpu_device *adev)
230 {
231 	struct amdgpu_ring *ring;
232 	int r;
233 
234 	r = vce_v3_0_start(adev);
235 	if (r)
236 		return r;
237 
238 	ring = &adev->vce.ring[0];
239 	ring->ready = true;
240 	r = amdgpu_ring_test_ring(ring);
241 	if (r) {
242 		ring->ready = false;
243 		return r;
244 	}
245 
246 	ring = &adev->vce.ring[1];
247 	ring->ready = true;
248 	r = amdgpu_ring_test_ring(ring);
249 	if (r) {
250 		ring->ready = false;
251 		return r;
252 	}
253 
254 	DRM_INFO("VCE initialized successfully.\n");
255 
256 	return 0;
257 }
258 
259 static int vce_v3_0_hw_fini(struct amdgpu_device *adev)
260 {
261 	// TODO
262 	return 0;
263 }
264 
265 static int vce_v3_0_suspend(struct amdgpu_device *adev)
266 {
267 	int r;
268 
269 	r = vce_v3_0_hw_fini(adev);
270 	if (r)
271 		return r;
272 
273 	r = amdgpu_vce_suspend(adev);
274 	if (r)
275 		return r;
276 
277 	return r;
278 }
279 
280 static int vce_v3_0_resume(struct amdgpu_device *adev)
281 {
282 	int r;
283 
284 	r = amdgpu_vce_resume(adev);
285 	if (r)
286 		return r;
287 
288 	r = vce_v3_0_hw_init(adev);
289 	if (r)
290 		return r;
291 
292 	return r;
293 }
294 
295 static void vce_v3_0_mc_resume(struct amdgpu_device *adev)
296 {
297 	uint32_t offset, size;
298 
299 	WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
300 	WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
301 	WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
302 	WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
303 
304 	WREG32(mmVCE_LMI_CTRL, 0x00398000);
305 	WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
306 	WREG32(mmVCE_LMI_SWAP_CNTL, 0);
307 	WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
308 	WREG32(mmVCE_LMI_VM_CTRL, 0);
309 
310 	WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
311 	offset = AMDGPU_VCE_FIRMWARE_OFFSET;
312 	size = VCE_V3_0_FW_SIZE;
313 	WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
314 	WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
315 
316 	offset += size;
317 	size = VCE_V3_0_STACK_SIZE;
318 	WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
319 	WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
320 
321 	offset += size;
322 	size = VCE_V3_0_DATA_SIZE;
323 	WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
324 	WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
325 
326 	WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
327 
328 	WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
329 		 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
330 }
331 
332 static bool vce_v3_0_is_idle(struct amdgpu_device *adev)
333 {
334 	return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
335 }
336 
337 static int vce_v3_0_wait_for_idle(struct amdgpu_device *adev)
338 {
339 	unsigned i;
340 
341 	for (i = 0; i < adev->usec_timeout; i++) {
342 		if (!(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK))
343 			return 0;
344 	}
345 	return -ETIMEDOUT;
346 }
347 
348 static int vce_v3_0_soft_reset(struct amdgpu_device *adev)
349 {
350 	WREG32_P(mmSRBM_SOFT_RESET, SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK,
351 			~SRBM_SOFT_RESET__SOFT_RESET_VCE_MASK);
352 	mdelay(5);
353 
354 	return vce_v3_0_start(adev);
355 }
356 
357 static void vce_v3_0_print_status(struct amdgpu_device *adev)
358 {
359 	dev_info(adev->dev, "VCE 3.0 registers\n");
360 	dev_info(adev->dev, "  VCE_STATUS=0x%08X\n",
361 		 RREG32(mmVCE_STATUS));
362 	dev_info(adev->dev, "  VCE_VCPU_CNTL=0x%08X\n",
363 		 RREG32(mmVCE_VCPU_CNTL));
364 	dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET0=0x%08X\n",
365 		 RREG32(mmVCE_VCPU_CACHE_OFFSET0));
366 	dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE0=0x%08X\n",
367 		 RREG32(mmVCE_VCPU_CACHE_SIZE0));
368 	dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET1=0x%08X\n",
369 		 RREG32(mmVCE_VCPU_CACHE_OFFSET1));
370 	dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE1=0x%08X\n",
371 		 RREG32(mmVCE_VCPU_CACHE_SIZE1));
372 	dev_info(adev->dev, "  VCE_VCPU_CACHE_OFFSET2=0x%08X\n",
373 		 RREG32(mmVCE_VCPU_CACHE_OFFSET2));
374 	dev_info(adev->dev, "  VCE_VCPU_CACHE_SIZE2=0x%08X\n",
375 		 RREG32(mmVCE_VCPU_CACHE_SIZE2));
376 	dev_info(adev->dev, "  VCE_SOFT_RESET=0x%08X\n",
377 		 RREG32(mmVCE_SOFT_RESET));
378 	dev_info(adev->dev, "  VCE_RB_BASE_LO2=0x%08X\n",
379 		 RREG32(mmVCE_RB_BASE_LO2));
380 	dev_info(adev->dev, "  VCE_RB_BASE_HI2=0x%08X\n",
381 		 RREG32(mmVCE_RB_BASE_HI2));
382 	dev_info(adev->dev, "  VCE_RB_SIZE2=0x%08X\n",
383 		 RREG32(mmVCE_RB_SIZE2));
384 	dev_info(adev->dev, "  VCE_RB_RPTR2=0x%08X\n",
385 		 RREG32(mmVCE_RB_RPTR2));
386 	dev_info(adev->dev, "  VCE_RB_WPTR2=0x%08X\n",
387 		 RREG32(mmVCE_RB_WPTR2));
388 	dev_info(adev->dev, "  VCE_RB_BASE_LO=0x%08X\n",
389 		 RREG32(mmVCE_RB_BASE_LO));
390 	dev_info(adev->dev, "  VCE_RB_BASE_HI=0x%08X\n",
391 		 RREG32(mmVCE_RB_BASE_HI));
392 	dev_info(adev->dev, "  VCE_RB_SIZE=0x%08X\n",
393 		 RREG32(mmVCE_RB_SIZE));
394 	dev_info(adev->dev, "  VCE_RB_RPTR=0x%08X\n",
395 		 RREG32(mmVCE_RB_RPTR));
396 	dev_info(adev->dev, "  VCE_RB_WPTR=0x%08X\n",
397 		 RREG32(mmVCE_RB_WPTR));
398 	dev_info(adev->dev, "  VCE_CLOCK_GATING_A=0x%08X\n",
399 		 RREG32(mmVCE_CLOCK_GATING_A));
400 	dev_info(adev->dev, "  VCE_CLOCK_GATING_B=0x%08X\n",
401 		 RREG32(mmVCE_CLOCK_GATING_B));
402 	dev_info(adev->dev, "  VCE_UENC_CLOCK_GATING=0x%08X\n",
403 		 RREG32(mmVCE_UENC_CLOCK_GATING));
404 	dev_info(adev->dev, "  VCE_UENC_REG_CLOCK_GATING=0x%08X\n",
405 		 RREG32(mmVCE_UENC_REG_CLOCK_GATING));
406 	dev_info(adev->dev, "  VCE_SYS_INT_EN=0x%08X\n",
407 		 RREG32(mmVCE_SYS_INT_EN));
408 	dev_info(adev->dev, "  VCE_LMI_CTRL2=0x%08X\n",
409 		 RREG32(mmVCE_LMI_CTRL2));
410 	dev_info(adev->dev, "  VCE_LMI_CTRL=0x%08X\n",
411 		 RREG32(mmVCE_LMI_CTRL));
412 	dev_info(adev->dev, "  VCE_LMI_VM_CTRL=0x%08X\n",
413 		 RREG32(mmVCE_LMI_VM_CTRL));
414 	dev_info(adev->dev, "  VCE_LMI_SWAP_CNTL=0x%08X\n",
415 		 RREG32(mmVCE_LMI_SWAP_CNTL));
416 	dev_info(adev->dev, "  VCE_LMI_SWAP_CNTL1=0x%08X\n",
417 		 RREG32(mmVCE_LMI_SWAP_CNTL1));
418 	dev_info(adev->dev, "  VCE_LMI_CACHE_CTRL=0x%08X\n",
419 		 RREG32(mmVCE_LMI_CACHE_CTRL));
420 }
421 
422 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev,
423 					struct amdgpu_irq_src *source,
424 					unsigned type,
425 					enum amdgpu_interrupt_state state)
426 {
427 	uint32_t val = 0;
428 
429 	if (state == AMDGPU_IRQ_STATE_ENABLE)
430 		val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
431 
432 	WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
433 	return 0;
434 }
435 
436 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
437 				      struct amdgpu_irq_src *source,
438 				      struct amdgpu_iv_entry *entry)
439 {
440 	DRM_DEBUG("IH: VCE\n");
441 	switch (entry->src_data) {
442 	case 0:
443 		amdgpu_fence_process(&adev->vce.ring[0]);
444 		break;
445 	case 1:
446 		amdgpu_fence_process(&adev->vce.ring[1]);
447 		break;
448 	default:
449 		DRM_ERROR("Unhandled interrupt: %d %d\n",
450 			  entry->src_id, entry->src_data);
451 		break;
452 	}
453 
454 	return 0;
455 }
456 
457 static int vce_v3_0_set_clockgating_state(struct amdgpu_device *adev,
458 					  enum amdgpu_clockgating_state state)
459 {
460 	//TODO
461 	return 0;
462 }
463 
464 static int vce_v3_0_set_powergating_state(struct amdgpu_device *adev,
465 					  enum amdgpu_powergating_state state)
466 {
467 	/* This doesn't actually powergate the VCE block.
468 	 * That's done in the dpm code via the SMC.  This
469 	 * just re-inits the block as necessary.  The actual
470 	 * gating still happens in the dpm code.  We should
471 	 * revisit this when there is a cleaner line between
472 	 * the smc and the hw blocks
473 	 */
474 	if (state == AMDGPU_PG_STATE_GATE)
475 		/* XXX do we need a vce_v3_0_stop()? */
476 		return 0;
477 	else
478 		return vce_v3_0_start(adev);
479 }
480 
481 const struct amdgpu_ip_funcs vce_v3_0_ip_funcs = {
482 	.early_init = vce_v3_0_early_init,
483 	.late_init = NULL,
484 	.sw_init = vce_v3_0_sw_init,
485 	.sw_fini = vce_v3_0_sw_fini,
486 	.hw_init = vce_v3_0_hw_init,
487 	.hw_fini = vce_v3_0_hw_fini,
488 	.suspend = vce_v3_0_suspend,
489 	.resume = vce_v3_0_resume,
490 	.is_idle = vce_v3_0_is_idle,
491 	.wait_for_idle = vce_v3_0_wait_for_idle,
492 	.soft_reset = vce_v3_0_soft_reset,
493 	.print_status = vce_v3_0_print_status,
494 	.set_clockgating_state = vce_v3_0_set_clockgating_state,
495 	.set_powergating_state = vce_v3_0_set_powergating_state,
496 };
497 
498 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = {
499 	.get_rptr = vce_v3_0_ring_get_rptr,
500 	.get_wptr = vce_v3_0_ring_get_wptr,
501 	.set_wptr = vce_v3_0_ring_set_wptr,
502 	.parse_cs = amdgpu_vce_ring_parse_cs,
503 	.emit_ib = amdgpu_vce_ring_emit_ib,
504 	.emit_fence = amdgpu_vce_ring_emit_fence,
505 	.emit_semaphore = amdgpu_vce_ring_emit_semaphore,
506 	.test_ring = amdgpu_vce_ring_test_ring,
507 	.test_ib = amdgpu_vce_ring_test_ib,
508 	.is_lockup = amdgpu_ring_test_lockup,
509 };
510 
511 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
512 {
513 	adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs;
514 	adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs;
515 }
516 
517 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = {
518 	.set = vce_v3_0_set_interrupt_state,
519 	.process = vce_v3_0_process_interrupt,
520 };
521 
522 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev)
523 {
524 	adev->vce.irq.num_types = 1;
525 	adev->vce.irq.funcs = &vce_v3_0_irq_funcs;
526 };
527