0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #include "radeon.h"
0032 #include "radeon_trace.h"
0033
0034 int radeon_semaphore_create(struct radeon_device *rdev,
0035 struct radeon_semaphore **semaphore)
0036 {
0037 int r;
0038
0039 *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
0040 if (*semaphore == NULL) {
0041 return -ENOMEM;
0042 }
0043 r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo,
0044 &(*semaphore)->sa_bo, 8, 8);
0045 if (r) {
0046 kfree(*semaphore);
0047 *semaphore = NULL;
0048 return r;
0049 }
0050 (*semaphore)->waiters = 0;
0051 (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo);
0052
0053 *((uint64_t *)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0;
0054
0055 return 0;
0056 }
0057
0058 bool radeon_semaphore_emit_signal(struct radeon_device *rdev, int ridx,
0059 struct radeon_semaphore *semaphore)
0060 {
0061 struct radeon_ring *ring = &rdev->ring[ridx];
0062
0063 trace_radeon_semaphore_signale(ridx, semaphore);
0064
0065 if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, false)) {
0066 --semaphore->waiters;
0067
0068
0069 ring->last_semaphore_signal_addr = semaphore->gpu_addr;
0070 return true;
0071 }
0072 return false;
0073 }
0074
0075 bool radeon_semaphore_emit_wait(struct radeon_device *rdev, int ridx,
0076 struct radeon_semaphore *semaphore)
0077 {
0078 struct radeon_ring *ring = &rdev->ring[ridx];
0079
0080 trace_radeon_semaphore_wait(ridx, semaphore);
0081
0082 if (radeon_semaphore_ring_emit(rdev, ridx, ring, semaphore, true)) {
0083 ++semaphore->waiters;
0084
0085
0086 ring->last_semaphore_wait_addr = semaphore->gpu_addr;
0087 return true;
0088 }
0089 return false;
0090 }
0091
0092 void radeon_semaphore_free(struct radeon_device *rdev,
0093 struct radeon_semaphore **semaphore,
0094 struct radeon_fence *fence)
0095 {
0096 if (semaphore == NULL || *semaphore == NULL) {
0097 return;
0098 }
0099 if ((*semaphore)->waiters > 0) {
0100 dev_err(rdev->dev, "semaphore %p has more waiters than signalers,"
0101 " hardware lockup imminent!\n", *semaphore);
0102 }
0103 radeon_sa_bo_free(rdev, &(*semaphore)->sa_bo, fence);
0104 kfree(*semaphore);
0105 *semaphore = NULL;
0106 }