1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * AMD Passthrough DMA device driver |
4 | * -- Based on the CCP driver |
5 | * |
6 | * Copyright (C) 2016,2021 Advanced Micro Devices, Inc. |
7 | * |
8 | * Author: Sanjay R Mehta <sanju.mehta@amd.com> |
9 | * Author: Gary R Hook <gary.hook@amd.com> |
10 | */ |
11 | |
12 | #include <linux/debugfs.h> |
13 | #include <linux/seq_file.h> |
14 | |
15 | #include "ptdma.h" |
16 | |
17 | /* DebugFS helpers */ |
18 | #define RI_VERSION_NUM 0x0000003F |
19 | |
20 | #define RI_NUM_VQM 0x00078000 |
21 | #define RI_NVQM_SHIFT 15 |
22 | |
23 | static int pt_debugfs_info_show(struct seq_file *s, void *p) |
24 | { |
25 | struct pt_device *pt = s->private; |
26 | unsigned int regval; |
27 | |
28 | seq_printf(m: s, fmt: "Device name: %s\n" , dev_name(dev: pt->dev)); |
29 | seq_printf(m: s, fmt: " # Queues: %d\n" , 1); |
30 | seq_printf(m: s, fmt: " # Cmds: %d\n" , pt->cmd_count); |
31 | |
32 | regval = ioread32(pt->io_regs + CMD_PT_VERSION); |
33 | |
34 | seq_printf(m: s, fmt: " Version: %d\n" , regval & RI_VERSION_NUM); |
35 | seq_puts(m: s, s: " Engines:" ); |
36 | seq_puts(m: s, s: "\n" ); |
37 | seq_printf(m: s, fmt: " Queues: %d\n" , (regval & RI_NUM_VQM) >> RI_NVQM_SHIFT); |
38 | |
39 | return 0; |
40 | } |
41 | |
42 | /* |
43 | * Return a formatted buffer containing the current |
44 | * statistics of queue for PTDMA |
45 | */ |
46 | static int pt_debugfs_stats_show(struct seq_file *s, void *p) |
47 | { |
48 | struct pt_device *pt = s->private; |
49 | |
50 | seq_printf(m: s, fmt: "Total Interrupts Handled: %ld\n" , pt->total_interrupts); |
51 | |
52 | return 0; |
53 | } |
54 | |
55 | static int pt_debugfs_queue_show(struct seq_file *s, void *p) |
56 | { |
57 | struct pt_cmd_queue *cmd_q = s->private; |
58 | unsigned int regval; |
59 | |
60 | if (!cmd_q) |
61 | return 0; |
62 | |
63 | seq_printf(m: s, fmt: " Pass-Thru: %ld\n" , cmd_q->total_pt_ops); |
64 | |
65 | regval = ioread32(cmd_q->reg_control + 0x000C); |
66 | |
67 | seq_puts(m: s, s: " Enabled Interrupts:" ); |
68 | if (regval & INT_EMPTY_QUEUE) |
69 | seq_puts(m: s, s: " EMPTY" ); |
70 | if (regval & INT_QUEUE_STOPPED) |
71 | seq_puts(m: s, s: " STOPPED" ); |
72 | if (regval & INT_ERROR) |
73 | seq_puts(m: s, s: " ERROR" ); |
74 | if (regval & INT_COMPLETION) |
75 | seq_puts(m: s, s: " COMPLETION" ); |
76 | seq_puts(m: s, s: "\n" ); |
77 | |
78 | return 0; |
79 | } |
80 | |
81 | DEFINE_SHOW_ATTRIBUTE(pt_debugfs_info); |
82 | DEFINE_SHOW_ATTRIBUTE(pt_debugfs_queue); |
83 | DEFINE_SHOW_ATTRIBUTE(pt_debugfs_stats); |
84 | |
85 | void ptdma_debugfs_setup(struct pt_device *pt) |
86 | { |
87 | struct pt_cmd_queue *cmd_q; |
88 | struct dentry *debugfs_q_instance; |
89 | |
90 | if (!debugfs_initialized()) |
91 | return; |
92 | |
93 | debugfs_create_file(name: "info" , mode: 0400, parent: pt->dma_dev.dbg_dev_root, data: pt, |
94 | fops: &pt_debugfs_info_fops); |
95 | |
96 | debugfs_create_file(name: "stats" , mode: 0400, parent: pt->dma_dev.dbg_dev_root, data: pt, |
97 | fops: &pt_debugfs_stats_fops); |
98 | |
99 | cmd_q = &pt->cmd_q; |
100 | |
101 | debugfs_q_instance = |
102 | debugfs_create_dir(name: "q" , parent: pt->dma_dev.dbg_dev_root); |
103 | |
104 | debugfs_create_file(name: "stats" , mode: 0400, parent: debugfs_q_instance, data: cmd_q, |
105 | fops: &pt_debugfs_queue_fops); |
106 | } |
107 | |