mock_gem_device.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. void mock_device_flush(struct drm_i915_private *i915)
  32. {
  33. struct intel_engine_cs *engine;
  34. enum intel_engine_id id;
  35. lockdep_assert_held(&i915->drm.struct_mutex);
  36. for_each_engine(engine, i915, id)
  37. mock_engine_flush(engine);
  38. i915_gem_retire_requests(i915);
  39. }
  40. static void mock_device_release(struct drm_device *dev)
  41. {
  42. struct drm_i915_private *i915 = to_i915(dev);
  43. struct intel_engine_cs *engine;
  44. enum intel_engine_id id;
  45. mutex_lock(&i915->drm.struct_mutex);
  46. mock_device_flush(i915);
  47. mutex_unlock(&i915->drm.struct_mutex);
  48. cancel_delayed_work_sync(&i915->gt.retire_work);
  49. cancel_delayed_work_sync(&i915->gt.idle_work);
  50. mutex_lock(&i915->drm.struct_mutex);
  51. for_each_engine(engine, i915, id)
  52. mock_engine_free(engine);
  53. i915_gem_context_fini(i915);
  54. mutex_unlock(&i915->drm.struct_mutex);
  55. drain_workqueue(i915->wq);
  56. i915_gem_drain_freed_objects(i915);
  57. mutex_lock(&i915->drm.struct_mutex);
  58. mock_fini_ggtt(i915);
  59. i915_gem_timeline_fini(&i915->gt.global_timeline);
  60. mutex_unlock(&i915->drm.struct_mutex);
  61. destroy_workqueue(i915->wq);
  62. kmem_cache_destroy(i915->dependencies);
  63. kmem_cache_destroy(i915->requests);
  64. kmem_cache_destroy(i915->vmas);
  65. kmem_cache_destroy(i915->objects);
  66. drm_dev_fini(&i915->drm);
  67. put_device(&i915->drm.pdev->dev);
  68. }
  69. static struct drm_driver mock_driver = {
  70. .name = "mock",
  71. .driver_features = DRIVER_GEM,
  72. .release = mock_device_release,
  73. .gem_close_object = i915_gem_close_object,
  74. .gem_free_object_unlocked = i915_gem_free_object,
  75. };
  76. static void release_dev(struct device *dev)
  77. {
  78. struct pci_dev *pdev = to_pci_dev(dev);
  79. kfree(pdev);
  80. }
  81. static void mock_retire_work_handler(struct work_struct *work)
  82. {
  83. }
  84. static void mock_idle_work_handler(struct work_struct *work)
  85. {
  86. }
  87. struct drm_i915_private *mock_gem_device(void)
  88. {
  89. struct drm_i915_private *i915;
  90. struct intel_engine_cs *engine;
  91. enum intel_engine_id id;
  92. struct pci_dev *pdev;
  93. int err;
  94. pdev = kzalloc(sizeof(*pdev) + sizeof(*i915), GFP_KERNEL);
  95. if (!pdev)
  96. goto err;
  97. device_initialize(&pdev->dev);
  98. pdev->dev.release = release_dev;
  99. dev_set_name(&pdev->dev, "mock");
  100. dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
  101. pm_runtime_dont_use_autosuspend(&pdev->dev);
  102. pm_runtime_get_sync(&pdev->dev);
  103. i915 = (struct drm_i915_private *)(pdev + 1);
  104. pci_set_drvdata(pdev, i915);
  105. err = drm_dev_init(&i915->drm, &mock_driver, &pdev->dev);
  106. if (err) {
  107. pr_err("Failed to initialise mock GEM device: err=%d\n", err);
  108. goto put_device;
  109. }
  110. i915->drm.pdev = pdev;
  111. i915->drm.dev_private = i915;
  112. /* Using the global GTT may ask questions about KMS users, so prepare */
  113. drm_mode_config_init(&i915->drm);
  114. mkwrite_device_info(i915)->gen = -1;
  115. spin_lock_init(&i915->mm.object_stat_lock);
  116. init_waitqueue_head(&i915->gpu_error.wait_queue);
  117. init_waitqueue_head(&i915->gpu_error.reset_queue);
  118. i915->wq = alloc_ordered_workqueue("mock", 0);
  119. if (!i915->wq)
  120. goto put_device;
  121. INIT_WORK(&i915->mm.free_work, __i915_gem_free_work);
  122. init_llist_head(&i915->mm.free_list);
  123. INIT_LIST_HEAD(&i915->mm.unbound_list);
  124. INIT_LIST_HEAD(&i915->mm.bound_list);
  125. ida_init(&i915->context_hw_ida);
  126. INIT_DELAYED_WORK(&i915->gt.retire_work, mock_retire_work_handler);
  127. INIT_DELAYED_WORK(&i915->gt.idle_work, mock_idle_work_handler);
  128. i915->gt.awake = true;
  129. i915->objects = KMEM_CACHE(mock_object, SLAB_HWCACHE_ALIGN);
  130. if (!i915->objects)
  131. goto err_wq;
  132. i915->vmas = KMEM_CACHE(i915_vma, SLAB_HWCACHE_ALIGN);
  133. if (!i915->vmas)
  134. goto err_objects;
  135. i915->requests = KMEM_CACHE(mock_request,
  136. SLAB_HWCACHE_ALIGN |
  137. SLAB_RECLAIM_ACCOUNT |
  138. SLAB_TYPESAFE_BY_RCU);
  139. if (!i915->requests)
  140. goto err_vmas;
  141. i915->dependencies = KMEM_CACHE(i915_dependency,
  142. SLAB_HWCACHE_ALIGN |
  143. SLAB_RECLAIM_ACCOUNT);
  144. if (!i915->dependencies)
  145. goto err_requests;
  146. mutex_lock(&i915->drm.struct_mutex);
  147. INIT_LIST_HEAD(&i915->gt.timelines);
  148. err = i915_gem_timeline_init__global(i915);
  149. if (err) {
  150. mutex_unlock(&i915->drm.struct_mutex);
  151. goto err_dependencies;
  152. }
  153. mock_init_ggtt(i915);
  154. mutex_unlock(&i915->drm.struct_mutex);
  155. mkwrite_device_info(i915)->ring_mask = BIT(0);
  156. i915->engine[RCS] = mock_engine(i915, "mock");
  157. if (!i915->engine[RCS])
  158. goto err_dependencies;
  159. i915->kernel_context = mock_context(i915, NULL);
  160. if (!i915->kernel_context)
  161. goto err_engine;
  162. return i915;
  163. err_engine:
  164. for_each_engine(engine, i915, id)
  165. mock_engine_free(engine);
  166. err_dependencies:
  167. kmem_cache_destroy(i915->dependencies);
  168. err_requests:
  169. kmem_cache_destroy(i915->requests);
  170. err_vmas:
  171. kmem_cache_destroy(i915->vmas);
  172. err_objects:
  173. kmem_cache_destroy(i915->objects);
  174. err_wq:
  175. destroy_workqueue(i915->wq);
  176. put_device:
  177. put_device(&pdev->dev);
  178. err:
  179. return NULL;
  180. }