radeon_semaphore.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright 2011 Christian König.
  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. */
  26. /*
  27. * Authors:
  28. * Christian König <deathsimple@vodafone.de>
  29. */
  30. #include "drmP.h"
  31. #include "drm.h"
  32. #include "radeon.h"
  33. static int radeon_semaphore_add_bo(struct radeon_device *rdev)
  34. {
  35. struct radeon_semaphore_bo *bo;
  36. unsigned long irq_flags;
  37. uint64_t gpu_addr;
  38. uint32_t *cpu_ptr;
  39. int r, i;
  40. bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL);
  41. if (bo == NULL) {
  42. return -ENOMEM;
  43. }
  44. INIT_LIST_HEAD(&bo->free);
  45. INIT_LIST_HEAD(&bo->list);
  46. bo->nused = 0;
  47. r = radeon_ib_get(rdev, 0, &bo->ib, RADEON_SEMAPHORE_BO_SIZE);
  48. if (r) {
  49. dev_err(rdev->dev, "failed to get a bo after 5 retry\n");
  50. kfree(bo);
  51. return r;
  52. }
  53. gpu_addr = rdev->ib_pool.sa_manager.gpu_addr;
  54. gpu_addr += bo->ib->sa_bo.offset;
  55. cpu_ptr = rdev->ib_pool.sa_manager.cpu_ptr;
  56. cpu_ptr += (bo->ib->sa_bo.offset >> 2);
  57. for (i = 0; i < (RADEON_SEMAPHORE_BO_SIZE/8); i++) {
  58. bo->semaphores[i].gpu_addr = gpu_addr;
  59. bo->semaphores[i].cpu_ptr = cpu_ptr;
  60. bo->semaphores[i].bo = bo;
  61. list_add_tail(&bo->semaphores[i].list, &bo->free);
  62. gpu_addr += 8;
  63. cpu_ptr += 2;
  64. }
  65. write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
  66. list_add_tail(&bo->list, &rdev->semaphore_drv.bo);
  67. write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
  68. return 0;
  69. }
  70. static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev,
  71. struct radeon_semaphore_bo *bo)
  72. {
  73. radeon_sa_bo_free(rdev, &bo->ib->sa_bo);
  74. radeon_fence_unref(&bo->ib->fence);
  75. list_del(&bo->list);
  76. kfree(bo);
  77. }
  78. void radeon_semaphore_shrink_locked(struct radeon_device *rdev)
  79. {
  80. struct radeon_semaphore_bo *bo, *n;
  81. if (list_empty(&rdev->semaphore_drv.bo)) {
  82. return;
  83. }
  84. /* only shrink if first bo has free semaphore */
  85. bo = list_first_entry(&rdev->semaphore_drv.bo, struct radeon_semaphore_bo, list);
  86. if (list_empty(&bo->free)) {
  87. return;
  88. }
  89. list_for_each_entry_safe_continue(bo, n, &rdev->semaphore_drv.bo, list) {
  90. if (bo->nused)
  91. continue;
  92. radeon_semaphore_del_bo_locked(rdev, bo);
  93. }
  94. }
  95. int radeon_semaphore_create(struct radeon_device *rdev,
  96. struct radeon_semaphore **semaphore)
  97. {
  98. struct radeon_semaphore_bo *bo;
  99. unsigned long irq_flags;
  100. bool do_retry = true;
  101. int r;
  102. retry:
  103. *semaphore = NULL;
  104. write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
  105. list_for_each_entry(bo, &rdev->semaphore_drv.bo, list) {
  106. if (list_empty(&bo->free))
  107. continue;
  108. *semaphore = list_first_entry(&bo->free, struct radeon_semaphore, list);
  109. (*semaphore)->cpu_ptr[0] = 0;
  110. (*semaphore)->cpu_ptr[1] = 0;
  111. list_del(&(*semaphore)->list);
  112. bo->nused++;
  113. break;
  114. }
  115. write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
  116. if (*semaphore == NULL) {
  117. if (do_retry) {
  118. do_retry = false;
  119. r = radeon_semaphore_add_bo(rdev);
  120. if (r)
  121. return r;
  122. goto retry;
  123. }
  124. return -ENOMEM;
  125. }
  126. return 0;
  127. }
  128. void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
  129. struct radeon_semaphore *semaphore)
  130. {
  131. radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false);
  132. }
  133. void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
  134. struct radeon_semaphore *semaphore)
  135. {
  136. radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true);
  137. }
  138. void radeon_semaphore_free(struct radeon_device *rdev,
  139. struct radeon_semaphore *semaphore)
  140. {
  141. unsigned long irq_flags;
  142. write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
  143. semaphore->bo->nused--;
  144. list_add_tail(&semaphore->list, &semaphore->bo->free);
  145. radeon_semaphore_shrink_locked(rdev);
  146. write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
  147. }
  148. void radeon_semaphore_driver_fini(struct radeon_device *rdev)
  149. {
  150. struct radeon_semaphore_bo *bo, *n;
  151. unsigned long irq_flags;
  152. write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
  153. /* we force to free everything */
  154. list_for_each_entry_safe(bo, n, &rdev->semaphore_drv.bo, list) {
  155. if (!list_empty(&bo->free)) {
  156. dev_err(rdev->dev, "still in use semaphore\n");
  157. }
  158. radeon_semaphore_del_bo_locked(rdev, bo);
  159. }
  160. write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
  161. }