radeon_gem.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Copyright 2008 Advanced Micro Devices, Inc.
  3. * Copyright 2008 Red Hat Inc.
  4. * Copyright 2009 Jerome Glisse.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the "Software"),
  8. * to deal in the Software without restriction, including without limitation
  9. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the
  11. * Software is furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22. * OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * Authors: Dave Airlie
  25. * Alex Deucher
  26. * Jerome Glisse
  27. */
  28. #include "drmP.h"
  29. #include "drm.h"
  30. #include "radeon_drm.h"
  31. #include "radeon.h"
  32. int radeon_gem_object_init(struct drm_gem_object *obj)
  33. {
  34. /* we do nothings here */
  35. return 0;
  36. }
  37. void radeon_gem_object_free(struct drm_gem_object *gobj)
  38. {
  39. struct radeon_object *robj = gobj->driver_private;
  40. gobj->driver_private = NULL;
  41. if (robj) {
  42. radeon_object_unref(&robj);
  43. }
  44. }
  45. int radeon_gem_object_create(struct radeon_device *rdev, int size,
  46. int alignment, int initial_domain,
  47. bool discardable, bool kernel,
  48. bool interruptible,
  49. struct drm_gem_object **obj)
  50. {
  51. struct drm_gem_object *gobj;
  52. struct radeon_object *robj;
  53. int r;
  54. *obj = NULL;
  55. gobj = drm_gem_object_alloc(rdev->ddev, size);
  56. if (!gobj) {
  57. return -ENOMEM;
  58. }
  59. /* At least align on page size */
  60. if (alignment < PAGE_SIZE) {
  61. alignment = PAGE_SIZE;
  62. }
  63. r = radeon_object_create(rdev, gobj, size, kernel, initial_domain,
  64. interruptible, &robj);
  65. if (r) {
  66. DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n",
  67. size, initial_domain, alignment);
  68. mutex_lock(&rdev->ddev->struct_mutex);
  69. drm_gem_object_unreference(gobj);
  70. mutex_unlock(&rdev->ddev->struct_mutex);
  71. return r;
  72. }
  73. gobj->driver_private = robj;
  74. *obj = gobj;
  75. return 0;
  76. }
  77. int radeon_gem_object_pin(struct drm_gem_object *obj, uint32_t pin_domain,
  78. uint64_t *gpu_addr)
  79. {
  80. struct radeon_object *robj = obj->driver_private;
  81. uint32_t flags;
  82. switch (pin_domain) {
  83. case RADEON_GEM_DOMAIN_VRAM:
  84. flags = TTM_PL_FLAG_VRAM;
  85. break;
  86. case RADEON_GEM_DOMAIN_GTT:
  87. flags = TTM_PL_FLAG_TT;
  88. break;
  89. default:
  90. flags = TTM_PL_FLAG_SYSTEM;
  91. break;
  92. }
  93. return radeon_object_pin(robj, flags, gpu_addr);
  94. }
  95. void radeon_gem_object_unpin(struct drm_gem_object *obj)
  96. {
  97. struct radeon_object *robj = obj->driver_private;
  98. radeon_object_unpin(robj);
  99. }
  100. int radeon_gem_set_domain(struct drm_gem_object *gobj,
  101. uint32_t rdomain, uint32_t wdomain)
  102. {
  103. struct radeon_object *robj;
  104. uint32_t domain;
  105. int r;
  106. /* FIXME: reeimplement */
  107. robj = gobj->driver_private;
  108. /* work out where to validate the buffer to */
  109. domain = wdomain;
  110. if (!domain) {
  111. domain = rdomain;
  112. }
  113. if (!domain) {
  114. /* Do nothings */
  115. printk(KERN_WARNING "Set domain withou domain !\n");
  116. return 0;
  117. }
  118. if (domain == RADEON_GEM_DOMAIN_CPU) {
  119. /* Asking for cpu access wait for object idle */
  120. r = radeon_object_wait(robj);
  121. if (r) {
  122. printk(KERN_ERR "Failed to wait for object !\n");
  123. return r;
  124. }
  125. }
  126. return 0;
  127. }
  128. int radeon_gem_init(struct radeon_device *rdev)
  129. {
  130. INIT_LIST_HEAD(&rdev->gem.objects);
  131. return 0;
  132. }
  133. void radeon_gem_fini(struct radeon_device *rdev)
  134. {
  135. radeon_object_force_delete(rdev);
  136. }
  137. /*
  138. * GEM ioctls.
  139. */
  140. int radeon_gem_info_ioctl(struct drm_device *dev, void *data,
  141. struct drm_file *filp)
  142. {
  143. struct radeon_device *rdev = dev->dev_private;
  144. struct drm_radeon_gem_info *args = data;
  145. args->vram_size = rdev->mc.vram_size;
  146. /* FIXME: report somethings that makes sense */
  147. args->vram_visible = rdev->mc.vram_size - (4 * 1024 * 1024);
  148. args->gart_size = rdev->mc.gtt_size;
  149. return 0;
  150. }
  151. int radeon_gem_pread_ioctl(struct drm_device *dev, void *data,
  152. struct drm_file *filp)
  153. {
  154. /* TODO: implement */
  155. DRM_ERROR("unimplemented %s\n", __func__);
  156. return -ENOSYS;
  157. }
  158. int radeon_gem_pwrite_ioctl(struct drm_device *dev, void *data,
  159. struct drm_file *filp)
  160. {
  161. /* TODO: implement */
  162. DRM_ERROR("unimplemented %s\n", __func__);
  163. return -ENOSYS;
  164. }
  165. int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
  166. struct drm_file *filp)
  167. {
  168. struct radeon_device *rdev = dev->dev_private;
  169. struct drm_radeon_gem_create *args = data;
  170. struct drm_gem_object *gobj;
  171. uint32_t handle;
  172. int r;
  173. /* create a gem object to contain this object in */
  174. args->size = roundup(args->size, PAGE_SIZE);
  175. r = radeon_gem_object_create(rdev, args->size, args->alignment,
  176. args->initial_domain, false,
  177. false, true, &gobj);
  178. if (r) {
  179. return r;
  180. }
  181. r = drm_gem_handle_create(filp, gobj, &handle);
  182. if (r) {
  183. mutex_lock(&dev->struct_mutex);
  184. drm_gem_object_unreference(gobj);
  185. mutex_unlock(&dev->struct_mutex);
  186. return r;
  187. }
  188. mutex_lock(&dev->struct_mutex);
  189. drm_gem_object_handle_unreference(gobj);
  190. mutex_unlock(&dev->struct_mutex);
  191. args->handle = handle;
  192. return 0;
  193. }
  194. int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
  195. struct drm_file *filp)
  196. {
  197. /* transition the BO to a domain -
  198. * just validate the BO into a certain domain */
  199. struct drm_radeon_gem_set_domain *args = data;
  200. struct drm_gem_object *gobj;
  201. struct radeon_object *robj;
  202. int r;
  203. /* for now if someone requests domain CPU -
  204. * just make sure the buffer is finished with */
  205. /* just do a BO wait for now */
  206. gobj = drm_gem_object_lookup(dev, filp, args->handle);
  207. if (gobj == NULL) {
  208. return -EINVAL;
  209. }
  210. robj = gobj->driver_private;
  211. r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
  212. mutex_lock(&dev->struct_mutex);
  213. drm_gem_object_unreference(gobj);
  214. mutex_unlock(&dev->struct_mutex);
  215. return r;
  216. }
  217. int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
  218. struct drm_file *filp)
  219. {
  220. struct drm_radeon_gem_mmap *args = data;
  221. struct drm_gem_object *gobj;
  222. struct radeon_object *robj;
  223. int r;
  224. gobj = drm_gem_object_lookup(dev, filp, args->handle);
  225. if (gobj == NULL) {
  226. return -EINVAL;
  227. }
  228. robj = gobj->driver_private;
  229. r = radeon_object_mmap(robj, &args->addr_ptr);
  230. mutex_lock(&dev->struct_mutex);
  231. drm_gem_object_unreference(gobj);
  232. mutex_unlock(&dev->struct_mutex);
  233. return r;
  234. }
  235. int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
  236. struct drm_file *filp)
  237. {
  238. /* FIXME: implement */
  239. return 0;
  240. }
  241. int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
  242. struct drm_file *filp)
  243. {
  244. struct drm_radeon_gem_wait_idle *args = data;
  245. struct drm_gem_object *gobj;
  246. struct radeon_object *robj;
  247. int r;
  248. gobj = drm_gem_object_lookup(dev, filp, args->handle);
  249. if (gobj == NULL) {
  250. return -EINVAL;
  251. }
  252. robj = gobj->driver_private;
  253. r = radeon_object_wait(robj);
  254. mutex_lock(&dev->struct_mutex);
  255. drm_gem_object_unreference(gobj);
  256. mutex_unlock(&dev->struct_mutex);
  257. return r;
  258. }