mock_gem_device.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Copyright © 2016 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. */
  24. #include <linux/pm_runtime.h>
  25. #include "mock_engine.h"
  26. #include "mock_context.h"
  27. #include "mock_request.h"
  28. #include "mock_gem_device.h"
  29. #include "mock_gem_object.h"
  30. #include "mock_gtt.h"
  31. #include "mock_uncore.h"
  32. void mock_device_flush(struct drm_i915_private *i915)
  33. {
  34. struct intel_engine_cs *engine;
  35. enum intel_engine_id id;
  36. lockdep_assert_held(&i915->drm.struct_mutex);
  37. for_each_engine(engine, i915, id)
  38. mock_engine_flush(engine);
  39. i915_gem_retire_requests(i915);
  40. }
  41. static void mock_device_release(struct drm_device *dev)
  42. {
  43. struct drm_i915_private *i915 = to_i915(dev);
  44. struct intel_engine_cs *engine;
  45. enum intel_engine_id id;
  46. mutex_lock(&i915->drm.struct_mutex);
  47. mock_device_flush(i915);
  48. mutex_unlock(&i915->drm.struct_mutex);
  49. cancel_delayed_work_sync(&i915->gt.retire_work);
  50. cancel_delayed_work_sync(&i915->gt.idle_work);
  51. mutex_lock(&i915->drm.struct_mutex);
  52. for_each_engine(engine, i915, id)
  53. mock_engine_free(engine);
  54. i915_gem_context_fini(i915);
  55. mutex_unlock(&i915->drm.struct_mutex);
  56. drain_workqueue(i915->wq);
  57. i915_gem_drain_freed_objects(i915);
  58. mutex_lock(&i915->drm.struct_mutex);
  59. mock_fini_ggtt(i915);
  60. i915_gem_timeline_fini(&i915->gt.global_timeline);
  61. mutex_unlock(&i915->drm.struct_mutex);
  62. destroy_workqueue(i915->wq);
  63. kmem_cache_destroy(i915->dependencies);
  64. kmem_cache_destroy(i915->requests);
  65. kmem_cache_destroy(i915->vmas);
  66. kmem_cache_destroy(i915->objects);
  67. drm_dev_fini(&i915->drm);
  68. put_device(&i915->drm.pdev->dev);
  69. }
  70. static struct drm_driver mock_driver = {
  71. .name = "mock",
  72. .driver_features = DRIVER_GEM,
  73. .release = mock_device_release,
  74. .gem_close_object = i915_gem_close_object,
  75. .gem_free_object_unlocked = i915_gem_free_object,
  76. };
  77. static void release_dev(struct device *dev)
  78. {
  79. struct pci_dev *pdev = to_pci_dev(dev);
  80. kfree(pdev);
  81. }
  82. static void mock_retire_work_handler(struct work_struct *work)
  83. {
  84. }
  85. static void mock_idle_work_handler(struct work_struct *work)
  86. {
  87. }
  88. struct drm_i915_private *mock_gem_device(void)
  89. {
  90. struct drm_i915_private *i915;
  91. struct intel_engine_cs *engine;
  92. enum intel_engine_id id;
  93. struct pci_dev *pdev;
  94. int err;
  95. pdev = kzalloc(sizeof(*pdev) + sizeof(*i915), GFP_KERNEL);
  96. if (!pdev)
  97. goto err;
  98. device_initialize(&pdev->dev);
  99. pdev->dev.release = release_dev;
  100. dev_set_name(&pdev->dev, "mock");
  101. dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  102. pm_runtime_dont_use_autosuspend(&pdev->dev);
  103. pm_runtime_get_sync(&pdev->dev);
  104. i915 = (struct drm_i915_private *)(pdev + 1);
  105. pci_set_drvdata(pdev, i915);
  106. err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
  107. if (err) {
  108. pr_err("Failed to initialise mock GEM device: err=%d\n", err);
  109. goto put_device;
  110. }
  111. i915->drm.pdev = pdev;
  112. i915->drm.dev_private = i915;
  113. /* Using the global GTT may ask questions about KMS users, so prepare */
  114. drm_mode_config_init(&i915->drm);
  115. mkwrite_device_info(i915)->gen = -1;
  116. spin_lock_init(&i915->mm.object_stat_lock);
  117. mock_uncore_init(i915);
  118. init_waitqueue_head(&i915->gpu_error.wait_queue);
  119. init_waitqueue_head(&i915->gpu_error.reset_queue);
  120. i915->wq = alloc_ordered_workqueue("mock", 0);
  121. if (!i915->wq)
  122. goto put_device;
  123. INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
  124. init_llist_head(&i915->mm.free_list);
  125. INIT_LIST_HEAD(&i915->mm.unbound_list);
  126. INIT_LIST_HEAD(&i915->mm.bound_list);
  127. ida_init(&i915->context_hw_ida);
  128. INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);
  129. INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler);
  130. i915->gt.awake = true;
  131. i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN);
  132. if (!i915->objects)
  133. goto err_wq;
  134. i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN);
  135. if (!i915->vmas)
  136. goto err_objects;
  137. i915->requests = KMEM_CACHE(mock_request,
  138. SLAB_HWCACHE_ALIGN |
  139. SLAB_RECLAIM_ACCOUNT |
  140. SLAB_DESTROY_BY_RCU);
  141. if (!i915->requests)
  142. goto err_vmas;
  143. i915->dependencies = KMEM_CACHE(i915_dependency,
  144. SLAB_HWCACHE_ALIGN |
  145. SLAB_RECLAIM_ACCOUNT);
  146. if (!i915->dependencies)
  147. goto err_requests;
  148. mutex_lock(&i915->drm.struct_mutex);
  149. INIT_LIST_HEAD(&i915->gt.timelines);
  150. err = i915_gem_timeline_init__global(i915);
  151. if (err) {
  152. mutex_unlock(&i915->drm.struct_mutex);
  153. goto err_dependencies;
  154. }
  155. mock_init_ggtt(i915);
  156. mutex_unlock(&i915->drm.struct_mutex);
  157. mkwrite_device_info(i915)->ring_mask = BIT(0);
  158. i915->engine[RCS] = mock_engine(i915, "mock");
  159. if (!i915->engine[RCS])
  160. goto err_dependencies;
  161. i915->kernel_context = mock_context(i915, NULL);
  162. if (!i915->kernel_context)
  163. goto err_engine;
  164. return i915;
  165. err_engine:
  166. for_each_engine(engine, i915, id)
  167. mock_engine_free(engine);
  168. err_dependencies:
  169. kmem_cache_destroy(i915->dependencies);
  170. err_requests:
  171. kmem_cache_destroy(i915->requests);
  172. err_vmas:
  173. kmem_cache_destroy(i915->vmas);
  174. err_objects:
  175. kmem_cache_destroy(i915->objects);
  176. err_wq:
  177. destroy_workqueue(i915->wq);
  178. put_device:
  179. put_device(&pdev->dev);
  180. err:
  181. return NULL;
  182. }