xref: /dflybsd-src/sys/dev/drm/radeon/radeon_semaphore.c (revision d78d3a2272f5ecf9e0b570e362128240417a1b85)
1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot  * Copyright 2011 Christian König.
3926deccbSFrançois Tigeot  * All Rights Reserved.
4926deccbSFrançois Tigeot  *
5926deccbSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
6926deccbSFrançois Tigeot  * copy of this software and associated documentation files (the
7926deccbSFrançois Tigeot  * "Software"), to deal in the Software without restriction, including
8926deccbSFrançois Tigeot  * without limitation the rights to use, copy, modify, merge, publish,
9926deccbSFrançois Tigeot  * distribute, sub license, and/or sell copies of the Software, and to
10926deccbSFrançois Tigeot  * permit persons to whom the Software is furnished to do so, subject to
11926deccbSFrançois Tigeot  * the following conditions:
12926deccbSFrançois Tigeot  *
13926deccbSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14926deccbSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15926deccbSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16926deccbSFrançois Tigeot  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17926deccbSFrançois Tigeot  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18926deccbSFrançois Tigeot  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19926deccbSFrançois Tigeot  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20926deccbSFrançois Tigeot  *
21926deccbSFrançois Tigeot  * The above copyright notice and this permission notice (including the
22926deccbSFrançois Tigeot  * next paragraph) shall be included in all copies or substantial portions
23926deccbSFrançois Tigeot  * of the Software.
24926deccbSFrançois Tigeot  *
25926deccbSFrançois Tigeot  */
26926deccbSFrançois Tigeot /*
27926deccbSFrançois Tigeot  * Authors:
28926deccbSFrançois Tigeot  *    Christian König <deathsimple@vodafone.de>
29926deccbSFrançois Tigeot  */
30926deccbSFrançois Tigeot #include <drm/drmP.h>
31926deccbSFrançois Tigeot #include "radeon.h"
32c6f73aabSFrançois Tigeot #ifdef TRACE_TODO
33c6f73aabSFrançois Tigeot #include "radeon_trace.h"
34c6f73aabSFrançois Tigeot #endif
35926deccbSFrançois Tigeot 
radeon_semaphore_create(struct radeon_device * rdev,struct radeon_semaphore ** semaphore)36926deccbSFrançois Tigeot int radeon_semaphore_create(struct radeon_device *rdev,
37926deccbSFrançois Tigeot 			    struct radeon_semaphore **semaphore)
38926deccbSFrançois Tigeot {
39*7dcf36dcSFrançois Tigeot 	int r;
40926deccbSFrançois Tigeot 
41*7dcf36dcSFrançois Tigeot 	*semaphore = kmalloc(sizeof(struct radeon_semaphore), M_DRM, GFP_KERNEL);
42926deccbSFrançois Tigeot 	if (*semaphore == NULL) {
43926deccbSFrançois Tigeot 		return -ENOMEM;
44926deccbSFrançois Tigeot 	}
45*7dcf36dcSFrançois Tigeot 	r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
46*7dcf36dcSFrançois Tigeot 			     &(*semaphore)->sa_bo, 8, 8);
47926deccbSFrançois Tigeot 	if (r) {
48c4ef309bSzrj 		kfree(*semaphore);
49926deccbSFrançois Tigeot 		*semaphore = NULL;
50926deccbSFrançois Tigeot 		return r;
51926deccbSFrançois Tigeot 	}
52926deccbSFrançois Tigeot 	(*semaphore)->waiters = 0;
53926deccbSFrançois Tigeot 	(*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
54c6f73aabSFrançois Tigeot 
55*7dcf36dcSFrançois Tigeot 	*((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
56c6f73aabSFrançois Tigeot 
57926deccbSFrançois Tigeot 	return 0;
58926deccbSFrançois Tigeot }
59926deccbSFrançois Tigeot 
radeon_semaphore_emit_signal(struct radeon_device * rdev,int ridx,struct radeon_semaphore * semaphore)60c6f73aabSFrançois Tigeot bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx,
61926deccbSFrançois Tigeot 				  struct radeon_semaphore *semaphore)
62926deccbSFrançois Tigeot {
63c6f73aabSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[ridx];
64c6f73aabSFrançois Tigeot 
65c6f73aabSFrançois Tigeot #ifdef TRACE_TODO
66c6f73aabSFrançois Tigeot 	trace_radeon_semaphore_signale(ridx, semaphore);
67c6f73aabSFrançois Tigeot #endif
68c6f73aabSFrançois Tigeot 
69c6f73aabSFrançois Tigeot 	if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) {
70926deccbSFrançois Tigeot 		--semaphore->waiters;
71c6f73aabSFrançois Tigeot 
72c6f73aabSFrançois Tigeot 		/* for debugging lockup only, used by sysfs debug files */
73c6f73aabSFrançois Tigeot 		ring->last_semaphore_signal_addr = semaphore->gpu_addr;
74c6f73aabSFrançois Tigeot 		return true;
75c6f73aabSFrançois Tigeot 	}
76c6f73aabSFrançois Tigeot 	return false;
77926deccbSFrançois Tigeot }
78926deccbSFrançois Tigeot 
radeon_semaphore_emit_wait(struct radeon_device * rdev,int ridx,struct radeon_semaphore * semaphore)79c6f73aabSFrançois Tigeot bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
80926deccbSFrançois Tigeot 				struct radeon_semaphore *semaphore)
81926deccbSFrançois Tigeot {
82c6f73aabSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[ridx];
83c6f73aabSFrançois Tigeot 
84c6f73aabSFrançois Tigeot #ifdef TRACE_TODO
85c6f73aabSFrançois Tigeot 	trace_radeon_semaphore_wait(ridx, semaphore);
86c6f73aabSFrançois Tigeot #endif
87c6f73aabSFrançois Tigeot 
88c6f73aabSFrançois Tigeot 	if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) {
89926deccbSFrançois Tigeot 		++semaphore->waiters;
90c6f73aabSFrançois Tigeot 
91c6f73aabSFrançois Tigeot 		/* for debugging lockup only, used by sysfs debug files */
92c6f73aabSFrançois Tigeot 		ring->last_semaphore_wait_addr = semaphore->gpu_addr;
93c6f73aabSFrançois Tigeot 		return true;
94c6f73aabSFrançois Tigeot 	}
95c6f73aabSFrançois Tigeot 	return false;
96926deccbSFrançois Tigeot }
97926deccbSFrançois Tigeot 
radeon_semaphore_free(struct radeon_device * rdev,struct radeon_semaphore ** semaphore,struct radeon_fence * fence)98926deccbSFrançois Tigeot void radeon_semaphore_free(struct radeon_device *rdev,
99926deccbSFrançois Tigeot 			   struct radeon_semaphore **semaphore,
100926deccbSFrançois Tigeot 			   struct radeon_fence *fence)
101926deccbSFrançois Tigeot {
102926deccbSFrançois Tigeot 	if (semaphore == NULL || *semaphore == NULL) {
103926deccbSFrançois Tigeot 		return;
104926deccbSFrançois Tigeot 	}
105926deccbSFrançois Tigeot 	if ((*semaphore)->waiters > 0) {
106926deccbSFrançois Tigeot 		dev_err(rdev->dev, "semaphore %p has more waiters than signalers,"
107926deccbSFrançois Tigeot 			" hardware lockup imminent!\n", *semaphore);
108926deccbSFrançois Tigeot 	}
109926deccbSFrançois Tigeot 	radeon_sa_bo_free(rdev, &(*semaphore)->sa_bo, fence);
110c4ef309bSzrj 	kfree(*semaphore);
111926deccbSFrançois Tigeot 	*semaphore = NULL;
112926deccbSFrançois Tigeot }
113