162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright © 2019 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "gt/intel_engine_pm.h" 762306a36Sopenharmony_ci#include "gt/intel_gpu_commands.h" 862306a36Sopenharmony_ci#include "i915_selftest.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include "gem/selftests/igt_gem_utils.h" 1162306a36Sopenharmony_ci#include "gem/selftests/mock_context.h" 1262306a36Sopenharmony_ci#include "selftests/igt_reset.h" 1362306a36Sopenharmony_ci#include "selftests/igt_spinner.h" 1462306a36Sopenharmony_ci#include "selftests/intel_scheduler_helpers.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistruct live_mocs { 1762306a36Sopenharmony_ci struct drm_i915_mocs_table table; 1862306a36Sopenharmony_ci struct drm_i915_mocs_table *mocs; 1962306a36Sopenharmony_ci struct drm_i915_mocs_table *l3cc; 2062306a36Sopenharmony_ci struct i915_vma *scratch; 2162306a36Sopenharmony_ci void *vaddr; 2262306a36Sopenharmony_ci}; 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic struct intel_context *mocs_context_create(struct intel_engine_cs *engine) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci struct intel_context *ce; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci ce = intel_context_create(engine); 2962306a36Sopenharmony_ci if (IS_ERR(ce)) 3062306a36Sopenharmony_ci return ce; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci /* We build large requests to read the registers from the ring */ 3362306a36Sopenharmony_ci ce->ring_size = SZ_16K; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci return ce; 3662306a36Sopenharmony_ci} 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cistatic int request_add_sync(struct i915_request *rq, int err) 3962306a36Sopenharmony_ci{ 4062306a36Sopenharmony_ci i915_request_get(rq); 4162306a36Sopenharmony_ci i915_request_add(rq); 4262306a36Sopenharmony_ci if (i915_request_wait(rq, 0, HZ / 5) < 0) 4362306a36Sopenharmony_ci err = -ETIME; 4462306a36Sopenharmony_ci i915_request_put(rq); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci return err; 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic int request_add_spin(struct i915_request *rq, struct igt_spinner *spin) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci int err = 0; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci i915_request_get(rq); 5462306a36Sopenharmony_ci i915_request_add(rq); 5562306a36Sopenharmony_ci if (spin && !igt_wait_for_spinner(spin, rq)) 5662306a36Sopenharmony_ci err = -ETIME; 5762306a36Sopenharmony_ci i915_request_put(rq); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci return err; 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistatic int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci unsigned int flags; 6562306a36Sopenharmony_ci int err; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci memset(arg, 0, sizeof(*arg)); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci flags = get_mocs_settings(gt->i915, &arg->table); 7062306a36Sopenharmony_ci if (!flags) 7162306a36Sopenharmony_ci return -EINVAL; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci if (flags & HAS_RENDER_L3CC) 7462306a36Sopenharmony_ci arg->l3cc = &arg->table; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci if (flags & (HAS_GLOBAL_MOCS | HAS_ENGINE_MOCS)) 7762306a36Sopenharmony_ci arg->mocs = &arg->table; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci arg->scratch = 8062306a36Sopenharmony_ci __vm_create_scratch_for_read_pinned(>->ggtt->vm, PAGE_SIZE); 8162306a36Sopenharmony_ci if (IS_ERR(arg->scratch)) 8262306a36Sopenharmony_ci return PTR_ERR(arg->scratch); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci arg->vaddr = i915_gem_object_pin_map_unlocked(arg->scratch->obj, I915_MAP_WB); 8562306a36Sopenharmony_ci if (IS_ERR(arg->vaddr)) { 8662306a36Sopenharmony_ci err = PTR_ERR(arg->vaddr); 8762306a36Sopenharmony_ci goto err_scratch; 8862306a36Sopenharmony_ci } 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci return 0; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cierr_scratch: 9362306a36Sopenharmony_ci i915_vma_unpin_and_release(&arg->scratch, 0); 9462306a36Sopenharmony_ci return err; 9562306a36Sopenharmony_ci} 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_cistatic void live_mocs_fini(struct live_mocs *arg) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci i915_vma_unpin_and_release(&arg->scratch, I915_VMA_RELEASE_MAP); 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic int read_regs(struct i915_request *rq, 10362306a36Sopenharmony_ci u32 addr, unsigned int count, 10462306a36Sopenharmony_ci u32 *offset) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci unsigned int i; 10762306a36Sopenharmony_ci u32 *cs; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci GEM_BUG_ON(!IS_ALIGNED(*offset, sizeof(u32))); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci cs = intel_ring_begin(rq, 4 * count); 11262306a36Sopenharmony_ci if (IS_ERR(cs)) 11362306a36Sopenharmony_ci return PTR_ERR(cs); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci for (i = 0; i < count; i++) { 11662306a36Sopenharmony_ci *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT; 11762306a36Sopenharmony_ci *cs++ = addr; 11862306a36Sopenharmony_ci *cs++ = *offset; 11962306a36Sopenharmony_ci *cs++ = 0; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci addr += sizeof(u32); 12262306a36Sopenharmony_ci *offset += sizeof(u32); 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci intel_ring_advance(rq, cs); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci return 0; 12862306a36Sopenharmony_ci} 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistatic int read_mocs_table(struct i915_request *rq, 13162306a36Sopenharmony_ci const struct drm_i915_mocs_table *table, 13262306a36Sopenharmony_ci u32 *offset) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci struct intel_gt *gt = rq->engine->gt; 13562306a36Sopenharmony_ci u32 addr; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if (!table) 13862306a36Sopenharmony_ci return 0; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (HAS_GLOBAL_MOCS_REGISTERS(rq->i915)) 14162306a36Sopenharmony_ci addr = global_mocs_offset() + gt->uncore->gsi_offset; 14262306a36Sopenharmony_ci else 14362306a36Sopenharmony_ci addr = mocs_offset(rq->engine); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci return read_regs(rq, addr, table->n_entries, offset); 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic int read_l3cc_table(struct i915_request *rq, 14962306a36Sopenharmony_ci const struct drm_i915_mocs_table *table, 15062306a36Sopenharmony_ci u32 *offset) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci u32 addr = i915_mmio_reg_offset(GEN9_LNCFCMOCS(0)); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci if (!table) 15562306a36Sopenharmony_ci return 0; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci return read_regs(rq, addr, (table->n_entries + 1) / 2, offset); 15862306a36Sopenharmony_ci} 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic int check_mocs_table(struct intel_engine_cs *engine, 16162306a36Sopenharmony_ci const struct drm_i915_mocs_table *table, 16262306a36Sopenharmony_ci u32 **vaddr) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci unsigned int i; 16562306a36Sopenharmony_ci u32 expect; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci if (!table) 16862306a36Sopenharmony_ci return 0; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci for_each_mocs(expect, table, i) { 17162306a36Sopenharmony_ci if (**vaddr != expect) { 17262306a36Sopenharmony_ci pr_err("%s: Invalid MOCS[%d] entry, found %08x, expected %08x\n", 17362306a36Sopenharmony_ci engine->name, i, **vaddr, expect); 17462306a36Sopenharmony_ci return -EINVAL; 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci ++*vaddr; 17762306a36Sopenharmony_ci } 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci return 0; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic bool mcr_range(struct drm_i915_private *i915, u32 offset) 18362306a36Sopenharmony_ci{ 18462306a36Sopenharmony_ci /* 18562306a36Sopenharmony_ci * Registers in this range are affected by the MCR selector 18662306a36Sopenharmony_ci * which only controls CPU initiated MMIO. Routing does not 18762306a36Sopenharmony_ci * work for CS access so we cannot verify them on this path. 18862306a36Sopenharmony_ci */ 18962306a36Sopenharmony_ci return GRAPHICS_VER(i915) >= 8 && offset >= 0xb000 && offset <= 0xb4ff; 19062306a36Sopenharmony_ci} 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_cistatic int check_l3cc_table(struct intel_engine_cs *engine, 19362306a36Sopenharmony_ci const struct drm_i915_mocs_table *table, 19462306a36Sopenharmony_ci u32 **vaddr) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci /* Can we read the MCR range 0xb00 directly? See intel_workarounds! */ 19762306a36Sopenharmony_ci u32 reg = i915_mmio_reg_offset(GEN9_LNCFCMOCS(0)); 19862306a36Sopenharmony_ci unsigned int i; 19962306a36Sopenharmony_ci u32 expect; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (!table) 20262306a36Sopenharmony_ci return 0; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci for_each_l3cc(expect, table, i) { 20562306a36Sopenharmony_ci if (!mcr_range(engine->i915, reg) && **vaddr != expect) { 20662306a36Sopenharmony_ci pr_err("%s: Invalid L3CC[%d] entry, found %08x, expected %08x\n", 20762306a36Sopenharmony_ci engine->name, i, **vaddr, expect); 20862306a36Sopenharmony_ci return -EINVAL; 20962306a36Sopenharmony_ci } 21062306a36Sopenharmony_ci ++*vaddr; 21162306a36Sopenharmony_ci reg += 4; 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci return 0; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic int check_mocs_engine(struct live_mocs *arg, 21862306a36Sopenharmony_ci struct intel_context *ce) 21962306a36Sopenharmony_ci{ 22062306a36Sopenharmony_ci struct i915_vma *vma = arg->scratch; 22162306a36Sopenharmony_ci struct i915_request *rq; 22262306a36Sopenharmony_ci u32 offset; 22362306a36Sopenharmony_ci u32 *vaddr; 22462306a36Sopenharmony_ci int err; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci memset32(arg->vaddr, STACK_MAGIC, PAGE_SIZE / sizeof(u32)); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci rq = intel_context_create_request(ce); 22962306a36Sopenharmony_ci if (IS_ERR(rq)) 23062306a36Sopenharmony_ci return PTR_ERR(rq); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci err = igt_vma_move_to_active_unlocked(vma, rq, EXEC_OBJECT_WRITE); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci /* Read the mocs tables back using SRM */ 23562306a36Sopenharmony_ci offset = i915_ggtt_offset(vma); 23662306a36Sopenharmony_ci if (!err) 23762306a36Sopenharmony_ci err = read_mocs_table(rq, arg->mocs, &offset); 23862306a36Sopenharmony_ci if (!err && ce->engine->class == RENDER_CLASS) 23962306a36Sopenharmony_ci err = read_l3cc_table(rq, arg->l3cc, &offset); 24062306a36Sopenharmony_ci offset -= i915_ggtt_offset(vma); 24162306a36Sopenharmony_ci GEM_BUG_ON(offset > PAGE_SIZE); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci err = request_add_sync(rq, err); 24462306a36Sopenharmony_ci if (err) 24562306a36Sopenharmony_ci return err; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci /* Compare the results against the expected tables */ 24862306a36Sopenharmony_ci vaddr = arg->vaddr; 24962306a36Sopenharmony_ci if (!err) 25062306a36Sopenharmony_ci err = check_mocs_table(ce->engine, arg->mocs, &vaddr); 25162306a36Sopenharmony_ci if (!err && ce->engine->class == RENDER_CLASS) 25262306a36Sopenharmony_ci err = check_l3cc_table(ce->engine, arg->l3cc, &vaddr); 25362306a36Sopenharmony_ci if (err) 25462306a36Sopenharmony_ci return err; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci GEM_BUG_ON(arg->vaddr + offset != vaddr); 25762306a36Sopenharmony_ci return 0; 25862306a36Sopenharmony_ci} 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_cistatic int live_mocs_kernel(void *arg) 26162306a36Sopenharmony_ci{ 26262306a36Sopenharmony_ci struct intel_gt *gt = arg; 26362306a36Sopenharmony_ci struct intel_engine_cs *engine; 26462306a36Sopenharmony_ci enum intel_engine_id id; 26562306a36Sopenharmony_ci struct live_mocs mocs; 26662306a36Sopenharmony_ci int err; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* Basic check the system is configured with the expected mocs table */ 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci err = live_mocs_init(&mocs, gt); 27162306a36Sopenharmony_ci if (err) 27262306a36Sopenharmony_ci return err; 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 27562306a36Sopenharmony_ci intel_engine_pm_get(engine); 27662306a36Sopenharmony_ci err = check_mocs_engine(&mocs, engine->kernel_context); 27762306a36Sopenharmony_ci intel_engine_pm_put(engine); 27862306a36Sopenharmony_ci if (err) 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci live_mocs_fini(&mocs); 28362306a36Sopenharmony_ci return err; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic int live_mocs_clean(void *arg) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci struct intel_gt *gt = arg; 28962306a36Sopenharmony_ci struct intel_engine_cs *engine; 29062306a36Sopenharmony_ci enum intel_engine_id id; 29162306a36Sopenharmony_ci struct live_mocs mocs; 29262306a36Sopenharmony_ci int err; 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* Every new context should see the same mocs table */ 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci err = live_mocs_init(&mocs, gt); 29762306a36Sopenharmony_ci if (err) 29862306a36Sopenharmony_ci return err; 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 30162306a36Sopenharmony_ci struct intel_context *ce; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci ce = mocs_context_create(engine); 30462306a36Sopenharmony_ci if (IS_ERR(ce)) { 30562306a36Sopenharmony_ci err = PTR_ERR(ce); 30662306a36Sopenharmony_ci break; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci err = check_mocs_engine(&mocs, ce); 31062306a36Sopenharmony_ci intel_context_put(ce); 31162306a36Sopenharmony_ci if (err) 31262306a36Sopenharmony_ci break; 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci live_mocs_fini(&mocs); 31662306a36Sopenharmony_ci return err; 31762306a36Sopenharmony_ci} 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistatic int active_engine_reset(struct intel_context *ce, 32062306a36Sopenharmony_ci const char *reason, 32162306a36Sopenharmony_ci bool using_guc) 32262306a36Sopenharmony_ci{ 32362306a36Sopenharmony_ci struct igt_spinner spin; 32462306a36Sopenharmony_ci struct i915_request *rq; 32562306a36Sopenharmony_ci int err; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci err = igt_spinner_init(&spin, ce->engine->gt); 32862306a36Sopenharmony_ci if (err) 32962306a36Sopenharmony_ci return err; 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci rq = igt_spinner_create_request(&spin, ce, MI_NOOP); 33262306a36Sopenharmony_ci if (IS_ERR(rq)) { 33362306a36Sopenharmony_ci igt_spinner_fini(&spin); 33462306a36Sopenharmony_ci return PTR_ERR(rq); 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci err = request_add_spin(rq, &spin); 33862306a36Sopenharmony_ci if (err == 0 && !using_guc) 33962306a36Sopenharmony_ci err = intel_engine_reset(ce->engine, reason); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci /* Ensure the reset happens and kills the engine */ 34262306a36Sopenharmony_ci if (err == 0) 34362306a36Sopenharmony_ci err = intel_selftest_wait_for_rq(rq); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci igt_spinner_end(&spin); 34662306a36Sopenharmony_ci igt_spinner_fini(&spin); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci return err; 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_cistatic int __live_mocs_reset(struct live_mocs *mocs, 35262306a36Sopenharmony_ci struct intel_context *ce, bool using_guc) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci struct intel_gt *gt = ce->engine->gt; 35562306a36Sopenharmony_ci int err; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci if (intel_has_reset_engine(gt)) { 35862306a36Sopenharmony_ci if (!using_guc) { 35962306a36Sopenharmony_ci err = intel_engine_reset(ce->engine, "mocs"); 36062306a36Sopenharmony_ci if (err) 36162306a36Sopenharmony_ci return err; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci err = check_mocs_engine(mocs, ce); 36462306a36Sopenharmony_ci if (err) 36562306a36Sopenharmony_ci return err; 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci err = active_engine_reset(ce, "mocs", using_guc); 36962306a36Sopenharmony_ci if (err) 37062306a36Sopenharmony_ci return err; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci err = check_mocs_engine(mocs, ce); 37362306a36Sopenharmony_ci if (err) 37462306a36Sopenharmony_ci return err; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci if (intel_has_gpu_reset(gt)) { 37862306a36Sopenharmony_ci intel_gt_reset(gt, ce->engine->mask, "mocs"); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci err = check_mocs_engine(mocs, ce); 38162306a36Sopenharmony_ci if (err) 38262306a36Sopenharmony_ci return err; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci return 0; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistatic int live_mocs_reset(void *arg) 38962306a36Sopenharmony_ci{ 39062306a36Sopenharmony_ci struct intel_gt *gt = arg; 39162306a36Sopenharmony_ci struct intel_engine_cs *engine; 39262306a36Sopenharmony_ci enum intel_engine_id id; 39362306a36Sopenharmony_ci struct live_mocs mocs; 39462306a36Sopenharmony_ci int err = 0; 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* Check the mocs setup is retained over per-engine and global resets */ 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci err = live_mocs_init(&mocs, gt); 39962306a36Sopenharmony_ci if (err) 40062306a36Sopenharmony_ci return err; 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci igt_global_reset_lock(gt); 40362306a36Sopenharmony_ci for_each_engine(engine, gt, id) { 40462306a36Sopenharmony_ci bool using_guc = intel_engine_uses_guc(engine); 40562306a36Sopenharmony_ci struct intel_selftest_saved_policy saved; 40662306a36Sopenharmony_ci struct intel_context *ce; 40762306a36Sopenharmony_ci int err2; 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci err = intel_selftest_modify_policy(engine, &saved, 41062306a36Sopenharmony_ci SELFTEST_SCHEDULER_MODIFY_FAST_RESET); 41162306a36Sopenharmony_ci if (err) 41262306a36Sopenharmony_ci break; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci ce = mocs_context_create(engine); 41562306a36Sopenharmony_ci if (IS_ERR(ce)) { 41662306a36Sopenharmony_ci err = PTR_ERR(ce); 41762306a36Sopenharmony_ci goto restore; 41862306a36Sopenharmony_ci } 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci intel_engine_pm_get(engine); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci err = __live_mocs_reset(&mocs, ce, using_guc); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci intel_engine_pm_put(engine); 42562306a36Sopenharmony_ci intel_context_put(ce); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_cirestore: 42862306a36Sopenharmony_ci err2 = intel_selftest_restore_policy(engine, &saved); 42962306a36Sopenharmony_ci if (err == 0) 43062306a36Sopenharmony_ci err = err2; 43162306a36Sopenharmony_ci if (err) 43262306a36Sopenharmony_ci break; 43362306a36Sopenharmony_ci } 43462306a36Sopenharmony_ci igt_global_reset_unlock(gt); 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci live_mocs_fini(&mocs); 43762306a36Sopenharmony_ci return err; 43862306a36Sopenharmony_ci} 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ciint intel_mocs_live_selftests(struct drm_i915_private *i915) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci static const struct i915_subtest tests[] = { 44362306a36Sopenharmony_ci SUBTEST(live_mocs_kernel), 44462306a36Sopenharmony_ci SUBTEST(live_mocs_clean), 44562306a36Sopenharmony_ci SUBTEST(live_mocs_reset), 44662306a36Sopenharmony_ci }; 44762306a36Sopenharmony_ci struct drm_i915_mocs_table table; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci if (!get_mocs_settings(i915, &table)) 45062306a36Sopenharmony_ci return 0; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci return intel_gt_live_subtests(tests, to_gt(i915)); 45362306a36Sopenharmony_ci} 454