History

Merge tag 'drm-intel-gt-next-2024-02-15' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

UAPI Changes: - Add GuC submission interface version query (Tvrtko Ursulin) Driver Changes: Fixes/improvements/new stuff: - Atomically invalidate userptr on mmu-notifier (Jonathan Cavitt) - Update handling of MMIO triggered reports (Umesh Nerlige Ramappa) - Don't make assumptions about intel_wakeref_t type (Jani Nikula) - Add workaround 14019877138 [xelpg] (Tejas Upadhyay) - Allow for very slow HuC loading [huc] (John Harrison) - Flush context destruction worker at suspend [guc] (Alan Previn) - Close deregister-context race against CT-loss [guc] (Alan Previn) - Avoid circular locking issue on busyness flush [guc] (John Harrison) - Use rc6.supported flag from intel_gt for rc6_enable sysfs (Juan Escamilla) - Reflect the true and current status of rc6_enable (Juan Escamilla) - Wake GT before sending H2G message [mtl] (Vinay Belgaumkar) - Restart the heartbeat timer when forcing a pulse (John Harrison) Future platform enablement: - Extend driver code of Xe_LPG to Xe_LPG+ [xelpg] (Harish Chegondi) - Extend some workarounds/tuning to gfx version 12.74 [xelpg] (Matt Roper) Miscellaneous: - Reconcile Excess struct member kernel-doc warnings (Randy Dunlap) - Change wa and EU_PERF_CNTL registers to MCR type [guc] (Shuicheng Lin) - Add flex arrays to struct i915_syncmap (Erick Archer) - Increasing the sleep time for live_rc6_manual [selftests] (Anirban Sk)

Dave Airlie committed 2 years ago

Commit 6f167a32 parents b13cfb4 eb927f026 files · +301 −149Browse files

Unified · Split

26 files
  1. drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +0 −8
  2. drivers/gpu/drm/i915/gem/i915_gem_pm.c +10 −0
  3. drivers/gpu/drm/i915/gem/i915_gem_userptr.c +0 −42
  4. drivers/gpu/drm/i915/gem/i915_gem_userptr.h +0 −14
  5. drivers/gpu/drm/i915/gt/gen8_engine_cs.c +2 −2
  6. drivers/gpu/drm/i915/gt/intel_engine_cs.c +2 −1
  7. drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c +3 −0
  8. drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +2 −16
  9. drivers/gpu/drm/i915/gt/intel_mocs.c +1 −1
  10. drivers/gpu/drm/i915/gt/intel_rc6.c +1 −1
  11. drivers/gpu/drm/i915/gt/intel_workarounds.c +18 −9
  12. drivers/gpu/drm/i915/gt/selftest_rc6.c +2 −2
  13. drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c +13 −8
  14. drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c +5 −5
  15. drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +120 −6
  16. drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h +2 −0
  17. drivers/gpu/drm/i915/gt/uc/intel_huc.c +58 −6
  18. drivers/gpu/drm/i915/gt/uc/intel_uc.c +3 −1
  19. drivers/gpu/drm/i915/i915_debugfs.c +1 −1
  20. drivers/gpu/drm/i915/i915_drv.h +0 −8
  21. drivers/gpu/drm/i915/i915_gem.c +0 −5
  22. drivers/gpu/drm/i915/i915_perf.c +1 −1
  23. drivers/gpu/drm/i915/i915_query.c +33 −0
  24. drivers/gpu/drm/i915/i915_syncmap.c +8 −11
  25. drivers/gpu/drm/i915/intel_uncore.c +4 −1
  26. include/uapi/drm/i915_drm.h +12 −0
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c+0−8
@@ -2160,12 +2160,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) · 2159 unmodified lines
2160 2160
2161#ifdef CONFIG_MMU_NOTIFIER2161#ifdef CONFIG_MMU_NOTIFIER
2162 if (!err && (eb->args->flags & __EXEC_USERPTR_USED)) {2162 if (!err && (eb->args->flags & __EXEC_USERPTR_USED)) {
2163 read_lock(&eb->i915->mm.notifier_lock);
2164
2165 /*
2166 * count is always at least 1, otherwise __EXEC_USERPTR_USED
2167 * could not have been set
2168 */
2169 for (i = 0; i < count; i++) {2163 for (i = 0; i < count; i++) {
2170 struct eb_vma *ev = &eb->vma[i];2164 struct eb_vma *ev = &eb->vma[i];
2171 struct drm_i915_gem_object *obj = ev->vma->obj;2165 struct drm_i915_gem_object *obj = ev->vma->obj;
@@ -2177,8 +2171,6 @@ static int eb_move_to_gpu(struct i915_execbuffer *eb) · 5 unmodified lines
2177 if (err)2171 if (err)
2178 break;2172 break;
2179 }2173 }
2180
2181 read_unlock(&eb->i915->mm.notifier_lock);
2182 }2174 }
2183#endif2175#endif
2184 2176
drivers/gpu/drm/i915/gem/i915_gem_pm.c+10−0
@@ -28,6 +28,13 @@ void i915_gem_suspend(struct drm_i915_private *i915) · 27 unmodified lines
28 GEM_TRACE("%s\n", dev_name(i915->drm.dev));28 GEM_TRACE("%s\n", dev_name(i915->drm.dev));
29 29
30 intel_wakeref_auto(&i915->runtime_pm.userfault_wakeref, 0);30 intel_wakeref_auto(&i915->runtime_pm.userfault_wakeref, 0);
31 /*
32 * On rare occasions, we've observed the fence completion triggers
33 * free_engines asynchronously via rcu_call. Ensure those are done.
34 * This path is only called on suspend, so it's an acceptable cost.
35 */
36 rcu_barrier();
37
31 flush_workqueue(i915->wq);38 flush_workqueue(i915->wq);
32 39
33 /*40 /*
@@ -160,6 +167,9 @@ void i915_gem_suspend_late(struct drm_i915_private *i915) · 126 unmodified lines
160 * machine in an unusable condition.167 * machine in an unusable condition.
161 */168 */
162 169
170 /* Like i915_gem_suspend, flush tasks staged from fence triggers */
171 rcu_barrier();
172
163 for_each_gt(gt, i915, i)173 for_each_gt(gt, i915, i)
164 intel_gt_suspend_late(gt);174 intel_gt_suspend_late(gt);
165 175
drivers/gpu/drm/i915/gem/i915_gem_userptr.c+0−42
@@ -42,7 +42,6 @@ · 41 unmodified lines
42#include "i915_drv.h"42#include "i915_drv.h"
43#include "i915_gem_ioctls.h"43#include "i915_gem_ioctls.h"
44#include "i915_gem_object.h"44#include "i915_gem_object.h"
45#include "i915_gem_userptr.h"
46#include "i915_scatterlist.h"45#include "i915_scatterlist.h"
47 46
48#ifdef CONFIG_MMU_NOTIFIER47#ifdef CONFIG_MMU_NOTIFIER
@@ -61,36 +60,7 @@ static bool i915_gem_userptr_invalidate(struct mmu_interval_notifier *mni, · 12 unmodified lines
61 const struct mmu_notifier_range *range,60 const struct mmu_notifier_range *range,
62 unsigned long cur_seq)61 unsigned long cur_seq)
63{62{
64 struct drm_i915_gem_object *obj = container_of(mni, struct drm_i915_gem_object, userptr.notifier);
65 struct drm_i915_private *i915 = to_i915(obj->base.dev);
66 long r;
67
68 if (!mmu_notifier_range_blockable(range))
69 return false;
70
71 write_lock(&i915->mm.notifier_lock);
72
73 mmu_interval_set_seq(mni, cur_seq);63 mmu_interval_set_seq(mni, cur_seq);
74
75 write_unlock(&i915->mm.notifier_lock);
76
77 /*
78 * We don't wait when the process is exiting. This is valid
79 * because the object will be cleaned up anyway.
80 *
81 * This is also temporarily required as a hack, because we
82 * cannot currently force non-consistent batch buffers to preempt
83 * and reschedule by waiting on it, hanging processes on exit.
84 */
85 if (current->flags & PF_EXITING)
86 return true;
87
88 /* we will unbind on next submission, still have userptr pins */
89 r = dma_resv_wait_timeout(obj->base.resv, DMA_RESV_USAGE_BOOKKEEP, false,
90 MAX_SCHEDULE_TIMEOUT);
91 if (r <= 0)
92 drm_err(&i915->drm, "(%ld) failed to wait for idle\n", r);
93
94 return true;64 return true;
95}65}
96 66
@@ -580,15 +550,3 @@ i915_gem_userptr_ioctl(struct drm_device *dev, · 483 unmodified lines
580#endif550#endif
581}551}
582 552
583int i915_gem_init_userptr(struct drm_i915_private *dev_priv)
584{
585#ifdef CONFIG_MMU_NOTIFIER
586 rwlock_init(&dev_priv->mm.notifier_lock);
587#endif
588
589 return 0;
590}
591
592void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv)
593{
594}
drivers/gpu/drm/i915/gem/i915_gem_userptr.h+0−14
@@ -1,14 +0,0 @@
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2021 Intel Corporation
4 */
5
6#ifndef __I915_GEM_USERPTR_H__
7#define __I915_GEM_USERPTR_H__
8
9struct drm_i915_private;
10
11int i915_gem_init_userptr(struct drm_i915_private *dev_priv);
12void i915_gem_cleanup_userptr(struct drm_i915_private *dev_priv);
13
14#endif /* __I915_GEM_USERPTR_H__ */
drivers/gpu/drm/i915/gt/gen8_engine_cs.c+2−2
@@ -226,7 +226,7 @@ u32 *gen12_emit_aux_table_inv(struct intel_engine_cs *engine, u32 *cs) · 225 unmodified lines
226static int mtl_dummy_pipe_control(struct i915_request *rq)226static int mtl_dummy_pipe_control(struct i915_request *rq)
227{227{
228 /* Wa_14016712196 */228 /* Wa_14016712196 */
229 if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 71)) ||229 if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||
230 IS_DG2(rq->i915)) {230 IS_DG2(rq->i915)) {
231 u32 *cs;231 u32 *cs;
232 232
@@ -822,7 +822,7 @@ u32 *gen12_emit_fini_breadcrumb_rcs(struct i915_request *rq, u32 *cs) · 589 unmodified lines
822 flags |= PIPE_CONTROL_FLUSH_L3;822 flags |= PIPE_CONTROL_FLUSH_L3;
823 823
824 /* Wa_14016712196 */824 /* Wa_14016712196 */
825 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))825 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915))
826 /* dummy PIPE_CONTROL + depth flush */826 /* dummy PIPE_CONTROL + depth flush */
827 cs = gen12_emit_pipe_control(cs, 0,827 cs = gen12_emit_pipe_control(cs, 0,
828 PIPE_CONTROL_DEPTH_CACHE_FLUSH, 0);828 PIPE_CONTROL_DEPTH_CACHE_FLUSH, 0);
drivers/gpu/drm/i915/gt/intel_engine_cs.c+2−1
@@ -1190,7 +1190,8 @@ static int intel_engine_init_tlb_invalidation(struct intel_engine_cs *engine) · 1189 unmodified lines
1190 num = ARRAY_SIZE(xelpmp_regs);1190 num = ARRAY_SIZE(xelpmp_regs);
1191 }1191 }
1192 } else {1192 } else {
1193 if (GRAPHICS_VER_FULL(i915) == IP_VER(12, 71) ||1193 if (GRAPHICS_VER_FULL(i915) == IP_VER(12, 74) ||
1194 GRAPHICS_VER_FULL(i915) == IP_VER(12, 71) ||
1194 GRAPHICS_VER_FULL(i915) == IP_VER(12, 70) ||1195 GRAPHICS_VER_FULL(i915) == IP_VER(12, 70) ||
1195 GRAPHICS_VER_FULL(i915) == IP_VER(12, 50) ||1196 GRAPHICS_VER_FULL(i915) == IP_VER(12, 50) ||
1196 GRAPHICS_VER_FULL(i915) == IP_VER(12, 55)) {1197 GRAPHICS_VER_FULL(i915) == IP_VER(12, 55)) {
drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c+3−0
@@ -290,6 +290,9 @@ static int __intel_engine_pulse(struct intel_engine_cs *engine) · 289 unmodified lines
290 heartbeat_commit(rq, &attr);290 heartbeat_commit(rq, &attr);
291 GEM_BUG_ON(rq->sched.attr.priority < I915_PRIORITY_BARRIER);291 GEM_BUG_ON(rq->sched.attr.priority < I915_PRIORITY_BARRIER);
292 292
293 /* Ensure the forced pulse gets a full period to execute */
294 next_heartbeat(engine);
295
293 return 0;296 return 0;
294}297}
295 298
drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c+2−16
@@ -176,27 +176,13 @@ static u32 get_residency(struct intel_gt *gt, enum intel_rc6_res_type id) · 175 unmodified lines
176 return DIV_ROUND_CLOSEST_ULL(res, 1000);176 return DIV_ROUND_CLOSEST_ULL(res, 1000);
177}177}
178 178
179static u8 get_rc6_mask(struct intel_gt *gt)
180{
181 u8 mask = 0;
182
183 if (HAS_RC6(gt->i915))
184 mask |= BIT(0);
185 if (HAS_RC6p(gt->i915))
186 mask |= BIT(1);
187 if (HAS_RC6pp(gt->i915))
188 mask |= BIT(2);
189
190 return mask;
191}
192
193static ssize_t rc6_enable_show(struct kobject *kobj,179static ssize_t rc6_enable_show(struct kobject *kobj,
194 struct kobj_attribute *attr,180 struct kobj_attribute *attr,
195 char *buff)181 char *buff)
196{182{
197 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);183 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(kobj, attr->attr.name);
198 184
199 return sysfs_emit(buff, "%x\n", get_rc6_mask(gt));185 return sysfs_emit(buff, "%x\n", gt->rc6.enabled);
200}186}
201 187
202static ssize_t rc6_enable_dev_show(struct device *dev,188static ssize_t rc6_enable_dev_show(struct device *dev,
@@ -205,7 +191,7 @@ static ssize_t rc6_enable_dev_show(struct device *dev, · 2 unmodified lines
205{191{
206 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(&dev->kobj, attr->attr.name);192 struct intel_gt *gt = intel_gt_sysfs_get_drvdata(&dev->kobj, attr->attr.name);
207 193
208 return sysfs_emit(buff, "%x\n", get_rc6_mask(gt));194 return sysfs_emit(buff, "%x\n", gt->rc6.enabled);
209}195}
210 196
211static u32 __rc6_residency_ms_show(struct intel_gt *gt)197static u32 __rc6_residency_ms_show(struct intel_gt *gt)
drivers/gpu/drm/i915/gt/intel_mocs.c+1−1
@@ -495,7 +495,7 @@ static unsigned int get_mocs_settings(struct drm_i915_private *i915, · 494 unmodified lines
495 memset(table, 0, sizeof(struct drm_i915_mocs_table));495 memset(table, 0, sizeof(struct drm_i915_mocs_table));
496 496
497 table->unused_entries_index = I915_MOCS_PTE;497 table->unused_entries_index = I915_MOCS_PTE;
498 if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 71))) {498 if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 74))) {
499 table->size = ARRAY_SIZE(mtl_mocs_table);499 table->size = ARRAY_SIZE(mtl_mocs_table);
500 table->table = mtl_mocs_table;500 table->table = mtl_mocs_table;
501 table->n_entries = MTL_NUM_MOCS_ENTRIES;501 table->n_entries = MTL_NUM_MOCS_ENTRIES;
drivers/gpu/drm/i915/gt/intel_rc6.c+1−1
@@ -123,7 +123,7 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6) · 122 unmodified lines
123 * temporary wa and should be removed after fixing real cause123 * temporary wa and should be removed after fixing real cause
124 * of forcewake timeouts.124 * of forcewake timeouts.
125 */125 */
126 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))126 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))
127 pg_enable =127 pg_enable =
128 GEN9_MEDIA_PG_ENABLE |128 GEN9_MEDIA_PG_ENABLE |
129 GEN11_MEDIA_SAMPLER_PG_ENABLE;129 GEN11_MEDIA_SAMPLER_PG_ENABLE;
drivers/gpu/drm/i915/gt/intel_workarounds.c+18−9
@@ -789,8 +789,13 @@ static void xelpg_ctx_gt_tuning_init(struct intel_engine_cs *engine, · 788 unmodified lines
789 789
790 dg2_ctx_gt_tuning_init(engine, wal);790 dg2_ctx_gt_tuning_init(engine, wal);
791 791
792 if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||792 /*
793 IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))793 * Due to Wa_16014892111, the DRAW_WATERMARK tuning must be done in
794 * gen12_emit_indirect_ctx_rcs() rather than here on some early
795 * steppings.
796 */
797 if (!(IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
798 IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)))
794 wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);799 wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);
795}800}
796 801
@@ -820,6 +825,9 @@ static void xelpg_ctx_workarounds_init(struct intel_engine_cs *engine, · 23 unmodified lines
820 825
821 /* Wa_18019271663 */826 /* Wa_18019271663 */
822 wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);827 wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);
828
829 /* Wa_14019877138 */
830 wa_mcr_masked_en(wal, XEHP_PSS_CHICKEN, FD_END_COLLECT);
823}831}
824 832
825static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,833static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,
@@ -908,7 +916,7 @@ __intel_engine_init_ctx_wa(struct intel_engine_cs *engine, · 82 unmodified lines
908 if (engine->class != RENDER_CLASS)916 if (engine->class != RENDER_CLASS)
909 goto done;917 goto done;
910 918
911 if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))919 if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))
912 xelpg_ctx_workarounds_init(engine, wal);920 xelpg_ctx_workarounds_init(engine, wal);
913 else if (IS_PONTEVECCHIO(i915))921 else if (IS_PONTEVECCHIO(i915))
914 ; /* noop; none at this time */922 ; /* noop; none at this time */
@@ -1643,7 +1651,7 @@ pvc_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) · 728 unmodified lines
1643static void1651static void
1644xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1652xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1645{1653{
1646 /* Wa_14018778641 / Wa_18018781329 */1654 /* Wa_14018575942 / Wa_18018781329 */
1647 wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);1655 wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
1648 1656
1649 /* Wa_22016670082 */1657 /* Wa_22016670082 */
@@ -1710,7 +1718,7 @@ xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal) · 60 unmodified lines
1710 */1718 */
1711static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)1719static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)
1712{1720{
1713 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {1721 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) {
1714 wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);1722 wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
1715 wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);1723 wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);
1716 }1724 }
@@ -1743,7 +1751,7 @@ gt_init_workarounds(struct intel_gt *gt, struct i915_wa_list *wal) · 26 unmodified lines
1743 return;1751 return;
1744 }1752 }
1745 1753
1746 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))1754 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))
1747 xelpg_gt_workarounds_init(gt, wal);1755 xelpg_gt_workarounds_init(gt, wal);
1748 else if (IS_PONTEVECCHIO(i915))1756 else if (IS_PONTEVECCHIO(i915))
1749 pvc_gt_workarounds_init(gt, wal);1757 pvc_gt_workarounds_init(gt, wal);
@@ -2216,7 +2224,7 @@ void intel_engine_init_whitelist(struct intel_engine_cs *engine) · 466 unmodified lines
2216 2224
2217 if (engine->gt->type == GT_MEDIA)2225 if (engine->gt->type == GT_MEDIA)
2218 ; /* none yet */2226 ; /* none yet */
2219 else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))2227 else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))
2220 xelpg_whitelist_build(engine);2228 xelpg_whitelist_build(engine);
2221 else if (IS_PONTEVECCHIO(i915))2229 else if (IS_PONTEVECCHIO(i915))
2222 pvc_whitelist_build(engine);2230 pvc_whitelist_build(engine);
@@ -2828,7 +2836,7 @@ add_render_compute_tuning_settings(struct intel_gt *gt, · 605 unmodified lines
2828{2836{
2829 struct drm_i915_private *i915 = gt->i915;2837 struct drm_i915_private *i915 = gt->i915;
2830 2838
2831 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))2839 if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915))
2832 wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);2840 wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);
2833 2841
2834 /*2842 /*
@@ -2881,7 +2889,8 @@ general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_li · 46 unmodified lines
2881 }2889 }
2882 2890
2883 if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||2891 if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
2884 IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))2892 IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER) ||
2893 IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74)))
2885 /* Wa_14017856879 */2894 /* Wa_14017856879 */
2886 wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);2895 wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);
2887 2896
drivers/gpu/drm/i915/gt/selftest_rc6.c+2−2
@@ -62,12 +62,12 @@ int live_rc6_manual(void *arg) · 61 unmodified lines
62 62
63 dt = ktime_get();63 dt = ktime_get();
64 rc0_power = librapl_energy_uJ();64 rc0_power = librapl_energy_uJ();
65 msleep(250);65 msleep(1000);
66 rc0_power = librapl_energy_uJ() - rc0_power;66 rc0_power = librapl_energy_uJ() - rc0_power;
67 dt = ktime_sub(ktime_get(), dt);67 dt = ktime_sub(ktime_get(), dt);
68 res[1] = rc6_residency(rc6);68 res[1] = rc6_residency(rc6);
69 if ((res[1] - res[0]) >> 10) {69 if ((res[1] - res[0]) >> 10) {
70 pr_err("RC6 residency increased by %lldus while disabled for 250ms!\n",70 pr_err("RC6 residency increased by %lldus while disabled for 1000ms!\n",
71 (res[1] - res[0]) >> 10);71 (res[1] - res[0]) >> 10);
72 err = -EINVAL;72 err = -EINVAL;
73 goto out_unlock;73 goto out_unlock;
drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c+13−8
@@ -377,8 +377,13 @@ static int guc_mmio_regset_init(struct temp_regset *regset, · 376 unmodified lines
377 CCS_MASK(engine->gt))377 CCS_MASK(engine->gt))
378 ret |= GUC_MMIO_REG_ADD(gt, regset, GEN12_RCU_MODE, true);378 ret |= GUC_MMIO_REG_ADD(gt, regset, GEN12_RCU_MODE, true);
379 379
380 /*
381 * some of the WA registers are MCR registers. As it is safe to
382 * use MCR form for non-MCR registers, for code simplicity, all
383 * WA registers are added with MCR form.
384 */
380 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)385 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
381 ret |= GUC_MMIO_REG_ADD(gt, regset, wa->reg, wa->masked_reg);386 ret |= GUC_MCR_REG_ADD(gt, regset, wa->mcr_reg, wa->masked_reg);
382 387
383 /* Be extra paranoid and include all whitelist registers. */388 /* Be extra paranoid and include all whitelist registers. */
384 for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++)389 for (i = 0; i < RING_MAX_NONPRIV_SLOTS; i++)
@@ -394,13 +399,13 @@ static int guc_mmio_regset_init(struct temp_regset *regset, · 9 unmodified lines
394 ret |= GUC_MMIO_REG_ADD(gt, regset, GEN9_LNCFCMOCS(i), false);399 ret |= GUC_MMIO_REG_ADD(gt, regset, GEN9_LNCFCMOCS(i), false);
395 400
396 if (GRAPHICS_VER(engine->i915) >= 12) {401 if (GRAPHICS_VER(engine->i915) >= 12) {
397 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL0, false);402 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL0)), false);
398 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL1, false);403 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL1)), false);
399 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL2, false);404 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL2)), false);
400 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL3, false);405 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL3)), false);
401 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL4, false);406 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL4)), false);
402 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL5, false);407 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL5)), false);
403 ret |= GUC_MMIO_REG_ADD(gt, regset, EU_PERF_CNTL6, false);408 ret |= GUC_MCR_REG_ADD(gt, regset, MCR_REG(i915_mmio_reg_offset(EU_PERF_CNTL6)), false);
404 }409 }
405 410
406 return ret ? -1 : 0;411 return ret ? -1 : 0;
drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c+5−5
@@ -184,7 +184,7 @@ static int guc_wait_ucode(struct intel_guc *guc) · 183 unmodified lines
184 * in the seconds range. However, there is a limit on how long an184 * in the seconds range. However, there is a limit on how long an
185 * individual wait_for() can wait. So wrap it in a loop.185 * individual wait_for() can wait. So wrap it in a loop.
186 */186 */
187 before_freq = intel_rps_read_actual_frequency(&uncore->gt->rps);187 before_freq = intel_rps_read_actual_frequency(&gt->rps);
188 before = ktime_get();188 before = ktime_get();
189 for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) {189 for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) {
190 ret = wait_for(guc_load_done(uncore, &status, &success), 1000);190 ret = wait_for(guc_load_done(uncore, &status, &success), 1000);
@@ -192,7 +192,7 @@ static int guc_wait_ucode(struct intel_guc *guc) · 1 unmodified line
192 break;192 break;
193 193
194 guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, status = 0x%08X [0x%02X/%02X]\n",194 guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, status = 0x%08X [0x%02X/%02X]\n",
195 count, intel_rps_read_actual_frequency(&uncore->gt->rps), status,195 count, intel_rps_read_actual_frequency(&gt->rps), status,
196 REG_FIELD_GET(GS_BOOTROM_MASK, status),196 REG_FIELD_GET(GS_BOOTROM_MASK, status),
197 REG_FIELD_GET(GS_UKERNEL_MASK, status));197 REG_FIELD_GET(GS_UKERNEL_MASK, status));
198 }198 }
@@ -204,7 +204,7 @@ static int guc_wait_ucode(struct intel_guc *guc) · 5 unmodified lines
204 u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);204 u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
205 205
206 guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = %dMHz, ret = %d\n",206 guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = %dMHz, ret = %d\n",
207 status, delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps), ret);207 status, delta_ms, intel_rps_read_actual_frequency(&gt->rps), ret);
208 guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",208 guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",
209 REG_FIELD_GET(GS_MIA_IN_RESET, status),209 REG_FIELD_GET(GS_MIA_IN_RESET, status),
210 bootrom, ukernel,210 bootrom, ukernel,
@@ -254,11 +254,11 @@ static int guc_wait_ucode(struct intel_guc *guc) · 43 unmodified lines
254 guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",254 guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",
255 delta_ms, status, count, ret);255 delta_ms, status, count, ret);
256 guc_warn(guc, "excessive init time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n",256 guc_warn(guc, "excessive init time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n",
257 intel_rps_read_actual_frequency(&uncore->gt->rps), before_freq,257 intel_rps_read_actual_frequency(&gt->rps), before_freq,
258 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));258 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));
259 } else {259 } else {
260 guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n",260 guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n",
261 delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps),261 delta_ms, intel_rps_read_actual_frequency(&gt->rps),
262 before_freq, status, count, ret);262 before_freq, status, count, ret);
263 }263 }
264 264
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c+120−6
@@ -236,6 +236,13 @@ set_context_destroyed(struct intel_context *ce) · 235 unmodified lines
236 ce->guc_state.sched_state |= SCHED_STATE_DESTROYED;236 ce->guc_state.sched_state |= SCHED_STATE_DESTROYED;
237}237}
238 238
239static inline void
240clr_context_destroyed(struct intel_context *ce)
241{
242 lockdep_assert_held(&ce->guc_state.lock);
243 ce->guc_state.sched_state &= ~SCHED_STATE_DESTROYED;
244}
245
239static inline bool context_pending_disable(struct intel_context *ce)246static inline bool context_pending_disable(struct intel_context *ce)
240{247{
241 return ce->guc_state.sched_state & SCHED_STATE_PENDING_DISABLE;248 return ce->guc_state.sched_state & SCHED_STATE_PENDING_DISABLE;
@@ -613,6 +620,8 @@ static int guc_submission_send_busy_loop(struct intel_guc *guc, · 371 unmodified lines
613 u32 g2h_len_dw,620 u32 g2h_len_dw,
614 bool loop)621 bool loop)
615{622{
623 int ret;
624
616 /*625 /*
617 * We always loop when a send requires a reply (i.e. g2h_len_dw > 0),626 * We always loop when a send requires a reply (i.e. g2h_len_dw > 0),
618 * so we don't handle the case where we don't get a reply because we627 * so we don't handle the case where we don't get a reply because we
@@ -623,7 +632,11 @@ static int guc_submission_send_busy_loop(struct intel_guc *guc, · 4 unmodified lines
623 if (g2h_len_dw)632 if (g2h_len_dw)
624 atomic_inc(&guc->outstanding_submission_g2h);633 atomic_inc(&guc->outstanding_submission_g2h);
625 634
626 return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);635 ret = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
636 if (ret)
637 atomic_dec(&guc->outstanding_submission_g2h);
638
639 return ret;
627}640}
628 641
629int intel_guc_wait_for_pending_msg(struct intel_guc *guc,642int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
@@ -1362,7 +1375,45 @@ static void guc_enable_busyness_worker(struct intel_guc *guc) · 732 unmodified lines
1362 1375
1363static void guc_cancel_busyness_worker(struct intel_guc *guc)1376static void guc_cancel_busyness_worker(struct intel_guc *guc)
1364{1377{
1365 cancel_delayed_work_sync(&guc->timestamp.work);1378 /*
1379 * There are many different call stacks that can get here. Some of them
1380 * hold the reset mutex. The busyness worker also attempts to acquire the
1381 * reset mutex. Synchronously flushing a worker thread requires acquiring
1382 * the worker mutex. Lockdep sees this as a conflict. It thinks that the
1383 * flush can deadlock because it holds the worker mutex while waiting for
1384 * the reset mutex, but another thread is holding the reset mutex and might
1385 * attempt to use other worker functions.
1386 *
1387 * In practice, this scenario does not exist because the busyness worker
1388 * does not block waiting for the reset mutex. It does a try-lock on it and
1389 * immediately exits if the lock is already held. Unfortunately, the mutex
1390 * in question (I915_RESET_BACKOFF) is an i915 implementation which has lockdep
1391 * annotation but not to the extent of explaining the 'might lock' is also a
1392 * 'does not need to lock'. So one option would be to add more complex lockdep
1393 * annotations to ignore the issue (if at all possible). A simpler option is to
1394 * just not flush synchronously when a rest in progress. Given that the worker
1395 * will just early exit and re-schedule itself anyway, there is no advantage
1396 * to running it immediately.
1397 *
1398 * If a reset is not in progress, then the synchronous flush may be required.
1399 * As noted many call stacks lead here, some during suspend and driver unload
1400 * which do require a synchronous flush to make sure the worker is stopped
1401 * before memory is freed.
1402 *
1403 * Trying to pass a 'need_sync' or 'in_reset' flag all the way down through
1404 * every possible call stack is unfeasible. It would be too intrusive to many
1405 * areas that really don't care about the GuC backend. However, there is the
1406 * 'reset_in_progress' flag available, so just use that.
1407 *
1408 * And note that in the case of a reset occurring during driver unload
1409 * (wedge_on_fini), skipping the cancel in _prepare (when the reset flag is set
1410 * is fine because there is another cancel in _finish (when the reset flag is
1411 * not).
1412 */
1413 if (guc_to_gt(guc)->uc.reset_in_progress)
1414 cancel_delayed_work(&guc->timestamp.work);
1415 else
1416 cancel_delayed_work_sync(&guc->timestamp.work);
1366}1417}
1367 1418
1368static void __reset_guc_busyness_stats(struct intel_guc *guc)1419static void __reset_guc_busyness_stats(struct intel_guc *guc)
@@ -1613,6 +1664,11 @@ static void guc_flush_submissions(struct intel_guc *guc) · 244 unmodified lines
1613 spin_unlock_irqrestore(&sched_engine->lock, flags);1664 spin_unlock_irqrestore(&sched_engine->lock, flags);
1614}1665}
1615 1666
1667void intel_guc_submission_flush_work(struct intel_guc *guc)
1668{
1669 flush_work(&guc->submission_state.destroyed_worker);
1670}
1671
1616static void guc_flush_destroyed_contexts(struct intel_guc *guc);1672static void guc_flush_destroyed_contexts(struct intel_guc *guc);
1617 1673
1618void intel_guc_submission_reset_prepare(struct intel_guc *guc)1674void intel_guc_submission_reset_prepare(struct intel_guc *guc)
@@ -1948,8 +2004,16 @@ void intel_guc_submission_cancel_requests(struct intel_guc *guc) · 329 unmodified lines
1948 2004
1949void intel_guc_submission_reset_finish(struct intel_guc *guc)2005void intel_guc_submission_reset_finish(struct intel_guc *guc)
1950{2006{
2007 /*
2008 * Ensure the busyness worker gets cancelled even on a fatal wedge.
2009 * Note that reset_prepare is not allowed to because it confuses lockdep.
2010 */
2011 if (guc_submission_initialized(guc))
2012 guc_cancel_busyness_worker(guc);
2013
1951 /* Reset called during driver load or during wedge? */2014 /* Reset called during driver load or during wedge? */
1952 if (unlikely(!guc_submission_initialized(guc) ||2015 if (unlikely(!guc_submission_initialized(guc) ||
2016 !intel_guc_is_fw_running(guc) ||
1953 intel_gt_is_wedged(guc_to_gt(guc)))) {2017 intel_gt_is_wedged(guc_to_gt(guc)))) {
1954 return;2018 return;
1955 }2019 }
@@ -3283,12 +3347,13 @@ static void guc_context_close(struct intel_context *ce) · 1327 unmodified lines
3283 spin_unlock_irqrestore(&ce->guc_state.lock, flags);3347 spin_unlock_irqrestore(&ce->guc_state.lock, flags);
3284}3348}
3285 3349
3286static inline void guc_lrc_desc_unpin(struct intel_context *ce)3350static inline int guc_lrc_desc_unpin(struct intel_context *ce)
3287{3351{
3288 struct intel_guc *guc = ce_to_guc(ce);3352 struct intel_guc *guc = ce_to_guc(ce);
3289 struct intel_gt *gt = guc_to_gt(guc);3353 struct intel_gt *gt = guc_to_gt(guc);
3290 unsigned long flags;3354 unsigned long flags;
3291 bool disabled;3355 bool disabled;
3356 int ret;
3292 3357
3293 GEM_BUG_ON(!intel_gt_pm_is_awake(gt));3358 GEM_BUG_ON(!intel_gt_pm_is_awake(gt));
3294 GEM_BUG_ON(!ctx_id_mapped(guc, ce->guc_id.id));3359 GEM_BUG_ON(!ctx_id_mapped(guc, ce->guc_id.id));
@@ -3299,18 +3364,41 @@ static inline void guc_lrc_desc_unpin(struct intel_context *ce) · 4 unmodified lines
3299 spin_lock_irqsave(&ce->guc_state.lock, flags);3364 spin_lock_irqsave(&ce->guc_state.lock, flags);
3300 disabled = submission_disabled(guc);3365 disabled = submission_disabled(guc);
3301 if (likely(!disabled)) {3366 if (likely(!disabled)) {
3367 /*
3368 * Take a gt-pm ref and change context state to be destroyed.
3369 * NOTE: a G2H IRQ that comes after will put this gt-pm ref back
3370 */
3302 __intel_gt_pm_get(gt);3371 __intel_gt_pm_get(gt);
3303 set_context_destroyed(ce);3372 set_context_destroyed(ce);
3304 clr_context_registered(ce);3373 clr_context_registered(ce);
3305 }3374 }
3306 spin_unlock_irqrestore(&ce->guc_state.lock, flags);3375 spin_unlock_irqrestore(&ce->guc_state.lock, flags);
3376
3307 if (unlikely(disabled)) {3377 if (unlikely(disabled)) {
3308 release_guc_id(guc, ce);3378 release_guc_id(guc, ce);
3309 __guc_context_destroy(ce);3379 __guc_context_destroy(ce);
3310 return;3380 return 0;
3311 }3381 }
3312 3382
3313 deregister_context(ce, ce->guc_id.id);3383 /*
3384 * GuC is active, lets destroy this context, but at this point we can still be racing
3385 * with suspend, so we undo everything if the H2G fails in deregister_context so
3386 * that GuC reset will find this context during clean up.
3387 */
3388 ret = deregister_context(ce, ce->guc_id.id);
3389 if (ret) {
3390 spin_lock(&ce->guc_state.lock);
3391 set_context_registered(ce);
3392 clr_context_destroyed(ce);
3393 spin_unlock(&ce->guc_state.lock);
3394 /*
3395 * As gt-pm is awake at function entry, intel_wakeref_put_async merely decrements
3396 * the wakeref immediately but per function spec usage call this after unlock.
3397 */
3398 intel_wakeref_put_async(&gt->wakeref);
3399 }
3400
3401 return ret;
3314}3402}
3315 3403
3316static void __guc_context_destroy(struct intel_context *ce)3404static void __guc_context_destroy(struct intel_context *ce)
@@ -3378,7 +3466,22 @@ static void deregister_destroyed_contexts(struct intel_guc *guc) · 61 unmodified lines
3378 if (!ce)3466 if (!ce)
3379 break;3467 break;
3380 3468
3381 guc_lrc_desc_unpin(ce);3469 if (guc_lrc_desc_unpin(ce)) {
3470 /*
3471 * This means GuC's CT link severed mid-way which could happen
3472 * in suspend-resume corner cases. In this case, put the
3473 * context back into the destroyed_contexts list which will
3474 * get picked up on the next context deregistration event or
3475 * purged in a GuC sanitization event (reset/unload/wedged/...).
3476 */
3477 spin_lock_irqsave(&guc->submission_state.lock, flags);
3478 list_add_tail(&ce->destroyed_link,
3479 &guc->submission_state.destroyed_contexts);
3480 spin_unlock_irqrestore(&guc->submission_state.lock, flags);
3481 /* Bail now since the list might never be emptied if h2gs fail */
3482 break;
3483 }
3484
3382 }3485 }
3383}3486}
3384 3487
@@ -3389,6 +3492,17 @@ static void destroyed_worker_func(struct work_struct *w) · 4 unmodified lines
3389 struct intel_gt *gt = guc_to_gt(guc);3492 struct intel_gt *gt = guc_to_gt(guc);
3390 intel_wakeref_t wakeref;3493 intel_wakeref_t wakeref;
3391 3494
3495 /*
3496 * In rare cases we can get here via async context-free fence-signals that
3497 * come very late in suspend flow or very early in resume flows. In these
3498 * cases, GuC won't be ready but just skipping it here is fine as these
3499 * pending-destroy-contexts get destroyed totally at GuC reset time at the
3500 * end of suspend.. OR.. this worker can be picked up later on the next
3501 * context destruction trigger after resume-completes
3502 */
3503 if (!intel_guc_is_ready(guc))
3504 return;
3505
3392 with_intel_gt_pm(gt, wakeref)3506 with_intel_gt_pm(gt, wakeref)
3393 deregister_destroyed_contexts(guc);3507 deregister_destroyed_contexts(guc);
3394}3508}
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h+2−0
@@ -38,6 +38,8 @@ int intel_guc_wait_for_pending_msg(struct intel_guc *guc, · 37 unmodified lines
38 bool interruptible,38 bool interruptible,
39 long timeout);39 long timeout);
40 40
41void intel_guc_submission_flush_work(struct intel_guc *guc);
42
41static inline bool intel_guc_submission_is_supported(struct intel_guc *guc)43static inline bool intel_guc_submission_is_supported(struct intel_guc *guc)
42{44{
43 return guc->submission_supported;45 return guc->submission_supported;
drivers/gpu/drm/i915/gt/uc/intel_huc.c+58−6
@@ -6,6 +6,7 @@ · 5 unmodified lines
6#include <linux/types.h>6#include <linux/types.h>
7 7
8#include "gt/intel_gt.h"8#include "gt/intel_gt.h"
9#include "gt/intel_rps.h"
9#include "intel_guc_reg.h"10#include "intel_guc_reg.h"
10#include "intel_huc.h"11#include "intel_huc.h"
11#include "intel_huc_print.h"12#include "intel_huc_print.h"
@@ -447,17 +448,68 @@ static const char *auth_mode_string(struct intel_huc *huc, · 435 unmodified lines
447 return partial ? "clear media" : "all workloads";448 return partial ? "clear media" : "all workloads";
448}449}
449 450
451/*
452 * Use a longer timeout for debug builds so that problems can be detected
453 * and analysed. But a shorter timeout for releases so that user's don't
454 * wait forever to find out there is a problem. Note that the only reason
455 * an end user should hit the timeout is in case of extreme thermal throttling.
456 * And a system that is that hot during boot is probably dead anyway!
457 */
458#if defined(CONFIG_DRM_I915_DEBUG_GEM)
459#define HUC_LOAD_RETRY_LIMIT 20
460#else
461#define HUC_LOAD_RETRY_LIMIT 3
462#endif
463
450int intel_huc_wait_for_auth_complete(struct intel_huc *huc,464int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
451 enum intel_huc_authentication_type type)465 enum intel_huc_authentication_type type)
452{466{
453 struct intel_gt *gt = huc_to_gt(huc);467 struct intel_gt *gt = huc_to_gt(huc);
454 int ret;468 struct intel_uncore *uncore = gt->uncore;
469 ktime_t before, after, delta;
470 int ret, count;
471 u64 delta_ms;
472 u32 before_freq;
455 473
456 ret = __intel_wait_for_register(gt->uncore,474 /*
457 huc->status[type].reg,475 * The KMD requests maximum frequency during driver load, however thermal
458 huc->status[type].mask,476 * throttling can force the frequency down to minimum (although the board
459 huc->status[type].value,477 * really should never get that hot in real life!). IFWI issues have been
460 2, 50, NULL);478 * seen to cause sporadic failures to grant the higher frequency. And at
479 * minimum frequency, the authentication time can be in the seconds range.
480 * Note that there is a limit on how long an individual wait_for() can wait.
481 * So wrap it in a loop.
482 */
483 before_freq = intel_rps_read_actual_frequency(&gt->rps);
484 before = ktime_get();
485 for (count = 0; count < HUC_LOAD_RETRY_LIMIT; count++) {
486 ret = __intel_wait_for_register(gt->uncore,
487 huc->status[type].reg,
488 huc->status[type].mask,
489 huc->status[type].value,
490 2, 1000, NULL);
491 if (!ret)
492 break;
493
494 huc_dbg(huc, "auth still in progress, count = %d, freq = %dMHz, status = 0x%08X\n",
495 count, intel_rps_read_actual_frequency(&gt->rps),
496 huc->status[type].reg.reg);
497 }
498 after = ktime_get();
499 delta = ktime_sub(after, before);
500 delta_ms = ktime_to_ms(delta);
501
502 if (delta_ms > 50) {
503 huc_warn(huc, "excessive auth time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",
504 delta_ms, huc->status[type].reg.reg, count, ret);
505 huc_warn(huc, "excessive auth time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n",
506 intel_rps_read_actual_frequency(&gt->rps), before_freq,
507 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));
508 } else {
509 huc_dbg(huc, "auth took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n",
510 delta_ms, intel_rps_read_actual_frequency(&gt->rps),
511 before_freq, huc->status[type].reg.reg, count, ret);
512 }
461 513
462 /* mark the load process as complete even if the wait failed */514 /* mark the load process as complete even if the wait failed */
463 delayed_huc_load_complete(huc);515 delayed_huc_load_complete(huc);
drivers/gpu/drm/i915/gt/uc/intel_uc.c+3−1
@@ -640,7 +640,7 @@ void intel_uc_reset_finish(struct intel_uc *uc) · 639 unmodified lines
640 uc->reset_in_progress = false;640 uc->reset_in_progress = false;
641 641
642 /* Firmware expected to be running when this function is called */642 /* Firmware expected to be running when this function is called */
643 if (intel_guc_is_fw_running(guc) && intel_uc_uses_guc_submission(uc))643 if (intel_uc_uses_guc_submission(uc))
644 intel_guc_submission_reset_finish(guc);644 intel_guc_submission_reset_finish(guc);
645}645}
646 646
@@ -690,6 +690,8 @@ void intel_uc_suspend(struct intel_uc *uc) · 43 unmodified lines
690 return;690 return;
691 }691 }
692 692
693 intel_guc_submission_flush_work(guc);
694
693 with_intel_runtime_pm(&uc_to_gt(uc)->i915->runtime_pm, wakeref) {695 with_intel_runtime_pm(&uc_to_gt(uc)->i915->runtime_pm, wakeref) {
694 err = intel_guc_suspend(guc);696 err = intel_guc_suspend(guc);
695 if (err)697 if (err)
drivers/gpu/drm/i915/i915_debugfs.c+1−1
@@ -147,7 +147,7 @@ static const char *i915_cache_level_str(struct drm_i915_gem_object *obj) · 146 unmodified lines
147{147{
148 struct drm_i915_private *i915 = obj_to_i915(obj);148 struct drm_i915_private *i915 = obj_to_i915(obj);
149 149
150 if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 71))) {150 if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 74))) {
151 switch (obj->pat_index) {151 switch (obj->pat_index) {
152 case 0: return " WB";152 case 0: return " WB";
153 case 1: return " WT";153 case 1: return " WT";
drivers/gpu/drm/i915/i915_drv.h+0−8
@@ -165,14 +165,6 @@ struct i915_gem_mm { · 164 unmodified lines
165 struct notifier_block vmap_notifier;165 struct notifier_block vmap_notifier;
166 struct shrinker *shrinker;166 struct shrinker *shrinker;
167 167
168#ifdef CONFIG_MMU_NOTIFIER
169 /**
170 * notifier_lock for mmu notifiers, memory may not be allocated
171 * while holding this lock.
172 */
173 rwlock_t notifier_lock;
174#endif
175
176 /* shrinker accounting, also useful for userland debugging */168 /* shrinker accounting, also useful for userland debugging */
177 u64 shrink_memory;169 u64 shrink_memory;
178 u32 shrink_count;170 u32 shrink_count;
drivers/gpu/drm/i915/i915_gem.c+0−5
@@ -48,7 +48,6 @@ · 47 unmodified lines
48#include "gem/i915_gem_object_frontbuffer.h"48#include "gem/i915_gem_object_frontbuffer.h"
49#include "gem/i915_gem_pm.h"49#include "gem/i915_gem_pm.h"
50#include "gem/i915_gem_region.h"50#include "gem/i915_gem_region.h"
51#include "gem/i915_gem_userptr.h"
52#include "gt/intel_engine_user.h"51#include "gt/intel_engine_user.h"
53#include "gt/intel_gt.h"52#include "gt/intel_gt.h"
54#include "gt/intel_gt_pm.h"53#include "gt/intel_gt_pm.h"
@@ -1165,10 +1164,6 @@ int i915_gem_init(struct drm_i915_private *dev_priv) · 1110 unmodified lines
1165 if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))1164 if (intel_vgpu_active(dev_priv) && !intel_vgpu_has_huge_gtt(dev_priv))
1166 RUNTIME_INFO(dev_priv)->page_sizes = I915_GTT_PAGE_SIZE_4K;1165 RUNTIME_INFO(dev_priv)->page_sizes = I915_GTT_PAGE_SIZE_4K;
1167 1166
1168 ret = i915_gem_init_userptr(dev_priv);
1169 if (ret)
1170 return ret;
1171
1172 for_each_gt(gt, dev_priv, i) {1167 for_each_gt(gt, dev_priv, i) {
1173 intel_uc_fetch_firmwares(&gt->uc);1168 intel_uc_fetch_firmwares(&gt->uc);
1174 intel_wopcm_init(&gt->wopcm);1169 intel_wopcm_init(&gt->wopcm);
drivers/gpu/drm/i915/i915_perf.c+1−1
@@ -3225,7 +3225,7 @@ u32 i915_perf_oa_timestamp_frequency(struct drm_i915_private *i915) · 3224 unmodified lines
3225 struct intel_gt *gt = to_gt(i915);3225 struct intel_gt *gt = to_gt(i915);
3226 3226
3227 /* Wa_18013179988 */3227 /* Wa_18013179988 */
3228 if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {3228 if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) {
3229 intel_wakeref_t wakeref;3229 intel_wakeref_t wakeref;
3230 u32 reg, shift;3230 u32 reg, shift;
3231 3231
drivers/gpu/drm/i915/i915_query.c+33−0
@@ -551,6 +551,38 @@ static int query_hwconfig_blob(struct drm_i915_private *i915, · 550 unmodified lines
551 return hwconfig->size;551 return hwconfig->size;
552}552}
553 553
554static int
555query_guc_submission_version(struct drm_i915_private *i915,
556 struct drm_i915_query_item *query)
557{
558 struct drm_i915_query_guc_submission_version __user *query_ptr =
559 u64_to_user_ptr(query->data_ptr);
560 struct drm_i915_query_guc_submission_version ver;
561 struct intel_guc *guc = &to_gt(i915)->uc.guc;
562 const size_t size = sizeof(ver);
563 int ret;
564
565 if (!intel_uc_uses_guc_submission(&to_gt(i915)->uc))
566 return -ENODEV;
567
568 ret = copy_query_item(&ver, size, size, query);
569 if (ret != 0)
570 return ret;
571
572 if (ver.branch || ver.major || ver.minor || ver.patch)
573 return -EINVAL;
574
575 ver.branch = 0;
576 ver.major = guc->submission_version.major;
577 ver.minor = guc->submission_version.minor;
578 ver.patch = guc->submission_version.patch;
579
580 if (copy_to_user(query_ptr, &ver, size))
581 return -EFAULT;
582
583 return 0;
584}
585
554static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,586static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
555 struct drm_i915_query_item *query_item) = {587 struct drm_i915_query_item *query_item) = {
556 query_topology_info,588 query_topology_info,
@@ -559,6 +591,7 @@ static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv, · 2 unmodified lines
559 query_memregion_info,591 query_memregion_info,
560 query_hwconfig_blob,592 query_hwconfig_blob,
561 query_geometry_subslices,593 query_geometry_subslices,
594 query_guc_submission_version,
562};595};
563 596
564int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)597int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
drivers/gpu/drm/i915/i915_syncmap.c+8−11
@@ -75,13 +75,10 @@ struct i915_syncmap { · 74 unmodified lines
75 unsigned int height;75 unsigned int height;
76 unsigned int bitmap;76 unsigned int bitmap;
77 struct i915_syncmap *parent;77 struct i915_syncmap *parent;
78 /*78 union {
79 * Following this header is an array of either seqno or child pointers:79 DECLARE_FLEX_ARRAY(u32, seqno);
80 * union {80 DECLARE_FLEX_ARRAY(struct i915_syncmap *, child);
81 * u32 seqno[KSYNCMAP];81 };
82 * struct i915_syncmap *child[KSYNCMAP];
83 * };
84 */
85};82};
86 83
87/**84/**
@@ -99,13 +96,13 @@ void i915_syncmap_init(struct i915_syncmap **root) · 11 unmodified lines
99static inline u32 *__sync_seqno(struct i915_syncmap *p)96static inline u32 *__sync_seqno(struct i915_syncmap *p)
100{97{
101 GEM_BUG_ON(p->height);98 GEM_BUG_ON(p->height);
102 return (u32 *)(p + 1);99 return p->seqno;
103}100}
104 101
105static inline struct i915_syncmap **__sync_child(struct i915_syncmap *p)102static inline struct i915_syncmap **__sync_child(struct i915_syncmap *p)
106{103{
107 GEM_BUG_ON(!p->height);104 GEM_BUG_ON(!p->height);
108 return (struct i915_syncmap **)(p + 1);105 return p->child;
109}106}
110 107
111static inline unsigned int108static inline unsigned int
@@ -200,7 +197,7 @@ __sync_alloc_leaf(struct i915_syncmap *parent, u64 id) · 88 unmodified lines
200{197{
201 struct i915_syncmap *p;198 struct i915_syncmap *p;
202 199
203 p = kmalloc(sizeof(*p) + KSYNCMAP * sizeof(u32), GFP_KERNEL);200 p = kmalloc(struct_size(p, seqno, KSYNCMAP), GFP_KERNEL);
204 if (unlikely(!p))201 if (unlikely(!p))
205 return NULL;202 return NULL;
206 203
@@ -282,7 +279,7 @@ static noinline int __sync_set(struct i915_syncmap **root, u64 id, u32 seqno) · 75 unmodified lines
282 unsigned int above;279 unsigned int above;
283 280
284 /* Insert a join above the current layer */281 /* Insert a join above the current layer */
285 next = kzalloc(sizeof(*next) + KSYNCMAP * sizeof(next),282 next = kzalloc(struct_size(next, child, KSYNCMAP),
286 GFP_KERNEL);283 GFP_KERNEL);
287 if (unlikely(!next))284 if (unlikely(!next))
288 return -ENOMEM;285 return -ENOMEM;
drivers/gpu/drm/i915/intel_uncore.c+4−1
@@ -1800,7 +1800,10 @@ static const struct intel_forcewake_range __mtl_fw_ranges[] = { · 1799 unmodified lines
1800 GEN_FW_RANGE(0x24000, 0x2ffff, 0), /*1800 GEN_FW_RANGE(0x24000, 0x2ffff, 0), /*
1801 0x24000 - 0x2407f: always on1801 0x24000 - 0x2407f: always on
1802 0x24080 - 0x2ffff: reserved */1802 0x24080 - 0x2ffff: reserved */
1803 GEN_FW_RANGE(0x30000, 0x3ffff, FORCEWAKE_GT)1803 GEN_FW_RANGE(0x30000, 0x3ffff, FORCEWAKE_GT),
1804 GEN_FW_RANGE(0x40000, 0x1901ef, 0),
1805 GEN_FW_RANGE(0x1901f0, 0x1901f3, FORCEWAKE_GT)
1806 /* FIXME: WA to wake GT while triggering H2G */
1804};1807};
1805 1808
1806/*1809/*
include/uapi/drm/i915_drm.h+12−0
@@ -3013,6 +3013,7 @@ struct drm_i915_query_item { · 3012 unmodified lines
3013 * - %DRM_I915_QUERY_MEMORY_REGIONS (see struct drm_i915_query_memory_regions)3013 * - %DRM_I915_QUERY_MEMORY_REGIONS (see struct drm_i915_query_memory_regions)
3014 * - %DRM_I915_QUERY_HWCONFIG_BLOB (see `GuC HWCONFIG blob uAPI`)3014 * - %DRM_I915_QUERY_HWCONFIG_BLOB (see `GuC HWCONFIG blob uAPI`)
3015 * - %DRM_I915_QUERY_GEOMETRY_SUBSLICES (see struct drm_i915_query_topology_info)3015 * - %DRM_I915_QUERY_GEOMETRY_SUBSLICES (see struct drm_i915_query_topology_info)
3016 * - %DRM_I915_QUERY_GUC_SUBMISSION_VERSION (see struct drm_i915_query_guc_submission_version)
3016 */3017 */
3017 __u64 query_id;3018 __u64 query_id;
3018#define DRM_I915_QUERY_TOPOLOGY_INFO 13019#define DRM_I915_QUERY_TOPOLOGY_INFO 1
@@ -3021,6 +3022,7 @@ struct drm_i915_query_item { · 2 unmodified lines
3021#define DRM_I915_QUERY_MEMORY_REGIONS 43022#define DRM_I915_QUERY_MEMORY_REGIONS 4
3022#define DRM_I915_QUERY_HWCONFIG_BLOB 53023#define DRM_I915_QUERY_HWCONFIG_BLOB 5
3023#define DRM_I915_QUERY_GEOMETRY_SUBSLICES 63024#define DRM_I915_QUERY_GEOMETRY_SUBSLICES 6
3025#define DRM_I915_QUERY_GUC_SUBMISSION_VERSION 7
3024/* Must be kept compact -- no holes and well documented */3026/* Must be kept compact -- no holes and well documented */
3025 3027
3026 /**3028 /**
@@ -3566,6 +3568,16 @@ struct drm_i915_query_memory_regions { · 539 unmodified lines
3566 struct drm_i915_memory_region_info regions[];3568 struct drm_i915_memory_region_info regions[];
3567};3569};
3568 3570
3571/**
3572 * struct drm_i915_query_guc_submission_version - query GuC submission interface version
3573 */
3574struct drm_i915_query_guc_submission_version {
3575 __u32 branch;
3576 __u32 major;
3577 __u32 minor;
3578 __u32 patch;
3579};
3580
3569/**3581/**
3570 * DOC: GuC HWCONFIG blob uAPI3582 * DOC: GuC HWCONFIG blob uAPI
3571 *3583 *