intel_guc_ads.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * Copyright © 2014-2017 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 "intel_guc_ads.h"
  25. #include "intel_uc.h"
  26. #include "i915_drv.h"
  27. /*
  28. * The Additional Data Struct (ADS) has pointers for different buffers used by
  29. * the GuC. One single gem object contains the ADS struct itself (guc_ads), the
  30. * scheduling policies (guc_policies), a structure describing a collection of
  31. * register sets (guc_mmio_reg_state) and some extra pages for the GuC to save
  32. * its internal state for sleep.
  33. */
  34. static void guc_policy_init(struct guc_policy *policy)
  35. {
  36. policy->execution_quantum = POLICY_DEFAULT_EXECUTION_QUANTUM_US;
  37. policy->preemption_time = POLICY_DEFAULT_PREEMPTION_TIME_US;
  38. policy->fault_time = POLICY_DEFAULT_FAULT_TIME_US;
  39. policy->policy_flags = 0;
  40. }
  41. static void guc_policies_init(struct guc_policies *policies)
  42. {
  43. struct guc_policy *policy;
  44. u32 p, i;
  45. policies->dpc_promote_time = POLICY_DEFAULT_DPC_PROMOTE_TIME_US;
  46. policies->max_num_work_items = POLICY_MAX_NUM_WI;
  47. for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) {
  48. for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) {
  49. policy = &policies->policy[p][i];
  50. guc_policy_init(policy);
  51. }
  52. }
  53. policies->is_valid = 1;
  54. }
  55. /*
  56. * The first 80 dwords of the register state context, containing the
  57. * execlists and ppgtt registers.
  58. */
  59. #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
  60. /**
  61. * intel_guc_ads_create() - creates GuC ADS
  62. * @guc: intel_guc struct
  63. *
  64. */
  65. int intel_guc_ads_create(struct intel_guc *guc)
  66. {
  67. struct drm_i915_private *dev_priv = guc_to_i915(guc);
  68. struct i915_vma *vma, *kernel_ctx_vma;
  69. struct page *page;
  70. /* The ads obj includes the struct itself and buffers passed to GuC */
  71. struct {
  72. struct guc_ads ads;
  73. struct guc_policies policies;
  74. struct guc_mmio_reg_state reg_state;
  75. u8 reg_state_buffer[GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE];
  76. } __packed *blob;
  77. struct intel_engine_cs *engine;
  78. enum intel_engine_id id;
  79. const u32 skipped_offset = LRC_HEADER_PAGES * PAGE_SIZE;
  80. const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE;
  81. u32 base;
  82. GEM_BUG_ON(guc->ads_vma);
  83. vma = intel_guc_allocate_vma(guc, PAGE_ALIGN(sizeof(*blob)));
  84. if (IS_ERR(vma))
  85. return PTR_ERR(vma);
  86. guc->ads_vma = vma;
  87. page = i915_vma_first_page(vma);
  88. blob = kmap(page);
  89. /* GuC scheduling policies */
  90. guc_policies_init(&blob->policies);
  91. /* MMIO reg state */
  92. for_each_engine(engine, dev_priv, id) {
  93. blob->reg_state.white_list[engine->guc_id].mmio_start =
  94. engine->mmio_base + GUC_MMIO_WHITE_LIST_START;
  95. /* Nothing to be saved or restored for now. */
  96. blob->reg_state.white_list[engine->guc_id].count = 0;
  97. }
  98. /*
  99. * The GuC requires a "Golden Context" when it reinitialises
  100. * engines after a reset. Here we use the Render ring default
  101. * context, which must already exist and be pinned in the GGTT,
  102. * so its address won't change after we've told the GuC where
  103. * to find it. Note that we have to skip our header (1 page),
  104. * because our GuC shared data is there.
  105. */
  106. kernel_ctx_vma = to_intel_context(dev_priv->kernel_context,
  107. dev_priv->engine[RCS])->state;
  108. blob->ads.golden_context_lrca =
  109. intel_guc_ggtt_offset(guc, kernel_ctx_vma) + skipped_offset;
  110. /*
  111. * The GuC expects us to exclude the portion of the context image that
  112. * it skips from the size it is to read. It starts reading from after
  113. * the execlist context (so skipping the first page [PPHWSP] and 80
  114. * dwords). Weird guc is weird.
  115. */
  116. for_each_engine(engine, dev_priv, id)
  117. blob->ads.eng_state_size[engine->guc_id] =
  118. engine->context_size - skipped_size;
  119. base = intel_guc_ggtt_offset(guc, vma);
  120. blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
  121. blob->ads.reg_state_buffer = base + ptr_offset(blob, reg_state_buffer);
  122. blob->ads.reg_state_addr = base + ptr_offset(blob, reg_state);
  123. kunmap(page);
  124. return 0;
  125. }
  126. void intel_guc_ads_destroy(struct intel_guc *guc)
  127. {
  128. i915_vma_unpin_and_release(&guc->ads_vma, 0);
  129. }