1/* 2 * linux/arch/arm/plat-pxa/dma.c 3 * 4 * PXA DMA registration and IRQ dispatching 5 * 6 * Author: Nicolas Pitre 7 * Created: Nov 15, 2001 8 * Copyright: MontaVista Software Inc. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/module.h> 16#include <linux/init.h> 17#include <linux/slab.h> 18#include <linux/kernel.h> 19#include <linux/interrupt.h> 20#include <linux/errno.h> 21#include <linux/dma-mapping.h> 22 23#include <asm/irq.h> 24#include <asm/memory.h> 25#include <mach/hardware.h> 26#include <mach/dma.h> 27 28#define DMA_DEBUG_NAME "pxa_dma" 29#define DMA_MAX_REQUESTERS 64 30 31struct dma_channel { 32 char *name; 33 pxa_dma_prio prio; 34 void (*irq_handler)(int, void *); 35 void *data; 36 spinlock_t lock; 37}; 38 39static struct dma_channel *dma_channels; 40static int num_dma_channels; 41 42/* 43 * Debug fs 44 */ 45#ifdef CONFIG_DEBUG_FS 46#include <linux/debugfs.h> 47#include <linux/uaccess.h> 48#include <linux/seq_file.h> 49 50static struct dentry *dbgfs_root, *dbgfs_state, **dbgfs_chan; 51 52static int dbg_show_requester_chan(struct seq_file *s, void *p) 53{ 54 int chan = (int)s->private; 55 int i; 56 u32 drcmr; 57 58 seq_printf(s, "DMA channel %d requesters list :\n", chan); 59 for (i = 0; i < DMA_MAX_REQUESTERS; i++) { 60 drcmr = DRCMR(i); 61 if ((drcmr & DRCMR_CHLNUM) == chan) 62 seq_printf(s, "\tRequester %d (MAPVLD=%d)\n", 63 i, !!(drcmr & DRCMR_MAPVLD)); 64 } 65 66 return 0; 67} 68 69static inline int dbg_burst_from_dcmd(u32 dcmd) 70{ 71 int burst = (dcmd >> 16) & 0x3; 72 73 return burst ? 4 << burst : 0; 74} 75 76static int is_phys_valid(unsigned long addr) 77{ 78 return pfn_valid(__phys_to_pfn(addr)); 79} 80 81#define DCSR_STR(flag) (dcsr & DCSR_##flag ? #flag" " : "") 82#define DCMD_STR(flag) (dcmd & DCMD_##flag ? #flag" " : "") 83 84static int dbg_show_descriptors(struct seq_file *s, void *p) 85{ 86 int chan = (int)s->private; 87 int i, max_show = 20, burst, width; 88 u32 dcmd; 89 unsigned long phys_desc; 90 struct pxa_dma_desc *desc; 91 unsigned long flags; 92 93 spin_lock_irqsave(&dma_channels[chan].lock, flags); 94 phys_desc = DDADR(chan); 95 96 seq_printf(s, "DMA channel %d descriptors :\n", chan); 97 seq_printf(s, "[%03d] First descriptor unknown\n", 0); 98 for (i = 1; i < max_show && is_phys_valid(phys_desc); i++) { 99 desc = phys_to_virt(phys_desc); 100 dcmd = desc->dcmd; 101 burst = dbg_burst_from_dcmd(dcmd); 102 width = (1 << ((dcmd >> 14) & 0x3)) >> 1; 103 104 seq_printf(s, "[%03d] Desc at %08lx(virt %p)\n", 105 i, phys_desc, desc); 106 seq_printf(s, "\tDDADR = %08x\n", desc->ddadr); 107 seq_printf(s, "\tDSADR = %08x\n", desc->dsadr); 108 seq_printf(s, "\tDTADR = %08x\n", desc->dtadr); 109 seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d len=%d)\n", 110 dcmd, 111 DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR), 112 DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG), 113 DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN), 114 DCMD_STR(ENDIAN), burst, width, 115 dcmd & DCMD_LENGTH); 116 phys_desc = desc->ddadr; 117 } 118 if (i == max_show) 119 seq_printf(s, "[%03d] Desc at %08lx ... max display reached\n", 120 i, phys_desc); 121 else 122 seq_printf(s, "[%03d] Desc at %08lx is %s\n", 123 i, phys_desc, phys_desc == DDADR_STOP ? 124 "DDADR_STOP" : "invalid"); 125 126 spin_unlock_irqrestore(&dma_channels[chan].lock, flags); 127 128 return 0; 129} 130 131static int dbg_show_chan_state(struct seq_file *s, void *p) 132{ 133 int chan = (int)s->private; 134 u32 dcsr, dcmd; 135 int burst, width; 136 static char *str_prio[] = { "high", "normal", "low" }; 137 138 dcsr = DCSR(chan); 139 dcmd = DCMD(chan); 140 burst = dbg_burst_from_dcmd(dcmd); 141 width = (1 << ((dcmd >> 14) & 0x3)) >> 1; 142 143 seq_printf(s, "DMA channel %d\n", chan); 144 seq_printf(s, "\tPriority : %s\n", str_prio[dma_channels[chan].prio]); 145 seq_printf(s, "\tUnaligned transfer bit: %s\n", 146 DALGN & (1 << chan) ? "yes" : "no"); 147 seq_printf(s, "\tDCSR = %08x (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n", 148 dcsr, DCSR_STR(RUN), DCSR_STR(NODESC), 149 DCSR_STR(STOPIRQEN), DCSR_STR(EORIRQEN), 150 DCSR_STR(EORJMPEN), DCSR_STR(EORSTOPEN), 151 DCSR_STR(SETCMPST), DCSR_STR(CLRCMPST), 152 DCSR_STR(CMPST), DCSR_STR(EORINTR), DCSR_STR(REQPEND), 153 DCSR_STR(STOPSTATE), DCSR_STR(ENDINTR), 154 DCSR_STR(STARTINTR), DCSR_STR(BUSERR)); 155 156 seq_printf(s, "\tDCMD = %08x (%s%s%s%s%s%s%sburst=%d width=%d len=%d)\n", 157 dcmd, 158 DCMD_STR(INCSRCADDR), DCMD_STR(INCTRGADDR), 159 DCMD_STR(FLOWSRC), DCMD_STR(FLOWTRG), 160 DCMD_STR(STARTIRQEN), DCMD_STR(ENDIRQEN), 161 DCMD_STR(ENDIAN), burst, width, dcmd & DCMD_LENGTH); 162 seq_printf(s, "\tDSADR = %08x\n", DSADR(chan)); 163 seq_printf(s, "\tDTADR = %08x\n", DTADR(chan)); 164 seq_printf(s, "\tDDADR = %08x\n", DDADR(chan)); 165 166 return 0; 167} 168 169static int dbg_show_state(struct seq_file *s, void *p) 170{ 171 /* basic device status */ 172 seq_puts(s, "DMA engine status\n"); 173 seq_printf(s, "\tChannel number: %d\n", num_dma_channels); 174 175 return 0; 176} 177 178#define DBGFS_FUNC_DECL(name) \ 179static int dbg_open_##name(struct inode *inode, struct file *file) \ 180{ \ 181 return single_open(file, dbg_show_##name, inode->i_private); \ 182} \ 183static const struct file_operations dbg_fops_##name = { \ 184 .owner = THIS_MODULE, \ 185 .open = dbg_open_##name, \ 186 .llseek = seq_lseek, \ 187 .read = seq_read, \ 188 .release = single_release, \ 189} 190 191DBGFS_FUNC_DECL(state); 192DBGFS_FUNC_DECL(chan_state); 193DBGFS_FUNC_DECL(descriptors); 194DBGFS_FUNC_DECL(requester_chan); 195 196static struct dentry *pxa_dma_dbg_alloc_chan(int ch, struct dentry *chandir) 197{ 198 char chan_name[11]; 199 struct dentry *chan, *chan_state = NULL, *chan_descr = NULL; 200 struct dentry *chan_reqs = NULL; 201 void *dt; 202 203 scnprintf(chan_name, sizeof(chan_name), "%d", ch); 204 chan = debugfs_create_dir(chan_name, chandir); 205 dt = (void *)ch; 206 207 if (chan) 208 chan_state = debugfs_create_file("state", 0400, chan, dt, 209 &dbg_fops_chan_state); 210 if (chan_state) 211 chan_descr = debugfs_create_file("descriptors", 0400, chan, dt, 212 &dbg_fops_descriptors); 213 if (chan_descr) 214 chan_reqs = debugfs_create_file("requesters", 0400, chan, dt, 215 &dbg_fops_requester_chan); 216 if (!chan_reqs) 217 goto err_state; 218 219 return chan; 220 221err_state: 222 debugfs_remove_recursive(chan); 223 return NULL; 224} 225 226static void pxa_dma_init_debugfs(void) 227{ 228 int i; 229 struct dentry *chandir; 230 231 dbgfs_root = debugfs_create_dir(DMA_DEBUG_NAME, NULL); 232 if (IS_ERR(dbgfs_root) || !dbgfs_root) 233 goto err_root; 234 235 dbgfs_state = debugfs_create_file("state", 0400, dbgfs_root, NULL, 236 &dbg_fops_state); 237 if (!dbgfs_state) 238 goto err_state; 239 240 dbgfs_chan = kmalloc(sizeof(*dbgfs_state) * num_dma_channels, 241 GFP_KERNEL); 242 if (!dbgfs_chan) 243 goto err_alloc; 244 245 chandir = debugfs_create_dir("channels", dbgfs_root); 246 if (!chandir) 247 goto err_chandir; 248 249 for (i = 0; i < num_dma_channels; i++) { 250 dbgfs_chan[i] = pxa_dma_dbg_alloc_chan(i, chandir); 251 if (!dbgfs_chan[i]) 252 goto err_chans; 253 } 254 255 return; 256err_chans: 257err_chandir: 258 kfree(dbgfs_chan); 259err_alloc: 260err_state: 261 debugfs_remove_recursive(dbgfs_root); 262err_root: 263 pr_err("pxa_dma: debugfs is not available\n"); 264} 265 266static void __exit pxa_dma_cleanup_debugfs(void) 267{ 268 debugfs_remove_recursive(dbgfs_root); 269} 270#else 271static inline void pxa_dma_init_debugfs(void) {} 272static inline void pxa_dma_cleanup_debugfs(void) {} 273#endif 274 275int pxa_request_dma (char *name, pxa_dma_prio prio, 276 void (*irq_handler)(int, void *), 277 void *data) 278{ 279 unsigned long flags; 280 int i, found = 0; 281 282 /* basic sanity checks */ 283 if (!name || !irq_handler) 284 return -EINVAL; 285 286 local_irq_save(flags); 287 288 do { 289 /* try grabbing a DMA channel with the requested priority */ 290 for (i = 0; i < num_dma_channels; i++) { 291 if ((dma_channels[i].prio == prio) && 292 !dma_channels[i].name && 293 !pxad_toggle_reserved_channel(i)) { 294 found = 1; 295 break; 296 } 297 } 298 /* if requested prio group is full, try a hier priority */ 299 } while (!found && prio--); 300 301 if (found) { 302 DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; 303 dma_channels[i].name = name; 304 dma_channels[i].irq_handler = irq_handler; 305 dma_channels[i].data = data; 306 } else { 307 printk (KERN_WARNING "No more available DMA channels for %s\n", name); 308 i = -ENODEV; 309 } 310 311 local_irq_restore(flags); 312 return i; 313} 314EXPORT_SYMBOL(pxa_request_dma); 315 316void pxa_free_dma (int dma_ch) 317{ 318 unsigned long flags; 319 320 if (!dma_channels[dma_ch].name) { 321 printk (KERN_CRIT 322 "%s: trying to free channel %d which is already freed\n", 323 __func__, dma_ch); 324 return; 325 } 326 327 local_irq_save(flags); 328 DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; 329 dma_channels[dma_ch].name = NULL; 330 pxad_toggle_reserved_channel(dma_ch); 331 local_irq_restore(flags); 332} 333EXPORT_SYMBOL(pxa_free_dma); 334 335static irqreturn_t dma_irq_handler(int irq, void *dev_id) 336{ 337 int i, dint = DINT, done = 0; 338 struct dma_channel *channel; 339 340 while (dint) { 341 i = __ffs(dint); 342 dint &= (dint - 1); 343 channel = &dma_channels[i]; 344 if (channel->name && channel->irq_handler) { 345 channel->irq_handler(i, channel->data); 346 done++; 347 } 348 } 349 if (done) 350 return IRQ_HANDLED; 351 else 352 return IRQ_NONE; 353} 354 355int __init pxa_init_dma(int irq, int num_ch) 356{ 357 int i, ret; 358 359 dma_channels = kzalloc(sizeof(struct dma_channel) * num_ch, GFP_KERNEL); 360 if (dma_channels == NULL) 361 return -ENOMEM; 362 363 /* dma channel priorities on pxa2xx processors: 364 * ch 0 - 3, 16 - 19 <--> (0) DMA_PRIO_HIGH 365 * ch 4 - 7, 20 - 23 <--> (1) DMA_PRIO_MEDIUM 366 * ch 8 - 15, 24 - 31 <--> (2) DMA_PRIO_LOW 367 */ 368 for (i = 0; i < num_ch; i++) { 369 DCSR(i) = 0; 370 dma_channels[i].prio = min((i & 0xf) >> 2, DMA_PRIO_LOW); 371 spin_lock_init(&dma_channels[i].lock); 372 } 373 374 ret = request_irq(irq, dma_irq_handler, IRQF_SHARED, "DMA", 375 dma_channels); 376 if (ret) { 377 printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); 378 kfree(dma_channels); 379 return ret; 380 } 381 num_dma_channels = num_ch; 382 383 pxa_dma_init_debugfs(); 384 385 return 0; 386} 387