2 * Qualcomm Technologies HIDMA debug file
4 * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 and
8 * only version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/debugfs.h>
17 #include <linux/device.h>
18 #include <linux/list.h>
19 #include <linux/pm_runtime.h>
23 static void hidma_ll_chstats(struct seq_file
*s
, void *llhndl
, u32 tre_ch
)
25 struct hidma_lldev
*lldev
= llhndl
;
26 struct hidma_tre
*tre
;
29 dma_addr_t dest_start
;
32 if (tre_ch
>= lldev
->nr_tres
) {
33 dev_err(lldev
->dev
, "invalid TRE number in chstats:%d", tre_ch
);
36 tre
= &lldev
->trepool
[tre_ch
];
37 seq_printf(s
, "------Channel %d -----\n", tre_ch
);
38 seq_printf(s
, "allocated=%d\n", atomic_read(&tre
->allocated
));
39 seq_printf(s
, "queued = 0x%x\n", tre
->queued
);
40 seq_printf(s
, "err_info = 0x%x\n", tre
->err_info
);
41 seq_printf(s
, "err_code = 0x%x\n", tre
->err_code
);
42 seq_printf(s
, "status = 0x%x\n", tre
->status
);
43 seq_printf(s
, "idx = 0x%x\n", tre
->idx
);
44 seq_printf(s
, "dma_sig = 0x%x\n", tre
->dma_sig
);
45 seq_printf(s
, "dev_name=%s\n", tre
->dev_name
);
46 seq_printf(s
, "callback=%p\n", tre
->callback
);
47 seq_printf(s
, "data=%p\n", tre
->data
);
48 seq_printf(s
, "tre_index = 0x%x\n", tre
->tre_index
);
50 tre_local
= &tre
->tre_local
[0];
51 src_start
= tre_local
[HIDMA_TRE_SRC_LOW_IDX
];
52 src_start
= ((u64
) (tre_local
[HIDMA_TRE_SRC_HI_IDX
]) << 32) + src_start
;
53 dest_start
= tre_local
[HIDMA_TRE_DEST_LOW_IDX
];
54 dest_start
+= ((u64
) (tre_local
[HIDMA_TRE_DEST_HI_IDX
]) << 32);
55 length
= tre_local
[HIDMA_TRE_LEN_IDX
];
57 seq_printf(s
, "src=%pap\n", &src_start
);
58 seq_printf(s
, "dest=%pap\n", &dest_start
);
59 seq_printf(s
, "length = 0x%x\n", length
);
62 static void hidma_ll_devstats(struct seq_file
*s
, void *llhndl
)
64 struct hidma_lldev
*lldev
= llhndl
;
66 seq_puts(s
, "------Device -----\n");
67 seq_printf(s
, "lldev init = 0x%x\n", lldev
->initialized
);
68 seq_printf(s
, "trch_state = 0x%x\n", lldev
->trch_state
);
69 seq_printf(s
, "evch_state = 0x%x\n", lldev
->evch_state
);
70 seq_printf(s
, "chidx = 0x%x\n", lldev
->chidx
);
71 seq_printf(s
, "nr_tres = 0x%x\n", lldev
->nr_tres
);
72 seq_printf(s
, "trca=%p\n", lldev
->trca
);
73 seq_printf(s
, "tre_ring=%p\n", lldev
->tre_ring
);
74 seq_printf(s
, "tre_ring_handle=%pap\n", &lldev
->tre_dma
);
75 seq_printf(s
, "tre_ring_size = 0x%x\n", lldev
->tre_ring_size
);
76 seq_printf(s
, "tre_processed_off = 0x%x\n", lldev
->tre_processed_off
);
77 seq_printf(s
, "pending_tre_count=%d\n",
78 atomic_read(&lldev
->pending_tre_count
));
79 seq_printf(s
, "evca=%p\n", lldev
->evca
);
80 seq_printf(s
, "evre_ring=%p\n", lldev
->evre_ring
);
81 seq_printf(s
, "evre_ring_handle=%pap\n", &lldev
->evre_dma
);
82 seq_printf(s
, "evre_ring_size = 0x%x\n", lldev
->evre_ring_size
);
83 seq_printf(s
, "evre_processed_off = 0x%x\n", lldev
->evre_processed_off
);
84 seq_printf(s
, "tre_write_offset = 0x%x\n", lldev
->tre_write_offset
);
88 * hidma_chan_stats: display HIDMA channel statistics
90 * Display the statistics for the current HIDMA virtual channel device.
92 static int hidma_chan_stats(struct seq_file
*s
, void *unused
)
94 struct hidma_chan
*mchan
= s
->private;
95 struct hidma_desc
*mdesc
;
96 struct hidma_dev
*dmadev
= mchan
->dmadev
;
98 pm_runtime_get_sync(dmadev
->ddev
.dev
);
99 seq_printf(s
, "paused=%u\n", mchan
->paused
);
100 seq_printf(s
, "dma_sig=%u\n", mchan
->dma_sig
);
101 seq_puts(s
, "prepared\n");
102 list_for_each_entry(mdesc
, &mchan
->prepared
, node
)
103 hidma_ll_chstats(s
, mchan
->dmadev
->lldev
, mdesc
->tre_ch
);
105 seq_puts(s
, "active\n");
106 list_for_each_entry(mdesc
, &mchan
->active
, node
)
107 hidma_ll_chstats(s
, mchan
->dmadev
->lldev
, mdesc
->tre_ch
);
109 seq_puts(s
, "completed\n");
110 list_for_each_entry(mdesc
, &mchan
->completed
, node
)
111 hidma_ll_chstats(s
, mchan
->dmadev
->lldev
, mdesc
->tre_ch
);
113 hidma_ll_devstats(s
, mchan
->dmadev
->lldev
);
114 pm_runtime_mark_last_busy(dmadev
->ddev
.dev
);
115 pm_runtime_put_autosuspend(dmadev
->ddev
.dev
);
120 * hidma_dma_info: display HIDMA device info
122 * Display the info for the current HIDMA device.
124 static int hidma_dma_info(struct seq_file
*s
, void *unused
)
126 struct hidma_dev
*dmadev
= s
->private;
129 seq_printf(s
, "nr_descriptors=%d\n", dmadev
->nr_descriptors
);
130 seq_printf(s
, "dev_trca=%p\n", &dmadev
->dev_trca
);
131 seq_printf(s
, "dev_trca_phys=%pa\n", &dmadev
->trca_resource
->start
);
132 sz
= resource_size(dmadev
->trca_resource
);
133 seq_printf(s
, "dev_trca_size=%pa\n", &sz
);
134 seq_printf(s
, "dev_evca=%p\n", &dmadev
->dev_evca
);
135 seq_printf(s
, "dev_evca_phys=%pa\n", &dmadev
->evca_resource
->start
);
136 sz
= resource_size(dmadev
->evca_resource
);
137 seq_printf(s
, "dev_evca_size=%pa\n", &sz
);
141 static int hidma_chan_stats_open(struct inode
*inode
, struct file
*file
)
143 return single_open(file
, hidma_chan_stats
, inode
->i_private
);
146 static int hidma_dma_info_open(struct inode
*inode
, struct file
*file
)
148 return single_open(file
, hidma_dma_info
, inode
->i_private
);
151 static const struct file_operations hidma_chan_fops
= {
152 .open
= hidma_chan_stats_open
,
155 .release
= single_release
,
158 static const struct file_operations hidma_dma_fops
= {
159 .open
= hidma_dma_info_open
,
162 .release
= single_release
,
165 void hidma_debug_uninit(struct hidma_dev
*dmadev
)
167 debugfs_remove_recursive(dmadev
->debugfs
);
170 int hidma_debug_init(struct hidma_dev
*dmadev
)
174 struct list_head
*position
= NULL
;
176 dmadev
->debugfs
= debugfs_create_dir(dev_name(dmadev
->ddev
.dev
), NULL
);
177 if (!dmadev
->debugfs
) {
182 /* walk through the virtual channel list */
183 list_for_each(position
, &dmadev
->ddev
.channels
) {
184 struct hidma_chan
*chan
;
186 chan
= list_entry(position
, struct hidma_chan
,
188 sprintf(chan
->dbg_name
, "chan%d", chidx
);
189 chan
->debugfs
= debugfs_create_dir(chan
->dbg_name
,
191 if (!chan
->debugfs
) {
195 chan
->stats
= debugfs_create_file("stats", S_IRUGO
,
205 dmadev
->stats
= debugfs_create_file("stats", S_IRUGO
,
206 dmadev
->debugfs
, dmadev
,
208 if (!dmadev
->stats
) {
215 hidma_debug_uninit(dmadev
);