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