1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2022 Intel Corporation 4 */ 5 6 #include <drm/drm_debugfs.h> 7 #include <drm/drm_managed.h> 8 9 #include "xe_device.h" 10 #include "xe_force_wake.h" 11 #include "xe_gt.h" 12 #include "xe_gt_debugfs.h" 13 #include "xe_gt_mcr.h" 14 #include "xe_gt_pagefault.h" 15 #include "xe_gt_topology.h" 16 #include "xe_hw_engine.h" 17 #include "xe_macros.h" 18 #include "xe_uc_debugfs.h" 19 20 static struct xe_gt *node_to_gt(struct drm_info_node *node) 21 { 22 return node->info_ent->data; 23 } 24 25 static int hw_engines(struct seq_file *m, void *data) 26 { 27 struct xe_gt *gt = node_to_gt(m->private); 28 struct xe_device *xe = gt_to_xe(gt); 29 struct drm_printer p = drm_seq_file_printer(m); 30 struct xe_hw_engine *hwe; 31 enum xe_hw_engine_id id; 32 int err; 33 34 xe_device_mem_access_get(xe); 35 err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL); 36 if (err) { 37 xe_device_mem_access_put(xe); 38 return err; 39 } 40 41 for_each_hw_engine(hwe, gt, id) 42 xe_hw_engine_print_state(hwe, &p); 43 44 xe_device_mem_access_put(xe); 45 err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL); 46 if (err) 47 return err; 48 49 return 0; 50 } 51 52 static int force_reset(struct seq_file *m, void *data) 53 { 54 struct xe_gt *gt = node_to_gt(m->private); 55 56 xe_gt_reset_async(gt); 57 58 return 0; 59 } 60 61 static int sa_info(struct seq_file *m, void *data) 62 { 63 struct xe_gt *gt = node_to_gt(m->private); 64 struct drm_printer p = drm_seq_file_printer(m); 65 66 drm_suballoc_dump_debug_info(>->kernel_bb_pool.base, &p, 67 gt->kernel_bb_pool.gpu_addr); 68 69 return 0; 70 } 71 72 static int topology(struct seq_file *m, void *data) 73 { 74 struct xe_gt *gt = node_to_gt(m->private); 75 struct drm_printer p = drm_seq_file_printer(m); 76 77 xe_gt_topology_dump(gt, &p); 78 79 return 0; 80 } 81 82 static int steering(struct seq_file *m, void *data) 83 { 84 struct xe_gt *gt = node_to_gt(m->private); 85 struct drm_printer p = drm_seq_file_printer(m); 86 87 xe_gt_mcr_steering_dump(gt, &p); 88 89 return 0; 90 } 91 92 #ifdef CONFIG_DRM_XE_DEBUG 93 static int invalidate_tlb(struct seq_file *m, void *data) 94 { 95 struct xe_gt *gt = node_to_gt(m->private); 96 int seqno; 97 int ret = 0; 98 99 seqno = xe_gt_tlb_invalidation(gt); 100 XE_WARN_ON(seqno < 0); 101 if (seqno > 0) 102 ret = xe_gt_tlb_invalidation_wait(gt, seqno); 103 XE_WARN_ON(ret < 0); 104 105 return 0; 106 } 107 #endif 108 109 static const struct drm_info_list debugfs_list[] = { 110 {"hw_engines", hw_engines, 0}, 111 {"force_reset", force_reset, 0}, 112 {"sa_info", sa_info, 0}, 113 {"topology", topology, 0}, 114 {"steering", steering, 0}, 115 #ifdef CONFIG_DRM_XE_DEBUG 116 {"invalidate_tlb", invalidate_tlb, 0}, 117 #endif 118 }; 119 120 void xe_gt_debugfs_register(struct xe_gt *gt) 121 { 122 struct drm_minor *minor = gt_to_xe(gt)->drm.primary; 123 struct dentry *root; 124 struct drm_info_list *local; 125 char name[8]; 126 int i; 127 128 XE_BUG_ON(!minor->debugfs_root); 129 130 sprintf(name, "gt%d", gt->info.id); 131 root = debugfs_create_dir(name, minor->debugfs_root); 132 if (IS_ERR(root)) { 133 XE_WARN_ON("Create GT directory failed"); 134 return; 135 } 136 137 /* 138 * Allocate local copy as we need to pass in the GT to the debugfs 139 * entry and drm_debugfs_create_files just references the drm_info_list 140 * passed in (e.g. can't define this on the stack). 141 */ 142 #define DEBUGFS_SIZE ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list) 143 local = drmm_kmalloc(>_to_xe(gt)->drm, DEBUGFS_SIZE, GFP_KERNEL); 144 if (!local) { 145 XE_WARN_ON("Couldn't allocate memory"); 146 return; 147 } 148 149 memcpy(local, debugfs_list, DEBUGFS_SIZE); 150 #undef DEBUGFS_SIZE 151 152 for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i) 153 local[i].data = gt; 154 155 drm_debugfs_create_files(local, 156 ARRAY_SIZE(debugfs_list), 157 root, minor); 158 159 xe_uc_debugfs_register(>->uc, root); 160 } 161