Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2011 Christian König.
0003  * All Rights Reserved.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the
0007  * "Software"), to deal in the Software without restriction, including
0008  * without limitation the rights to use, copy, modify, merge, publish,
0009  * distribute, sub license, and/or sell copies of the Software, and to
0010  * permit persons to whom the Software is furnished to do so, subject to
0011  * the following conditions:
0012  *
0013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0014  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0015  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0016  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0017  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0018  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0019  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0020  *
0021  * The above copyright notice and this permission notice (including the
0022  * next paragraph) shall be included in all copies or substantial portions
0023  * of the Software.
0024  *
0025  */
0026 /*
0027  * Authors:
0028  *    Christian König <deathsimple@vodafone.de>
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         /* for debugging lockup only, used by sysfs debug files */
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         /* for debugging lockup only, used by sysfs debug files */
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 }