linux/arch/arm/plat-pxa/dma.c
<<
>>
Prefs
   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