linux/arch/blackfin/include/asm/dma.h
<<
>>
Prefs
   1/*
   2 * dma.h - Blackfin DMA defines/structures/etc...
   3 *
   4 * Copyright 2004-2008 Analog Devices Inc.
   5 * Licensed under the GPL-2 or later.
   6 */
   7
   8#ifndef _BLACKFIN_DMA_H_
   9#define _BLACKFIN_DMA_H_
  10
  11#include <linux/interrupt.h>
  12#include <mach/dma.h>
  13#include <asm/atomic.h>
  14#include <asm/blackfin.h>
  15#include <asm/page.h>
  16#include <asm-generic/dma.h>
  17#include <asm/bfin_dma.h>
  18
  19/*-------------------------
  20 * config reg bits value
  21 *-------------------------*/
  22#define DATA_SIZE_8                     0
  23#define DATA_SIZE_16            1
  24#define DATA_SIZE_32            2
  25
  26#define DMA_FLOW_STOP           0
  27#define DMA_FLOW_AUTO           1
  28#define DMA_FLOW_ARRAY          4
  29#define DMA_FLOW_SMALL          6
  30#define DMA_FLOW_LARGE          7
  31
  32#define DIMENSION_LINEAR        0
  33#define DIMENSION_2D            1
  34
  35#define DIR_READ                        0
  36#define DIR_WRITE                       1
  37
  38#define INTR_DISABLE            0
  39#define INTR_ON_BUF                     2
  40#define INTR_ON_ROW                     3
  41
  42#define DMA_NOSYNC_KEEP_DMA_BUF 0
  43#define DMA_SYNC_RESTART                1
  44
  45struct dmasg {
  46        void *next_desc_addr;
  47        unsigned long start_addr;
  48        unsigned short cfg;
  49        unsigned short x_count;
  50        short x_modify;
  51        unsigned short y_count;
  52        short y_modify;
  53} __attribute__((packed));
  54
  55struct dma_register {
  56        void *next_desc_ptr;    /* DMA Next Descriptor Pointer register */
  57        unsigned long start_addr;       /* DMA Start address  register */
  58
  59        unsigned short cfg;     /* DMA Configuration register */
  60        unsigned short dummy1;  /* DMA Configuration register */
  61
  62        unsigned long reserved;
  63
  64        unsigned short x_count; /* DMA x_count register */
  65        unsigned short dummy2;
  66
  67        short x_modify; /* DMA x_modify register */
  68        unsigned short dummy3;
  69
  70        unsigned short y_count; /* DMA y_count register */
  71        unsigned short dummy4;
  72
  73        short y_modify; /* DMA y_modify register */
  74        unsigned short dummy5;
  75
  76        void *curr_desc_ptr;    /* DMA Current Descriptor Pointer
  77                                           register */
  78        unsigned long curr_addr_ptr;    /* DMA Current Address Pointer
  79                                                   register */
  80        unsigned short irq_status;      /* DMA irq status register */
  81        unsigned short dummy6;
  82
  83        unsigned short peripheral_map;  /* DMA peripheral map register */
  84        unsigned short dummy7;
  85
  86        unsigned short curr_x_count;    /* DMA Current x-count register */
  87        unsigned short dummy8;
  88
  89        unsigned long reserved2;
  90
  91        unsigned short curr_y_count;    /* DMA Current y-count register */
  92        unsigned short dummy9;
  93
  94        unsigned long reserved3;
  95
  96};
  97
  98struct dma_channel {
  99        const char *device_id;
 100        atomic_t chan_status;
 101        volatile struct dma_register *regs;
 102        struct dmasg *sg;               /* large mode descriptor */
 103        unsigned int irq;
 104        void *data;
 105#ifdef CONFIG_PM
 106        unsigned short saved_peripheral_map;
 107#endif
 108};
 109
 110#ifdef CONFIG_PM
 111int blackfin_dma_suspend(void);
 112void blackfin_dma_resume(void);
 113#endif
 114
 115/*******************************************************************************
 116*       DMA API's
 117*******************************************************************************/
 118extern struct dma_channel dma_ch[MAX_DMA_CHANNELS];
 119extern struct dma_register * const dma_io_base_addr[MAX_DMA_CHANNELS];
 120extern int channel2irq(unsigned int channel);
 121
 122static inline void set_dma_start_addr(unsigned int channel, unsigned long addr)
 123{
 124        dma_ch[channel].regs->start_addr = addr;
 125}
 126static inline void set_dma_next_desc_addr(unsigned int channel, void *addr)
 127{
 128        dma_ch[channel].regs->next_desc_ptr = addr;
 129}
 130static inline void set_dma_curr_desc_addr(unsigned int channel, void *addr)
 131{
 132        dma_ch[channel].regs->curr_desc_ptr = addr;
 133}
 134static inline void set_dma_x_count(unsigned int channel, unsigned short x_count)
 135{
 136        dma_ch[channel].regs->x_count = x_count;
 137}
 138static inline void set_dma_y_count(unsigned int channel, unsigned short y_count)
 139{
 140        dma_ch[channel].regs->y_count = y_count;
 141}
 142static inline void set_dma_x_modify(unsigned int channel, short x_modify)
 143{
 144        dma_ch[channel].regs->x_modify = x_modify;
 145}
 146static inline void set_dma_y_modify(unsigned int channel, short y_modify)
 147{
 148        dma_ch[channel].regs->y_modify = y_modify;
 149}
 150static inline void set_dma_config(unsigned int channel, unsigned short config)
 151{
 152        dma_ch[channel].regs->cfg = config;
 153}
 154static inline void set_dma_curr_addr(unsigned int channel, unsigned long addr)
 155{
 156        dma_ch[channel].regs->curr_addr_ptr = addr;
 157}
 158
 159static inline unsigned short
 160set_bfin_dma_config(char direction, char flow_mode,
 161                    char intr_mode, char dma_mode, char width, char syncmode)
 162{
 163        return (direction << 1) | (width << 2) | (dma_mode << 4) |
 164                (intr_mode << 6) | (flow_mode << 12) | (syncmode << 5);
 165}
 166
 167static inline unsigned short get_dma_curr_irqstat(unsigned int channel)
 168{
 169        return dma_ch[channel].regs->irq_status;
 170}
 171static inline unsigned short get_dma_curr_xcount(unsigned int channel)
 172{
 173        return dma_ch[channel].regs->curr_x_count;
 174}
 175static inline unsigned short get_dma_curr_ycount(unsigned int channel)
 176{
 177        return dma_ch[channel].regs->curr_y_count;
 178}
 179static inline void *get_dma_next_desc_ptr(unsigned int channel)
 180{
 181        return dma_ch[channel].regs->next_desc_ptr;
 182}
 183static inline void *get_dma_curr_desc_ptr(unsigned int channel)
 184{
 185        return dma_ch[channel].regs->curr_desc_ptr;
 186}
 187static inline unsigned short get_dma_config(unsigned int channel)
 188{
 189        return dma_ch[channel].regs->cfg;
 190}
 191static inline unsigned long get_dma_curr_addr(unsigned int channel)
 192{
 193        return dma_ch[channel].regs->curr_addr_ptr;
 194}
 195
 196static inline void set_dma_sg(unsigned int channel, struct dmasg *sg, int ndsize)
 197{
 198        /* Make sure the internal data buffers in the core are drained
 199         * so that the DMA descriptors are completely written when the
 200         * DMA engine goes to fetch them below.
 201         */
 202        SSYNC();
 203
 204        dma_ch[channel].regs->next_desc_ptr = sg;
 205        dma_ch[channel].regs->cfg =
 206                (dma_ch[channel].regs->cfg & ~(0xf << 8)) |
 207                ((ndsize & 0xf) << 8);
 208}
 209
 210static inline int dma_channel_active(unsigned int channel)
 211{
 212        return atomic_read(&dma_ch[channel].chan_status);
 213}
 214
 215static inline void disable_dma(unsigned int channel)
 216{
 217        dma_ch[channel].regs->cfg &= ~DMAEN;
 218        SSYNC();
 219}
 220static inline void enable_dma(unsigned int channel)
 221{
 222        dma_ch[channel].regs->curr_x_count = 0;
 223        dma_ch[channel].regs->curr_y_count = 0;
 224        dma_ch[channel].regs->cfg |= DMAEN;
 225}
 226int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data);
 227
 228static inline void dma_disable_irq(unsigned int channel)
 229{
 230        disable_irq(dma_ch[channel].irq);
 231}
 232static inline void dma_disable_irq_nosync(unsigned int channel)
 233{
 234        disable_irq_nosync(dma_ch[channel].irq);
 235}
 236static inline void dma_enable_irq(unsigned int channel)
 237{
 238        enable_irq(dma_ch[channel].irq);
 239}
 240static inline void clear_dma_irqstat(unsigned int channel)
 241{
 242        dma_ch[channel].regs->irq_status = DMA_DONE | DMA_ERR;
 243}
 244
 245void *dma_memcpy(void *dest, const void *src, size_t count);
 246void *dma_memcpy_nocache(void *dest, const void *src, size_t count);
 247void *safe_dma_memcpy(void *dest, const void *src, size_t count);
 248void blackfin_dma_early_init(void);
 249void early_dma_memcpy(void *dest, const void *src, size_t count);
 250void early_dma_memcpy_done(void);
 251
 252#endif
 253