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