1*a6a4ea6dSRuthuvikas Ravikumar // SPDX-License-Identifier: GPL-2.0 AND MIT 2*a6a4ea6dSRuthuvikas Ravikumar /* 3*a6a4ea6dSRuthuvikas Ravikumar * Copyright © 2022 Intel Corporation 4*a6a4ea6dSRuthuvikas Ravikumar */ 5*a6a4ea6dSRuthuvikas Ravikumar 6*a6a4ea6dSRuthuvikas Ravikumar #include <kunit/test.h> 7*a6a4ea6dSRuthuvikas Ravikumar #include <kunit/visibility.h> 8*a6a4ea6dSRuthuvikas Ravikumar 9*a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_mocs_test.h" 10*a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_pci_test.h" 11*a6a4ea6dSRuthuvikas Ravikumar #include "tests/xe_test.h" 12*a6a4ea6dSRuthuvikas Ravikumar 13*a6a4ea6dSRuthuvikas Ravikumar #include "xe_pci.h" 14*a6a4ea6dSRuthuvikas Ravikumar #include "xe_gt.h" 15*a6a4ea6dSRuthuvikas Ravikumar #include "xe_mocs.h" 16*a6a4ea6dSRuthuvikas Ravikumar #include "xe_device.h" 17*a6a4ea6dSRuthuvikas Ravikumar 18*a6a4ea6dSRuthuvikas Ravikumar struct live_mocs { 19*a6a4ea6dSRuthuvikas Ravikumar struct xe_mocs_info table; 20*a6a4ea6dSRuthuvikas Ravikumar }; 21*a6a4ea6dSRuthuvikas Ravikumar 22*a6a4ea6dSRuthuvikas Ravikumar static int live_mocs_init(struct live_mocs *arg, struct xe_gt *gt) 23*a6a4ea6dSRuthuvikas Ravikumar { 24*a6a4ea6dSRuthuvikas Ravikumar unsigned int flags; 25*a6a4ea6dSRuthuvikas Ravikumar struct kunit *test = xe_cur_kunit(); 26*a6a4ea6dSRuthuvikas Ravikumar 27*a6a4ea6dSRuthuvikas Ravikumar memset(arg, 0, sizeof(*arg)); 28*a6a4ea6dSRuthuvikas Ravikumar 29*a6a4ea6dSRuthuvikas Ravikumar flags = get_mocs_settings(gt_to_xe(gt), &arg->table); 30*a6a4ea6dSRuthuvikas Ravikumar 31*a6a4ea6dSRuthuvikas Ravikumar kunit_info(test, "table size %d", arg->table.size); 32*a6a4ea6dSRuthuvikas Ravikumar kunit_info(test, "table uc_index %d", arg->table.uc_index); 33*a6a4ea6dSRuthuvikas Ravikumar kunit_info(test, "table n_entries %d", arg->table.n_entries); 34*a6a4ea6dSRuthuvikas Ravikumar 35*a6a4ea6dSRuthuvikas Ravikumar return flags; 36*a6a4ea6dSRuthuvikas Ravikumar } 37*a6a4ea6dSRuthuvikas Ravikumar 38*a6a4ea6dSRuthuvikas Ravikumar static void read_l3cc_table(struct xe_gt *gt, 39*a6a4ea6dSRuthuvikas Ravikumar const struct xe_mocs_info *info) 40*a6a4ea6dSRuthuvikas Ravikumar { 41*a6a4ea6dSRuthuvikas Ravikumar unsigned int i; 42*a6a4ea6dSRuthuvikas Ravikumar u32 l3cc; 43*a6a4ea6dSRuthuvikas Ravikumar u32 reg_val; 44*a6a4ea6dSRuthuvikas Ravikumar u32 ret; 45*a6a4ea6dSRuthuvikas Ravikumar 46*a6a4ea6dSRuthuvikas Ravikumar struct kunit *test = xe_cur_kunit(); 47*a6a4ea6dSRuthuvikas Ravikumar 48*a6a4ea6dSRuthuvikas Ravikumar xe_device_mem_access_get(gt_to_xe(gt)); 49*a6a4ea6dSRuthuvikas Ravikumar ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT); 50*a6a4ea6dSRuthuvikas Ravikumar KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n"); 51*a6a4ea6dSRuthuvikas Ravikumar mocs_dbg(>_to_xe(gt)->drm, "L3CC entries:%d\n", info->n_entries); 52*a6a4ea6dSRuthuvikas Ravikumar for (i = 0; 53*a6a4ea6dSRuthuvikas Ravikumar i < (info->n_entries + 1) / 2 ? 54*a6a4ea6dSRuthuvikas Ravikumar (l3cc = l3cc_combine(get_entry_l3cc(info, 2 * i), 55*a6a4ea6dSRuthuvikas Ravikumar get_entry_l3cc(info, 2 * i + 1))), 1 : 0; 56*a6a4ea6dSRuthuvikas Ravikumar i++) { 57*a6a4ea6dSRuthuvikas Ravikumar if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250) 58*a6a4ea6dSRuthuvikas Ravikumar reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_LNCFCMOCS(i)); 59*a6a4ea6dSRuthuvikas Ravikumar else 60*a6a4ea6dSRuthuvikas Ravikumar reg_val = xe_mmio_read32(gt, XELP_LNCFCMOCS(i)); 61*a6a4ea6dSRuthuvikas Ravikumar mocs_dbg(>_to_xe(gt)->drm, "%d 0x%x 0x%x 0x%x\n", i, 62*a6a4ea6dSRuthuvikas Ravikumar XELP_LNCFCMOCS(i).addr, reg_val, l3cc); 63*a6a4ea6dSRuthuvikas Ravikumar if (reg_val != l3cc) 64*a6a4ea6dSRuthuvikas Ravikumar KUNIT_FAIL(test, "l3cc reg 0x%x has incorrect val.\n", 65*a6a4ea6dSRuthuvikas Ravikumar XELP_LNCFCMOCS(i).addr); 66*a6a4ea6dSRuthuvikas Ravikumar } 67*a6a4ea6dSRuthuvikas Ravikumar xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); 68*a6a4ea6dSRuthuvikas Ravikumar xe_device_mem_access_put(gt_to_xe(gt)); 69*a6a4ea6dSRuthuvikas Ravikumar } 70*a6a4ea6dSRuthuvikas Ravikumar 71*a6a4ea6dSRuthuvikas Ravikumar static void read_mocs_table(struct xe_gt *gt, 72*a6a4ea6dSRuthuvikas Ravikumar const struct xe_mocs_info *info) 73*a6a4ea6dSRuthuvikas Ravikumar { 74*a6a4ea6dSRuthuvikas Ravikumar struct xe_device *xe = gt_to_xe(gt); 75*a6a4ea6dSRuthuvikas Ravikumar 76*a6a4ea6dSRuthuvikas Ravikumar unsigned int i; 77*a6a4ea6dSRuthuvikas Ravikumar u32 mocs; 78*a6a4ea6dSRuthuvikas Ravikumar u32 reg_val; 79*a6a4ea6dSRuthuvikas Ravikumar u32 ret; 80*a6a4ea6dSRuthuvikas Ravikumar 81*a6a4ea6dSRuthuvikas Ravikumar struct kunit *test = xe_cur_kunit(); 82*a6a4ea6dSRuthuvikas Ravikumar 83*a6a4ea6dSRuthuvikas Ravikumar xe_device_mem_access_get(gt_to_xe(gt)); 84*a6a4ea6dSRuthuvikas Ravikumar ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT); 85*a6a4ea6dSRuthuvikas Ravikumar KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n"); 86*a6a4ea6dSRuthuvikas Ravikumar mocs_dbg(>_to_xe(gt)->drm, "Global MOCS entries:%d\n", info->n_entries); 87*a6a4ea6dSRuthuvikas Ravikumar drm_WARN_ONCE(&xe->drm, !info->unused_entries_index, 88*a6a4ea6dSRuthuvikas Ravikumar "Unused entries index should have been defined\n"); 89*a6a4ea6dSRuthuvikas Ravikumar for (i = 0; 90*a6a4ea6dSRuthuvikas Ravikumar i < info->n_entries ? (mocs = get_entry_control(info, i)), 1 : 0; 91*a6a4ea6dSRuthuvikas Ravikumar i++) { 92*a6a4ea6dSRuthuvikas Ravikumar if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250) 93*a6a4ea6dSRuthuvikas Ravikumar reg_val = xe_gt_mcr_unicast_read_any(gt, XEHP_GLOBAL_MOCS(i)); 94*a6a4ea6dSRuthuvikas Ravikumar else 95*a6a4ea6dSRuthuvikas Ravikumar reg_val = xe_mmio_read32(gt, XELP_GLOBAL_MOCS(i)); 96*a6a4ea6dSRuthuvikas Ravikumar mocs_dbg(>_to_xe(gt)->drm, "%d 0x%x 0x%x 0x%x\n", i, 97*a6a4ea6dSRuthuvikas Ravikumar XELP_GLOBAL_MOCS(i).addr, reg_val, mocs); 98*a6a4ea6dSRuthuvikas Ravikumar if (reg_val != mocs) 99*a6a4ea6dSRuthuvikas Ravikumar KUNIT_FAIL(test, "mocs reg 0x%x has incorrect val.\n", 100*a6a4ea6dSRuthuvikas Ravikumar XELP_GLOBAL_MOCS(i).addr); 101*a6a4ea6dSRuthuvikas Ravikumar } 102*a6a4ea6dSRuthuvikas Ravikumar xe_force_wake_put(gt_to_fw(gt), XE_FW_GT); 103*a6a4ea6dSRuthuvikas Ravikumar xe_device_mem_access_put(gt_to_xe(gt)); 104*a6a4ea6dSRuthuvikas Ravikumar } 105*a6a4ea6dSRuthuvikas Ravikumar 106*a6a4ea6dSRuthuvikas Ravikumar static int mocs_kernel_test_run_device(struct xe_device *xe) 107*a6a4ea6dSRuthuvikas Ravikumar { 108*a6a4ea6dSRuthuvikas Ravikumar /* Basic check the system is configured with the expected mocs table */ 109*a6a4ea6dSRuthuvikas Ravikumar 110*a6a4ea6dSRuthuvikas Ravikumar struct live_mocs mocs; 111*a6a4ea6dSRuthuvikas Ravikumar struct xe_gt *gt; 112*a6a4ea6dSRuthuvikas Ravikumar 113*a6a4ea6dSRuthuvikas Ravikumar unsigned int flags; 114*a6a4ea6dSRuthuvikas Ravikumar int id; 115*a6a4ea6dSRuthuvikas Ravikumar 116*a6a4ea6dSRuthuvikas Ravikumar for_each_gt(gt, xe, id) { 117*a6a4ea6dSRuthuvikas Ravikumar flags = live_mocs_init(&mocs, gt); 118*a6a4ea6dSRuthuvikas Ravikumar if (flags & HAS_GLOBAL_MOCS) 119*a6a4ea6dSRuthuvikas Ravikumar read_mocs_table(gt, &mocs.table); 120*a6a4ea6dSRuthuvikas Ravikumar if (flags & HAS_LNCF_MOCS) 121*a6a4ea6dSRuthuvikas Ravikumar read_l3cc_table(gt, &mocs.table); 122*a6a4ea6dSRuthuvikas Ravikumar } 123*a6a4ea6dSRuthuvikas Ravikumar return 0; 124*a6a4ea6dSRuthuvikas Ravikumar } 125*a6a4ea6dSRuthuvikas Ravikumar 126*a6a4ea6dSRuthuvikas Ravikumar void xe_live_mocs_kernel_kunit(struct kunit *test) 127*a6a4ea6dSRuthuvikas Ravikumar { 128*a6a4ea6dSRuthuvikas Ravikumar xe_call_for_each_device(mocs_kernel_test_run_device); 129*a6a4ea6dSRuthuvikas Ravikumar } 130*a6a4ea6dSRuthuvikas Ravikumar EXPORT_SYMBOL_IF_KUNIT(xe_live_mocs_kernel_kunit); 131