Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | /* arch/arm/mach-s3c2410/include/mach/dma.h
*
* Copyright (C) 2003-2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* Samsung S3C24XX DMA support
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__
#include <linux/device.h>
#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
/* We use `virtual` dma channels to hide the fact we have only a limited
* number of DMA channels, and not of all of them (dependent on the device)
* can be attached to any DMA source. We therefore let the DMA core handle
* the allocation of hardware channels to clients.
*/
enum dma_ch {
DMACH_XD0 = 0,
DMACH_XD1,
DMACH_SDI,
DMACH_SPI0,
DMACH_SPI1,
DMACH_UART0,
DMACH_UART1,
DMACH_UART2,
DMACH_TIMER,
DMACH_I2S_IN,
DMACH_I2S_OUT,
DMACH_PCM_IN,
DMACH_PCM_OUT,
DMACH_MIC_IN,
DMACH_USB_EP1,
DMACH_USB_EP2,
DMACH_USB_EP3,
DMACH_USB_EP4,
DMACH_UART0_SRC2, /* s3c2412 second uart sources */
DMACH_UART1_SRC2,
DMACH_UART2_SRC2,
DMACH_UART3, /* s3c2443 has extra uart */
DMACH_UART3_SRC2,
DMACH_SPI0_TX, /* s3c2443/2416/2450 hsspi0 */
DMACH_SPI0_RX, /* s3c2443/2416/2450 hsspi0 */
DMACH_SPI1_TX, /* s3c2443/2450 hsspi1 */
DMACH_SPI1_RX, /* s3c2443/2450 hsspi1 */
DMACH_MAX, /* the end entry */
};
static inline bool samsung_dma_has_circular(void)
{
return false;
}
static inline bool samsung_dma_is_dmadev(void)
{
return false;
}
#include <plat/dma.h>
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
/* we have 4 dma channels */
#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
#define S3C_DMA_CHANNELS (4)
#else
#define S3C_DMA_CHANNELS (6)
#endif
/* types */
enum s3c2410_dma_state {
S3C2410_DMA_IDLE,
S3C2410_DMA_RUNNING,
S3C2410_DMA_PAUSED
};
/* enum s3c2410_dma_loadst
*
* This represents the state of the DMA engine, wrt to the loaded / running
* transfers. Since we don't have any way of knowing exactly the state of
* the DMA transfers, we need to know the state to make decisions on whether
* we can
*
* S3C2410_DMA_NONE
*
* There are no buffers loaded (the channel should be inactive)
*
* S3C2410_DMA_1LOADED
*
* There is one buffer loaded, however it has not been confirmed to be
* loaded by the DMA engine. This may be because the channel is not
* yet running, or the DMA driver decided that it was too costly to
* sit and wait for it to happen.
*
* S3C2410_DMA_1RUNNING
*
* The buffer has been confirmed running, and not finisged
*
* S3C2410_DMA_1LOADED_1RUNNING
*
* There is a buffer waiting to be loaded by the DMA engine, and one
* currently running.
*/
enum s3c2410_dma_loadst {
S3C2410_DMALOAD_NONE,
S3C2410_DMALOAD_1LOADED,
S3C2410_DMALOAD_1RUNNING,
S3C2410_DMALOAD_1LOADED_1RUNNING,
};
/* flags */
#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about
* waiting for reloads */
#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
/* dma buffer */
struct s3c2410_dma_buf;
/* s3c2410_dma_buf
*
* internally used buffer structure to describe a queued or running
* buffer.
*/
struct s3c2410_dma_buf {
struct s3c2410_dma_buf *next;
int magic; /* magic */
int size; /* buffer size in bytes */
dma_addr_t data; /* start of DMA data */
dma_addr_t ptr; /* where the DMA got to [1] */
void *id; /* client's id */
};
/* [1] is this updated for both recv/send modes? */
struct s3c2410_dma_stats {
unsigned long loads;
unsigned long timeout_longest;
unsigned long timeout_shortest;
unsigned long timeout_avg;
unsigned long timeout_failed;
};
struct s3c2410_dma_map;
/* struct s3c2410_dma_chan
*
* full state information for each DMA channel
*/
struct s3c2410_dma_chan {
/* channel state flags and information */
unsigned char number; /* number of this dma channel */
unsigned char in_use; /* channel allocated */
unsigned char irq_claimed; /* irq claimed for channel */
unsigned char irq_enabled; /* irq enabled for channel */
unsigned char xfer_unit; /* size of an transfer */
/* channel state */
enum s3c2410_dma_state state;
enum s3c2410_dma_loadst load_state;
struct s3c2410_dma_client *client;
/* channel configuration */
enum dma_data_direction source;
enum dma_ch req_ch;
unsigned long dev_addr;
unsigned long load_timeout;
unsigned int flags; /* channel flags */
struct s3c24xx_dma_map *map; /* channel hw maps */
/* channel's hardware position and configuration */
void __iomem *regs; /* channels registers */
void __iomem *addr_reg; /* data address register */
unsigned int irq; /* channel irq */
unsigned long dcon; /* default value of DCON */
/* driver handles */
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
s3c2410_dma_opfn_t op_fn; /* channel op callback */
/* stats gathering */
struct s3c2410_dma_stats *stats;
struct s3c2410_dma_stats stats_store;
/* buffer list and information */
struct s3c2410_dma_buf *curr; /* current dma buffer */
struct s3c2410_dma_buf *next; /* next buffer to load */
struct s3c2410_dma_buf *end; /* end of queue */
/* system device */
struct device dev;
};
typedef unsigned long dma_device_t;
#endif /* __ASM_ARCH_DMA_H */
|