18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * SPDX-License-Identifier: MIT 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright © 2019 Intel Corporation 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include "gt/intel_engine_pm.h" 88c2ecf20Sopenharmony_ci#include "i915_selftest.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "gem/selftests/mock_context.h" 118c2ecf20Sopenharmony_ci#include "selftests/igt_reset.h" 128c2ecf20Sopenharmony_ci#include "selftests/igt_spinner.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistruct live_mocs { 158c2ecf20Sopenharmony_ci struct drm_i915_mocs_table mocs; 168c2ecf20Sopenharmony_ci struct drm_i915_mocs_table l3cc; 178c2ecf20Sopenharmony_ci struct i915_vma *scratch; 188c2ecf20Sopenharmony_ci void *vaddr; 198c2ecf20Sopenharmony_ci}; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cistatic struct intel_context *mocs_context_create(struct intel_engine_cs *engine) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci struct intel_context *ce; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci ce = intel_context_create(engine); 268c2ecf20Sopenharmony_ci if (IS_ERR(ce)) 278c2ecf20Sopenharmony_ci return ce; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci /* We build large requests to read the registers from the ring */ 308c2ecf20Sopenharmony_ci ce->ring = __intel_context_ring_size(SZ_16K); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci return ce; 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic int request_add_sync(struct i915_request *rq, int err) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci i915_request_get(rq); 388c2ecf20Sopenharmony_ci i915_request_add(rq); 398c2ecf20Sopenharmony_ci if (i915_request_wait(rq, 0, HZ / 5) < 0) 408c2ecf20Sopenharmony_ci err = -ETIME; 418c2ecf20Sopenharmony_ci i915_request_put(rq); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci return err; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic int request_add_spin(struct i915_request *rq, struct igt_spinner *spin) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci int err = 0; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci i915_request_get(rq); 518c2ecf20Sopenharmony_ci i915_request_add(rq); 528c2ecf20Sopenharmony_ci if (spin && !igt_wait_for_spinner(spin, rq)) 538c2ecf20Sopenharmony_ci err = -ETIME; 548c2ecf20Sopenharmony_ci i915_request_put(rq); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci return err; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic struct i915_vma *create_scratch(struct intel_gt *gt) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci struct drm_i915_gem_object *obj; 628c2ecf20Sopenharmony_ci struct i915_vma *vma; 638c2ecf20Sopenharmony_ci int err; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci obj = i915_gem_object_create_internal(gt->i915, PAGE_SIZE); 668c2ecf20Sopenharmony_ci if (IS_ERR(obj)) 678c2ecf20Sopenharmony_ci return ERR_CAST(obj); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci i915_gem_object_set_cache_coherency(obj, I915_CACHING_CACHED); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci vma = i915_vma_instance(obj, >->ggtt->vm, NULL); 728c2ecf20Sopenharmony_ci if (IS_ERR(vma)) { 738c2ecf20Sopenharmony_ci i915_gem_object_put(obj); 748c2ecf20Sopenharmony_ci return vma; 758c2ecf20Sopenharmony_ci } 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci err = i915_vma_pin(vma, 0, 0, PIN_GLOBAL); 788c2ecf20Sopenharmony_ci if (err) { 798c2ecf20Sopenharmony_ci i915_gem_object_put(obj); 808c2ecf20Sopenharmony_ci return ERR_PTR(err); 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci return vma; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic int live_mocs_init(struct live_mocs *arg, struct intel_gt *gt) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci struct drm_i915_mocs_table table; 898c2ecf20Sopenharmony_ci unsigned int flags; 908c2ecf20Sopenharmony_ci int err; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci memset(arg, 0, sizeof(*arg)); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci flags = get_mocs_settings(gt->i915, &table); 958c2ecf20Sopenharmony_ci if (!flags) 968c2ecf20Sopenharmony_ci return -EINVAL; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci if (flags & HAS_RENDER_L3CC) 998c2ecf20Sopenharmony_ci arg->l3cc = table; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci if (flags & (HAS_GLOBAL_MOCS | HAS_ENGINE_MOCS)) 1028c2ecf20Sopenharmony_ci arg->mocs = table; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci arg->scratch = create_scratch(gt); 1058c2ecf20Sopenharmony_ci if (IS_ERR(arg->scratch)) 1068c2ecf20Sopenharmony_ci return PTR_ERR(arg->scratch); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci arg->vaddr = i915_gem_object_pin_map(arg->scratch->obj, I915_MAP_WB); 1098c2ecf20Sopenharmony_ci if (IS_ERR(arg->vaddr)) { 1108c2ecf20Sopenharmony_ci err = PTR_ERR(arg->vaddr); 1118c2ecf20Sopenharmony_ci goto err_scratch; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci return 0; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_cierr_scratch: 1178c2ecf20Sopenharmony_ci i915_vma_unpin_and_release(&arg->scratch, 0); 1188c2ecf20Sopenharmony_ci return err; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic void live_mocs_fini(struct live_mocs *arg) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci i915_vma_unpin_and_release(&arg->scratch, I915_VMA_RELEASE_MAP); 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistatic int read_regs(struct i915_request *rq, 1278c2ecf20Sopenharmony_ci u32 addr, unsigned int count, 1288c2ecf20Sopenharmony_ci uint32_t *offset) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci unsigned int i; 1318c2ecf20Sopenharmony_ci u32 *cs; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci GEM_BUG_ON(!IS_ALIGNED(*offset, sizeof(u32))); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci cs = intel_ring_begin(rq, 4 * count); 1368c2ecf20Sopenharmony_ci if (IS_ERR(cs)) 1378c2ecf20Sopenharmony_ci return PTR_ERR(cs); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci for (i = 0; i < count; i++) { 1408c2ecf20Sopenharmony_ci *cs++ = MI_STORE_REGISTER_MEM_GEN8 | MI_USE_GGTT; 1418c2ecf20Sopenharmony_ci *cs++ = addr; 1428c2ecf20Sopenharmony_ci *cs++ = *offset; 1438c2ecf20Sopenharmony_ci *cs++ = 0; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci addr += sizeof(u32); 1468c2ecf20Sopenharmony_ci *offset += sizeof(u32); 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci intel_ring_advance(rq, cs); 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci return 0; 1528c2ecf20Sopenharmony_ci} 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_cistatic int read_mocs_table(struct i915_request *rq, 1558c2ecf20Sopenharmony_ci const struct drm_i915_mocs_table *table, 1568c2ecf20Sopenharmony_ci uint32_t *offset) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci u32 addr; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (HAS_GLOBAL_MOCS_REGISTERS(rq->engine->i915)) 1618c2ecf20Sopenharmony_ci addr = global_mocs_offset(); 1628c2ecf20Sopenharmony_ci else 1638c2ecf20Sopenharmony_ci addr = mocs_offset(rq->engine); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci return read_regs(rq, addr, table->n_entries, offset); 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistatic int read_l3cc_table(struct i915_request *rq, 1698c2ecf20Sopenharmony_ci const struct drm_i915_mocs_table *table, 1708c2ecf20Sopenharmony_ci uint32_t *offset) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci u32 addr = i915_mmio_reg_offset(GEN9_LNCFCMOCS(0)); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci return read_regs(rq, addr, (table->n_entries + 1) / 2, offset); 1758c2ecf20Sopenharmony_ci} 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_cistatic int check_mocs_table(struct intel_engine_cs *engine, 1788c2ecf20Sopenharmony_ci const struct drm_i915_mocs_table *table, 1798c2ecf20Sopenharmony_ci uint32_t **vaddr) 1808c2ecf20Sopenharmony_ci{ 1818c2ecf20Sopenharmony_ci unsigned int i; 1828c2ecf20Sopenharmony_ci u32 expect; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci for_each_mocs(expect, table, i) { 1858c2ecf20Sopenharmony_ci if (**vaddr != expect) { 1868c2ecf20Sopenharmony_ci pr_err("%s: Invalid MOCS[%d] entry, found %08x, expected %08x\n", 1878c2ecf20Sopenharmony_ci engine->name, i, **vaddr, expect); 1888c2ecf20Sopenharmony_ci return -EINVAL; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci ++*vaddr; 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci return 0; 1948c2ecf20Sopenharmony_ci} 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic bool mcr_range(struct drm_i915_private *i915, u32 offset) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci /* 1998c2ecf20Sopenharmony_ci * Registers in this range are affected by the MCR selector 2008c2ecf20Sopenharmony_ci * which only controls CPU initiated MMIO. Routing does not 2018c2ecf20Sopenharmony_ci * work for CS access so we cannot verify them on this path. 2028c2ecf20Sopenharmony_ci */ 2038c2ecf20Sopenharmony_ci return INTEL_GEN(i915) >= 8 && offset >= 0xb000 && offset <= 0xb4ff; 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic int check_l3cc_table(struct intel_engine_cs *engine, 2078c2ecf20Sopenharmony_ci const struct drm_i915_mocs_table *table, 2088c2ecf20Sopenharmony_ci uint32_t **vaddr) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci /* Can we read the MCR range 0xb00 directly? See intel_workarounds! */ 2118c2ecf20Sopenharmony_ci u32 reg = i915_mmio_reg_offset(GEN9_LNCFCMOCS(0)); 2128c2ecf20Sopenharmony_ci unsigned int i; 2138c2ecf20Sopenharmony_ci u32 expect; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci for_each_l3cc(expect, table, i) { 2168c2ecf20Sopenharmony_ci if (!mcr_range(engine->i915, reg) && **vaddr != expect) { 2178c2ecf20Sopenharmony_ci pr_err("%s: Invalid L3CC[%d] entry, found %08x, expected %08x\n", 2188c2ecf20Sopenharmony_ci engine->name, i, **vaddr, expect); 2198c2ecf20Sopenharmony_ci return -EINVAL; 2208c2ecf20Sopenharmony_ci } 2218c2ecf20Sopenharmony_ci ++*vaddr; 2228c2ecf20Sopenharmony_ci reg += 4; 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci return 0; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic int check_mocs_engine(struct live_mocs *arg, 2298c2ecf20Sopenharmony_ci struct intel_context *ce) 2308c2ecf20Sopenharmony_ci{ 2318c2ecf20Sopenharmony_ci struct i915_vma *vma = arg->scratch; 2328c2ecf20Sopenharmony_ci struct i915_request *rq; 2338c2ecf20Sopenharmony_ci u32 offset; 2348c2ecf20Sopenharmony_ci u32 *vaddr; 2358c2ecf20Sopenharmony_ci int err; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci memset32(arg->vaddr, STACK_MAGIC, PAGE_SIZE / sizeof(u32)); 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci rq = intel_context_create_request(ce); 2408c2ecf20Sopenharmony_ci if (IS_ERR(rq)) 2418c2ecf20Sopenharmony_ci return PTR_ERR(rq); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci i915_vma_lock(vma); 2448c2ecf20Sopenharmony_ci err = i915_request_await_object(rq, vma->obj, true); 2458c2ecf20Sopenharmony_ci if (!err) 2468c2ecf20Sopenharmony_ci err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE); 2478c2ecf20Sopenharmony_ci i915_vma_unlock(vma); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci /* Read the mocs tables back using SRM */ 2508c2ecf20Sopenharmony_ci offset = i915_ggtt_offset(vma); 2518c2ecf20Sopenharmony_ci if (!err) 2528c2ecf20Sopenharmony_ci err = read_mocs_table(rq, &arg->mocs, &offset); 2538c2ecf20Sopenharmony_ci if (!err && ce->engine->class == RENDER_CLASS) 2548c2ecf20Sopenharmony_ci err = read_l3cc_table(rq, &arg->l3cc, &offset); 2558c2ecf20Sopenharmony_ci offset -= i915_ggtt_offset(vma); 2568c2ecf20Sopenharmony_ci GEM_BUG_ON(offset > PAGE_SIZE); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci err = request_add_sync(rq, err); 2598c2ecf20Sopenharmony_ci if (err) 2608c2ecf20Sopenharmony_ci return err; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* Compare the results against the expected tables */ 2638c2ecf20Sopenharmony_ci vaddr = arg->vaddr; 2648c2ecf20Sopenharmony_ci if (!err) 2658c2ecf20Sopenharmony_ci err = check_mocs_table(ce->engine, &arg->mocs, &vaddr); 2668c2ecf20Sopenharmony_ci if (!err && ce->engine->class == RENDER_CLASS) 2678c2ecf20Sopenharmony_ci err = check_l3cc_table(ce->engine, &arg->l3cc, &vaddr); 2688c2ecf20Sopenharmony_ci if (err) 2698c2ecf20Sopenharmony_ci return err; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci GEM_BUG_ON(arg->vaddr + offset != vaddr); 2728c2ecf20Sopenharmony_ci return 0; 2738c2ecf20Sopenharmony_ci} 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic int live_mocs_kernel(void *arg) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci struct intel_gt *gt = arg; 2788c2ecf20Sopenharmony_ci struct intel_engine_cs *engine; 2798c2ecf20Sopenharmony_ci enum intel_engine_id id; 2808c2ecf20Sopenharmony_ci struct live_mocs mocs; 2818c2ecf20Sopenharmony_ci int err; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci /* Basic check the system is configured with the expected mocs table */ 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci err = live_mocs_init(&mocs, gt); 2868c2ecf20Sopenharmony_ci if (err) 2878c2ecf20Sopenharmony_ci return err; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci for_each_engine(engine, gt, id) { 2908c2ecf20Sopenharmony_ci intel_engine_pm_get(engine); 2918c2ecf20Sopenharmony_ci err = check_mocs_engine(&mocs, engine->kernel_context); 2928c2ecf20Sopenharmony_ci intel_engine_pm_put(engine); 2938c2ecf20Sopenharmony_ci if (err) 2948c2ecf20Sopenharmony_ci break; 2958c2ecf20Sopenharmony_ci } 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci live_mocs_fini(&mocs); 2988c2ecf20Sopenharmony_ci return err; 2998c2ecf20Sopenharmony_ci} 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_cistatic int live_mocs_clean(void *arg) 3028c2ecf20Sopenharmony_ci{ 3038c2ecf20Sopenharmony_ci struct intel_gt *gt = arg; 3048c2ecf20Sopenharmony_ci struct intel_engine_cs *engine; 3058c2ecf20Sopenharmony_ci enum intel_engine_id id; 3068c2ecf20Sopenharmony_ci struct live_mocs mocs; 3078c2ecf20Sopenharmony_ci int err; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci /* Every new context should see the same mocs table */ 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci err = live_mocs_init(&mocs, gt); 3128c2ecf20Sopenharmony_ci if (err) 3138c2ecf20Sopenharmony_ci return err; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci for_each_engine(engine, gt, id) { 3168c2ecf20Sopenharmony_ci struct intel_context *ce; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci ce = mocs_context_create(engine); 3198c2ecf20Sopenharmony_ci if (IS_ERR(ce)) { 3208c2ecf20Sopenharmony_ci err = PTR_ERR(ce); 3218c2ecf20Sopenharmony_ci break; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci err = check_mocs_engine(&mocs, ce); 3258c2ecf20Sopenharmony_ci intel_context_put(ce); 3268c2ecf20Sopenharmony_ci if (err) 3278c2ecf20Sopenharmony_ci break; 3288c2ecf20Sopenharmony_ci } 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci live_mocs_fini(&mocs); 3318c2ecf20Sopenharmony_ci return err; 3328c2ecf20Sopenharmony_ci} 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic int active_engine_reset(struct intel_context *ce, 3358c2ecf20Sopenharmony_ci const char *reason) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci struct igt_spinner spin; 3388c2ecf20Sopenharmony_ci struct i915_request *rq; 3398c2ecf20Sopenharmony_ci int err; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci err = igt_spinner_init(&spin, ce->engine->gt); 3428c2ecf20Sopenharmony_ci if (err) 3438c2ecf20Sopenharmony_ci return err; 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci rq = igt_spinner_create_request(&spin, ce, MI_NOOP); 3468c2ecf20Sopenharmony_ci if (IS_ERR(rq)) { 3478c2ecf20Sopenharmony_ci igt_spinner_fini(&spin); 3488c2ecf20Sopenharmony_ci return PTR_ERR(rq); 3498c2ecf20Sopenharmony_ci } 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci err = request_add_spin(rq, &spin); 3528c2ecf20Sopenharmony_ci if (err == 0) 3538c2ecf20Sopenharmony_ci err = intel_engine_reset(ce->engine, reason); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci igt_spinner_end(&spin); 3568c2ecf20Sopenharmony_ci igt_spinner_fini(&spin); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci return err; 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_cistatic int __live_mocs_reset(struct live_mocs *mocs, 3628c2ecf20Sopenharmony_ci struct intel_context *ce) 3638c2ecf20Sopenharmony_ci{ 3648c2ecf20Sopenharmony_ci int err; 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci err = intel_engine_reset(ce->engine, "mocs"); 3678c2ecf20Sopenharmony_ci if (err) 3688c2ecf20Sopenharmony_ci return err; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci err = check_mocs_engine(mocs, ce); 3718c2ecf20Sopenharmony_ci if (err) 3728c2ecf20Sopenharmony_ci return err; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci err = active_engine_reset(ce, "mocs"); 3758c2ecf20Sopenharmony_ci if (err) 3768c2ecf20Sopenharmony_ci return err; 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci err = check_mocs_engine(mocs, ce); 3798c2ecf20Sopenharmony_ci if (err) 3808c2ecf20Sopenharmony_ci return err; 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci intel_gt_reset(ce->engine->gt, ce->engine->mask, "mocs"); 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci err = check_mocs_engine(mocs, ce); 3858c2ecf20Sopenharmony_ci if (err) 3868c2ecf20Sopenharmony_ci return err; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci return 0; 3898c2ecf20Sopenharmony_ci} 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_cistatic int live_mocs_reset(void *arg) 3928c2ecf20Sopenharmony_ci{ 3938c2ecf20Sopenharmony_ci struct intel_gt *gt = arg; 3948c2ecf20Sopenharmony_ci struct intel_engine_cs *engine; 3958c2ecf20Sopenharmony_ci enum intel_engine_id id; 3968c2ecf20Sopenharmony_ci struct live_mocs mocs; 3978c2ecf20Sopenharmony_ci int err = 0; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci /* Check the mocs setup is retained over per-engine and global resets */ 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci if (!intel_has_reset_engine(gt)) 4028c2ecf20Sopenharmony_ci return 0; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci err = live_mocs_init(&mocs, gt); 4058c2ecf20Sopenharmony_ci if (err) 4068c2ecf20Sopenharmony_ci return err; 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci igt_global_reset_lock(gt); 4098c2ecf20Sopenharmony_ci for_each_engine(engine, gt, id) { 4108c2ecf20Sopenharmony_ci struct intel_context *ce; 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci ce = mocs_context_create(engine); 4138c2ecf20Sopenharmony_ci if (IS_ERR(ce)) { 4148c2ecf20Sopenharmony_ci err = PTR_ERR(ce); 4158c2ecf20Sopenharmony_ci break; 4168c2ecf20Sopenharmony_ci } 4178c2ecf20Sopenharmony_ci 4188c2ecf20Sopenharmony_ci intel_engine_pm_get(engine); 4198c2ecf20Sopenharmony_ci err = __live_mocs_reset(&mocs, ce); 4208c2ecf20Sopenharmony_ci intel_engine_pm_put(engine); 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci intel_context_put(ce); 4238c2ecf20Sopenharmony_ci if (err) 4248c2ecf20Sopenharmony_ci break; 4258c2ecf20Sopenharmony_ci } 4268c2ecf20Sopenharmony_ci igt_global_reset_unlock(gt); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci live_mocs_fini(&mocs); 4298c2ecf20Sopenharmony_ci return err; 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ciint intel_mocs_live_selftests(struct drm_i915_private *i915) 4338c2ecf20Sopenharmony_ci{ 4348c2ecf20Sopenharmony_ci static const struct i915_subtest tests[] = { 4358c2ecf20Sopenharmony_ci SUBTEST(live_mocs_kernel), 4368c2ecf20Sopenharmony_ci SUBTEST(live_mocs_clean), 4378c2ecf20Sopenharmony_ci SUBTEST(live_mocs_reset), 4388c2ecf20Sopenharmony_ci }; 4398c2ecf20Sopenharmony_ci struct drm_i915_mocs_table table; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci if (!get_mocs_settings(i915, &table)) 4428c2ecf20Sopenharmony_ci return 0; 4438c2ecf20Sopenharmony_ci 4448c2ecf20Sopenharmony_ci return intel_gt_live_subtests(tests, &i915->gt); 4458c2ecf20Sopenharmony_ci} 446