xref: /linux/drivers/gpu/drm/xe/xe_pxp_debugfs.c (revision fe7fad476ec8153a8b8767a08114e3e4a58a837e)
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