15 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include <linux/kernel.h>
20 #include <linux/errno.h>
24 #include <asm/memory.h>
25 #include <mach/hardware.h>
28 #define DMA_DEBUG_NAME "pxa_dma"
29 #define DMA_MAX_REQUESTERS 64
40 static int num_dma_channels;
45 #ifdef CONFIG_DEBUG_FS
50 static struct dentry *dbgfs_root, *dbgfs_state, **dbgfs_chan;
52 static int dbg_show_requester_chan(
struct seq_file *
s,
void *
p)
59 pos +=
seq_printf(s,
"DMA channel %d requesters list :\n", chan);
63 pos +=
seq_printf(s,
"\tRequester %d (MAPVLD=%d)\n",
i,
69 static inline int dbg_burst_from_dcmd(
u32 dcmd)
71 int burst = (dcmd >> 16) & 0x3;
73 return burst ? 4 << burst : 0;
76 static int is_phys_valid(
unsigned long addr)
81 #define DCSR_STR(flag) (dcsr & DCSR_##flag ? #flag" " : "")
82 #define DCMD_STR(flag) (dcmd & DCMD_##flag ? #flag" " : "")
84 static int dbg_show_descriptors(
struct seq_file *
s,
void *
p)
88 int i, max_show = 20, burst,
width;
90 unsigned long phys_desc;
95 phys_desc =
DDADR(chan);
97 pos +=
seq_printf(s,
"DMA channel %d descriptors :\n", chan);
98 pos +=
seq_printf(s,
"[%03d] First descriptor unknown\n", 0);
99 for (i = 1; i < max_show && is_phys_valid(phys_desc); i++) {
102 burst = dbg_burst_from_dcmd(
dcmd);
103 width = (1 << ((
dcmd >> 14) & 0x3)) >> 1;
105 pos +=
seq_printf(s,
"[%03d] Desc at %08lx(virt %p)\n",
110 pos +=
seq_printf(s,
"\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d"
111 " width=%d len=%d)\n",
113 DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
114 DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
115 DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
118 phys_desc =
desc->ddadr;
121 pos +=
seq_printf(s,
"[%03d] Desc at %08lx ... max display reached\n",
124 pos +=
seq_printf(s,
"[%03d] Desc at %08lx is %s\n",
126 "DDADR_STOP" :
"invalid");
128 spin_unlock_irqrestore(&dma_channels[chan].lock,
flags);
132 static int dbg_show_chan_state(
struct seq_file *s,
void *p)
138 static char *str_prio[] = {
"high",
"normal",
"low" };
142 burst = dbg_burst_from_dcmd(
dcmd);
143 width = (1 << ((
dcmd >> 14) & 0x3)) >> 1;
145 pos +=
seq_printf(s,
"DMA channel %d\n", chan);
147 str_prio[dma_channels[chan].
prio]);
148 pos +=
seq_printf(s,
"\tUnaligned transfer bit: %s\n",
149 DALGN & (1 << chan) ?
"yes" :
"no");
150 pos +=
seq_printf(s,
"\tDCSR = %08x (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
151 dcsr, DCSR_STR(
RUN), DCSR_STR(NODESC),
152 DCSR_STR(STOPIRQEN), DCSR_STR(EORIRQEN),
153 DCSR_STR(EORJMPEN), DCSR_STR(EORSTOPEN),
154 DCSR_STR(SETCMPST), DCSR_STR(CLRCMPST),
155 DCSR_STR(CMPST), DCSR_STR(EORINTR), DCSR_STR(REQPEND),
156 DCSR_STR(STOPSTATE), DCSR_STR(ENDINTR),
157 DCSR_STR(STARTINTR), DCSR_STR(BUSERR));
159 pos +=
seq_printf(s,
"\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d"
162 DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR),
163 DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG),
164 DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN),
172 static int dbg_show_state(
struct seq_file *s,
void *p)
178 pos +=
seq_printf(s,
"\tChannel number: %d\n", num_dma_channels);
183 #define DBGFS_FUNC_DECL(name) \
184 static int dbg_open_##name(struct inode *inode, struct file *file) \
186 return single_open(file, dbg_show_##name, inode->i_private); \
188 static const struct file_operations dbg_fops_##name = { \
189 .owner = THIS_MODULE, \
190 .open = dbg_open_##name, \
191 .llseek = seq_lseek, \
193 .release = single_release, \
196 DBGFS_FUNC_DECL(
state);
197 DBGFS_FUNC_DECL(chan_state);
199 DBGFS_FUNC_DECL(requester_chan);
201 static struct dentry *pxa_dma_dbg_alloc_chan(
int ch,
struct dentry *chandir)
208 scnprintf(chan_name,
sizeof(chan_name),
"%d", ch);
214 &dbg_fops_chan_state);
217 &dbg_fops_descriptors);
220 &dbg_fops_requester_chan);
231 static void pxa_dma_init_debugfs(
void)
237 if (IS_ERR(dbgfs_root) || !dbgfs_root)
245 dbgfs_chan =
kmalloc(
sizeof(*dbgfs_state) * num_dma_channels,
254 for (i = 0; i < num_dma_channels; i++) {
255 dbgfs_chan[
i] = pxa_dma_dbg_alloc_chan(i, chandir);
268 pr_err(
"pxa_dma: debugfs is not available\n");
271 static void __exit pxa_dma_cleanup_debugfs(
void)
276 static inline void pxa_dma_init_debugfs(
void) {}
277 static inline void pxa_dma_cleanup_debugfs(
void) {}
295 for (i = 0; i < num_dma_channels; i++) {
296 if ((dma_channels[i].prio == prio) &&
297 !dma_channels[i].name) {
303 }
while (!found && prio--);
324 if (!dma_channels[dma_ch].name) {
326 "%s: trying to free channel %d which is already freed\n",
346 channel = &dma_channels[
i];
366 if (dma_channels ==
NULL)
374 for (i = 0; i < num_ch; i++) {
386 num_dma_channels = num_ch;
388 pxa_dma_init_debugfs();