1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2024 Intel Corporation 4 */ 5 6 #include "xe_pxp_debugfs.h" 7 8 #include <linux/debugfs.h> 9 10 #include <drm/drm_debugfs.h> 11 #include <drm/drm_managed.h> 12 #include <drm/drm_print.h> 13 14 #include "xe_device.h" 15 #include "xe_pxp.h" 16 #include "xe_pxp_types.h" 17 #include "regs/xe_irq_regs.h" 18 19 static struct xe_pxp *node_to_pxp(struct drm_info_node *node) 20 { 21 return node->info_ent->data; 22 } 23 24 static const char *pxp_status_to_str(struct xe_pxp *pxp) 25 { 26 lockdep_assert_held(&pxp->mutex); 27 28 switch (pxp->status) { 29 case XE_PXP_ERROR: 30 return "error"; 31 case XE_PXP_NEEDS_TERMINATION: 32 return "needs termination"; 33 case XE_PXP_TERMINATION_IN_PROGRESS: 34 return "termination in progress"; 35 case XE_PXP_READY_TO_START: 36 return "ready to start"; 37 case XE_PXP_ACTIVE: 38 return "active"; 39 case XE_PXP_SUSPENDED: 40 return "suspended"; 41 default: 42 return "unknown"; 43 } 44 }; 45 46 static int pxp_info(struct seq_file *m, void *data) 47 { 48 struct xe_pxp *pxp = node_to_pxp(m->private); 49 struct drm_printer p = drm_seq_file_printer(m); 50 const char *status; 51 52 if (!xe_pxp_is_enabled(pxp)) 53 return -ENODEV; 54 55 mutex_lock(&pxp->mutex); 56 status = pxp_status_to_str(pxp); 57 58 drm_printf(&p, "status: %s\n", status); 59 drm_printf(&p, "instance counter: %u\n", pxp->key_instance); 60 mutex_unlock(&pxp->mutex); 61 62 return 0; 63 } 64 65 static int pxp_terminate(struct seq_file *m, void *data) 66 { 67 struct xe_pxp *pxp = node_to_pxp(m->private); 68 struct drm_printer p = drm_seq_file_printer(m); 69 70 if (!xe_pxp_is_enabled(pxp)) 71 return -ENODEV; 72 73 /* simulate a termination interrupt */ 74 spin_lock_irq(&pxp->xe->irq.lock); 75 xe_pxp_irq_handler(pxp->xe, KCR_PXP_STATE_TERMINATED_INTERRUPT); 76 spin_unlock_irq(&pxp->xe->irq.lock); 77 78 drm_printf(&p, "PXP termination queued\n"); 79 80 return 0; 81 } 82 83 static const struct drm_info_list debugfs_list[] = { 84 {"info", pxp_info, 0}, 85 {"terminate", pxp_terminate, 0}, 86 }; 87 88 void xe_pxp_debugfs_register(struct xe_pxp *pxp) 89 { 90 struct drm_minor *minor; 91 struct drm_info_list *local; 92 struct dentry *root; 93 int i; 94 95 if (!xe_pxp_is_enabled(pxp)) 96 return; 97 98 minor = pxp->xe->drm.primary; 99 if (!minor->debugfs_root) 100 return; 101 102 #define DEBUGFS_SIZE (ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list)) 103 local = drmm_kmalloc(&pxp->xe->drm, DEBUGFS_SIZE, GFP_KERNEL); 104 if (!local) 105 return; 106 107 memcpy(local, debugfs_list, DEBUGFS_SIZE); 108 #undef DEBUGFS_SIZE 109 110 for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i) 111 local[i].data = pxp; 112 113 root = debugfs_create_dir("pxp", minor->debugfs_root); 114 if (IS_ERR(root)) 115 return; 116 117 drm_debugfs_create_files(local, 118 ARRAY_SIZE(debugfs_list), 119 root, minor); 120 } 121