xref: /linux/drivers/gpu/drm/xe/xe_pxp_debugfs.c (revision 51c7960b87f465d01ea8d8ff174e81dd69f3b2b4)
1385a8015SDaniele Ceraolo Spurio // SPDX-License-Identifier: MIT
2385a8015SDaniele Ceraolo Spurio /*
3385a8015SDaniele Ceraolo Spurio  * Copyright © 2024 Intel Corporation
4385a8015SDaniele Ceraolo Spurio  */
5385a8015SDaniele Ceraolo Spurio 
6385a8015SDaniele Ceraolo Spurio #include "xe_pxp_debugfs.h"
7385a8015SDaniele Ceraolo Spurio 
8385a8015SDaniele Ceraolo Spurio #include <linux/debugfs.h>
9385a8015SDaniele Ceraolo Spurio 
10385a8015SDaniele Ceraolo Spurio #include <drm/drm_debugfs.h>
11385a8015SDaniele Ceraolo Spurio #include <drm/drm_managed.h>
12385a8015SDaniele Ceraolo Spurio #include <drm/drm_print.h>
13385a8015SDaniele Ceraolo Spurio 
14385a8015SDaniele Ceraolo Spurio #include "xe_device.h"
15385a8015SDaniele Ceraolo Spurio #include "xe_pxp.h"
16385a8015SDaniele Ceraolo Spurio #include "xe_pxp_types.h"
17385a8015SDaniele Ceraolo Spurio #include "regs/xe_irq_regs.h"
18385a8015SDaniele Ceraolo Spurio 
node_to_pxp(struct drm_info_node * node)19385a8015SDaniele Ceraolo Spurio static struct xe_pxp *node_to_pxp(struct drm_info_node *node)
20385a8015SDaniele Ceraolo Spurio {
21385a8015SDaniele Ceraolo Spurio 	return node->info_ent->data;
22385a8015SDaniele Ceraolo Spurio }
23385a8015SDaniele Ceraolo Spurio 
pxp_status_to_str(struct xe_pxp * pxp)24385a8015SDaniele Ceraolo Spurio static const char *pxp_status_to_str(struct xe_pxp *pxp)
25385a8015SDaniele Ceraolo Spurio {
26385a8015SDaniele Ceraolo Spurio 	lockdep_assert_held(&pxp->mutex);
27385a8015SDaniele Ceraolo Spurio 
28385a8015SDaniele Ceraolo Spurio 	switch (pxp->status) {
29385a8015SDaniele Ceraolo Spurio 	case XE_PXP_ERROR:
30385a8015SDaniele Ceraolo Spurio 		return "error";
31385a8015SDaniele Ceraolo Spurio 	case XE_PXP_NEEDS_TERMINATION:
32385a8015SDaniele Ceraolo Spurio 		return "needs termination";
33385a8015SDaniele Ceraolo Spurio 	case XE_PXP_TERMINATION_IN_PROGRESS:
34385a8015SDaniele Ceraolo Spurio 		return "termination in progress";
35385a8015SDaniele Ceraolo Spurio 	case XE_PXP_READY_TO_START:
36385a8015SDaniele Ceraolo Spurio 		return "ready to start";
37385a8015SDaniele Ceraolo Spurio 	case XE_PXP_ACTIVE:
38385a8015SDaniele Ceraolo Spurio 		return "active";
39385a8015SDaniele Ceraolo Spurio 	case XE_PXP_SUSPENDED:
40385a8015SDaniele Ceraolo Spurio 		return "suspended";
41385a8015SDaniele Ceraolo Spurio 	default:
42385a8015SDaniele Ceraolo Spurio 		return "unknown";
43385a8015SDaniele Ceraolo Spurio 	}
44385a8015SDaniele Ceraolo Spurio };
45385a8015SDaniele Ceraolo Spurio 
pxp_info(struct seq_file * m,void * data)46385a8015SDaniele Ceraolo Spurio static int pxp_info(struct seq_file *m, void *data)
47385a8015SDaniele Ceraolo Spurio {
48385a8015SDaniele Ceraolo Spurio 	struct xe_pxp *pxp = node_to_pxp(m->private);
49385a8015SDaniele Ceraolo Spurio 	struct drm_printer p = drm_seq_file_printer(m);
50385a8015SDaniele Ceraolo Spurio 	const char *status;
51385a8015SDaniele Ceraolo Spurio 
52385a8015SDaniele Ceraolo Spurio 	if (!xe_pxp_is_enabled(pxp))
53385a8015SDaniele Ceraolo Spurio 		return -ENODEV;
54385a8015SDaniele Ceraolo Spurio 
55385a8015SDaniele Ceraolo Spurio 	mutex_lock(&pxp->mutex);
56385a8015SDaniele Ceraolo Spurio 	status = pxp_status_to_str(pxp);
57385a8015SDaniele Ceraolo Spurio 
58385a8015SDaniele Ceraolo Spurio 	drm_printf(&p, "status: %s\n", status);
59385a8015SDaniele Ceraolo Spurio 	drm_printf(&p, "instance counter: %u\n", pxp->key_instance);
60385a8015SDaniele Ceraolo Spurio 	mutex_unlock(&pxp->mutex);
61385a8015SDaniele Ceraolo Spurio 
62385a8015SDaniele Ceraolo Spurio 	return 0;
63385a8015SDaniele Ceraolo Spurio }
64385a8015SDaniele Ceraolo Spurio 
pxp_terminate(struct seq_file * m,void * data)65385a8015SDaniele Ceraolo Spurio static int pxp_terminate(struct seq_file *m, void *data)
66385a8015SDaniele Ceraolo Spurio {
67385a8015SDaniele Ceraolo Spurio 	struct xe_pxp *pxp = node_to_pxp(m->private);
68385a8015SDaniele Ceraolo Spurio 	struct drm_printer p = drm_seq_file_printer(m);
69*78600df8SDaniele Ceraolo Spurio 	int ready = xe_pxp_get_readiness_status(pxp);
70385a8015SDaniele Ceraolo Spurio 
71*78600df8SDaniele Ceraolo Spurio 	if (ready < 0)
72*78600df8SDaniele Ceraolo Spurio 		return ready; /* disabled or error occurred */
73*78600df8SDaniele Ceraolo Spurio 	else if (!ready)
74*78600df8SDaniele Ceraolo Spurio 		return -EBUSY; /* init still in progress */
75*78600df8SDaniele Ceraolo Spurio 
76*78600df8SDaniele Ceraolo Spurio 	/* no need for a termination if PXP is not active */
77*78600df8SDaniele Ceraolo Spurio 	if (pxp->status != XE_PXP_ACTIVE) {
78*78600df8SDaniele Ceraolo Spurio 		drm_printf(&p, "PXP not active\n");
79*78600df8SDaniele Ceraolo Spurio 		return 0;
80*78600df8SDaniele Ceraolo Spurio 	}
81385a8015SDaniele Ceraolo Spurio 
82385a8015SDaniele Ceraolo Spurio 	/* simulate a termination interrupt */
83385a8015SDaniele Ceraolo Spurio 	spin_lock_irq(&pxp->xe->irq.lock);
84385a8015SDaniele Ceraolo Spurio 	xe_pxp_irq_handler(pxp->xe, KCR_PXP_STATE_TERMINATED_INTERRUPT);
85385a8015SDaniele Ceraolo Spurio 	spin_unlock_irq(&pxp->xe->irq.lock);
86385a8015SDaniele Ceraolo Spurio 
87385a8015SDaniele Ceraolo Spurio 	drm_printf(&p, "PXP termination queued\n");
88385a8015SDaniele Ceraolo Spurio 
89385a8015SDaniele Ceraolo Spurio 	return 0;
90385a8015SDaniele Ceraolo Spurio }
91385a8015SDaniele Ceraolo Spurio 
92385a8015SDaniele Ceraolo Spurio static const struct drm_info_list debugfs_list[] = {
93385a8015SDaniele Ceraolo Spurio 	{"info", pxp_info, 0},
94385a8015SDaniele Ceraolo Spurio 	{"terminate", pxp_terminate, 0},
95385a8015SDaniele Ceraolo Spurio };
96385a8015SDaniele Ceraolo Spurio 
xe_pxp_debugfs_register(struct xe_pxp * pxp)97385a8015SDaniele Ceraolo Spurio void xe_pxp_debugfs_register(struct xe_pxp *pxp)
98385a8015SDaniele Ceraolo Spurio {
99385a8015SDaniele Ceraolo Spurio 	struct drm_minor *minor;
100385a8015SDaniele Ceraolo Spurio 	struct drm_info_list *local;
101385a8015SDaniele Ceraolo Spurio 	struct dentry *root;
102385a8015SDaniele Ceraolo Spurio 	int i;
103385a8015SDaniele Ceraolo Spurio 
104385a8015SDaniele Ceraolo Spurio 	if (!xe_pxp_is_enabled(pxp))
105385a8015SDaniele Ceraolo Spurio 		return;
106385a8015SDaniele Ceraolo Spurio 
107385a8015SDaniele Ceraolo Spurio 	minor = pxp->xe->drm.primary;
108385a8015SDaniele Ceraolo Spurio 	if (!minor->debugfs_root)
109385a8015SDaniele Ceraolo Spurio 		return;
110385a8015SDaniele Ceraolo Spurio 
111385a8015SDaniele Ceraolo Spurio #define DEBUGFS_SIZE	(ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list))
112385a8015SDaniele Ceraolo Spurio 	local = drmm_kmalloc(&pxp->xe->drm, DEBUGFS_SIZE, GFP_KERNEL);
113385a8015SDaniele Ceraolo Spurio 	if (!local)
114385a8015SDaniele Ceraolo Spurio 		return;
115385a8015SDaniele Ceraolo Spurio 
116385a8015SDaniele Ceraolo Spurio 	memcpy(local, debugfs_list, DEBUGFS_SIZE);
117385a8015SDaniele Ceraolo Spurio #undef DEBUGFS_SIZE
118385a8015SDaniele Ceraolo Spurio 
119385a8015SDaniele Ceraolo Spurio 	for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i)
120385a8015SDaniele Ceraolo Spurio 		local[i].data = pxp;
121385a8015SDaniele Ceraolo Spurio 
122385a8015SDaniele Ceraolo Spurio 	root = debugfs_create_dir("pxp", minor->debugfs_root);
123385a8015SDaniele Ceraolo Spurio 	if (IS_ERR(root))
124385a8015SDaniele Ceraolo Spurio 		return;
125385a8015SDaniele Ceraolo Spurio 
126385a8015SDaniele Ceraolo Spurio 	drm_debugfs_create_files(local,
127385a8015SDaniele Ceraolo Spurio 				 ARRAY_SIZE(debugfs_list),
128385a8015SDaniele Ceraolo Spurio 				 root, minor);
129385a8015SDaniele Ceraolo Spurio }
130