au1xxx_dbdma.h 13.3 KB
Newer Older
L
Linus Torvalds 已提交
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
/*
 *
 * BRIEF MODULE DESCRIPTION
 *	Include file for Alchemy Semiconductor's Au1550 Descriptor
 *	Based DMA Controller.
 *
 * Copyright 2004 Embedded Edge, LLC
 *	dan@embeddededge.com
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 *
 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  You should have received a copy of the  GNU General Public License along
 *  with this program; if not, write  to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

31 32 33
/*
 * Specifics for the Au1xxx Descriptor-Based DMA Controller,
 * first seen in the AU1550 part.
L
Linus Torvalds 已提交
34 35 36 37 38 39
 */
#ifndef _AU1000_DBDMA_H_
#define _AU1000_DBDMA_H_

#ifndef _LANGUAGE_ASSEMBLY

P
Pete Popov 已提交
40
typedef volatile struct dbdma_global {
L
Linus Torvalds 已提交
41 42 43 44 45 46
	u32	ddma_config;
	u32	ddma_intstat;
	u32	ddma_throttle;
	u32	ddma_inten;
} dbdma_global_t;

47
/* General Configuration. */
L
Linus Torvalds 已提交
48 49 50 51 52 53
#define DDMA_CONFIG_AF		(1 << 2)
#define DDMA_CONFIG_AH		(1 << 1)
#define DDMA_CONFIG_AL		(1 << 0)

#define DDMA_THROTTLE_EN	(1 << 31)

54
/* The structure of a DMA Channel. */
P
Pete Popov 已提交
55
typedef volatile struct au1xxx_dma_channel {
L
Linus Torvalds 已提交
56 57 58 59 60 61 62
	u32	ddma_cfg;	/* See below */
	u32	ddma_desptr;	/* 32-byte aligned pointer to descriptor */
	u32	ddma_statptr;	/* word aligned pointer to status word */
	u32	ddma_dbell;	/* A write activates channel operation */
	u32	ddma_irq;	/* If bit 0 set, interrupt pending */
	u32	ddma_stat;	/* See below */
	u32	ddma_bytecnt;	/* Byte count, valid only when chan idle */
63
	/* Remainder, up to the 256 byte boundary, is reserved. */
L
Linus Torvalds 已提交
64 65 66 67 68 69 70 71 72 73 74 75 76
} au1x_dma_chan_t;

#define DDMA_CFG_SED	(1 << 9)	/* source DMA level/edge detect */
#define DDMA_CFG_SP	(1 << 8)	/* source DMA polarity */
#define DDMA_CFG_DED	(1 << 7)	/* destination DMA level/edge detect */
#define DDMA_CFG_DP	(1 << 6)	/* destination DMA polarity */
#define DDMA_CFG_SYNC	(1 << 5)	/* Sync static bus controller */
#define DDMA_CFG_PPR	(1 << 4)	/* PCI posted read/write control */
#define DDMA_CFG_DFN	(1 << 3)	/* Descriptor fetch non-coherent */
#define DDMA_CFG_SBE	(1 << 2)	/* Source big endian */
#define DDMA_CFG_DBE	(1 << 1)	/* Destination big endian */
#define DDMA_CFG_EN	(1 << 0)	/* Channel enable */

77 78
/*
 * Always set when descriptor processing done, regardless of
L
Linus Torvalds 已提交
79 80 81 82 83 84 85 86 87
 * interrupt enable state.  Reflected in global intstat, don't
 * clear this until global intstat is read/used.
 */
#define DDMA_IRQ_IN	(1 << 0)

#define DDMA_STAT_DB	(1 << 2)	/* Doorbell pushed */
#define DDMA_STAT_V	(1 << 1)	/* Descriptor valid */
#define DDMA_STAT_H	(1 << 0)	/* Channel Halted */

88 89
/*
 * "Standard" DDMA Descriptor.
L
Linus Torvalds 已提交
90 91
 * Must be 32-byte aligned.
 */
P
Pete Popov 已提交
92
typedef volatile struct au1xxx_ddma_desc {
L
Linus Torvalds 已提交
93 94 95 96 97 98 99 100
	u32	dscr_cmd0;		/* See below */
	u32	dscr_cmd1;		/* See below */
	u32	dscr_source0;		/* source phys address */
	u32	dscr_source1;		/* See below */
	u32	dscr_dest0;		/* Destination address */
	u32	dscr_dest1;		/* See below */
	u32	dscr_stat;		/* completion status */
	u32	dscr_nxtptr;		/* Next descriptor pointer (mostly) */
101 102 103
	/*
	 * First 32 bytes are HW specific!!!
	 * Lets have some SW data following -- make sure it's 32 bytes.
P
Pete Popov 已提交
104 105 106 107
	 */
	u32	sw_status;
	u32 	sw_context;
	u32	sw_reserved[6];
L
Linus Torvalds 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
} au1x_ddma_desc_t;

#define DSCR_CMD0_V		(1 << 31)	/* Descriptor valid */
#define DSCR_CMD0_MEM		(1 << 30)	/* mem-mem transfer */
#define DSCR_CMD0_SID_MASK	(0x1f << 25)	/* Source ID */
#define DSCR_CMD0_DID_MASK	(0x1f << 20)	/* Destination ID */
#define DSCR_CMD0_SW_MASK	(0x3 << 18)	/* Source Width */
#define DSCR_CMD0_DW_MASK	(0x3 << 16)	/* Destination Width */
#define DSCR_CMD0_ARB		(0x1 << 15)	/* Set for Hi Pri */
#define DSCR_CMD0_DT_MASK	(0x3 << 13)	/* Descriptor Type */
#define DSCR_CMD0_SN		(0x1 << 12)	/* Source non-coherent */
#define DSCR_CMD0_DN		(0x1 << 11)	/* Destination non-coherent */
#define DSCR_CMD0_SM		(0x1 << 10)	/* Stride mode */
#define DSCR_CMD0_IE		(0x1 << 8)	/* Interrupt Enable */
#define DSCR_CMD0_SP		(0x1 << 4)	/* Status pointer select */
#define DSCR_CMD0_CV		(0x1 << 2)	/* Clear Valid when done */
#define DSCR_CMD0_ST_MASK	(0x3 << 0)	/* Status instruction */

126
#define SW_STATUS_INUSE 	(1 << 0)
P
Pete Popov 已提交
127

128
/* Command 0 device IDs. */
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
#define AU1550_DSCR_CMD0_UART0_TX	0
#define AU1550_DSCR_CMD0_UART0_RX	1
#define AU1550_DSCR_CMD0_UART3_TX	2
#define AU1550_DSCR_CMD0_UART3_RX	3
#define AU1550_DSCR_CMD0_DMA_REQ0	4
#define AU1550_DSCR_CMD0_DMA_REQ1	5
#define AU1550_DSCR_CMD0_DMA_REQ2	6
#define AU1550_DSCR_CMD0_DMA_REQ3	7
#define AU1550_DSCR_CMD0_USBDEV_RX0	8
#define AU1550_DSCR_CMD0_USBDEV_TX0	9
#define AU1550_DSCR_CMD0_USBDEV_TX1	10
#define AU1550_DSCR_CMD0_USBDEV_TX2	11
#define AU1550_DSCR_CMD0_USBDEV_RX3	12
#define AU1550_DSCR_CMD0_USBDEV_RX4	13
#define AU1550_DSCR_CMD0_PSC0_TX	14
#define AU1550_DSCR_CMD0_PSC0_RX	15
#define AU1550_DSCR_CMD0_PSC1_TX	16
#define AU1550_DSCR_CMD0_PSC1_RX	17
#define AU1550_DSCR_CMD0_PSC2_TX	18
#define AU1550_DSCR_CMD0_PSC2_RX	19
#define AU1550_DSCR_CMD0_PSC3_TX	20
#define AU1550_DSCR_CMD0_PSC3_RX	21
#define AU1550_DSCR_CMD0_PCI_WRITE	22
#define AU1550_DSCR_CMD0_NAND_FLASH	23
#define AU1550_DSCR_CMD0_MAC0_RX	24
#define AU1550_DSCR_CMD0_MAC0_TX	25
#define AU1550_DSCR_CMD0_MAC1_RX	26
#define AU1550_DSCR_CMD0_MAC1_TX	27
P
Pete Popov 已提交
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
#define AU1200_DSCR_CMD0_UART0_TX	0
#define AU1200_DSCR_CMD0_UART0_RX	1
#define AU1200_DSCR_CMD0_UART1_TX	2
#define AU1200_DSCR_CMD0_UART1_RX	3
#define AU1200_DSCR_CMD0_DMA_REQ0	4
#define AU1200_DSCR_CMD0_DMA_REQ1	5
#define AU1200_DSCR_CMD0_MAE_BE		6
#define AU1200_DSCR_CMD0_MAE_FE		7
#define AU1200_DSCR_CMD0_SDMS_TX0	8
#define AU1200_DSCR_CMD0_SDMS_RX0	9
#define AU1200_DSCR_CMD0_SDMS_TX1	10
#define AU1200_DSCR_CMD0_SDMS_RX1	11
#define AU1200_DSCR_CMD0_AES_TX		13
#define AU1200_DSCR_CMD0_AES_RX		12
#define AU1200_DSCR_CMD0_PSC0_TX	14
#define AU1200_DSCR_CMD0_PSC0_RX	15
#define AU1200_DSCR_CMD0_PSC1_TX	16
#define AU1200_DSCR_CMD0_PSC1_RX	17
#define AU1200_DSCR_CMD0_CIM_RXA	18
#define AU1200_DSCR_CMD0_CIM_RXB	19
#define AU1200_DSCR_CMD0_CIM_RXC	20
#define AU1200_DSCR_CMD0_MAE_BOTH	21
#define AU1200_DSCR_CMD0_LCD		22
#define AU1200_DSCR_CMD0_NAND_FLASH	23
#define AU1200_DSCR_CMD0_PSC0_SYNC	24
#define AU1200_DSCR_CMD0_PSC1_SYNC	25
#define AU1200_DSCR_CMD0_CIM_SYNC	26
P
Pete Popov 已提交
185

M
Manuel Lauss 已提交
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 215 216
#define AU1300_DSCR_CMD0_UART0_TX      0
#define AU1300_DSCR_CMD0_UART0_RX      1
#define AU1300_DSCR_CMD0_UART1_TX      2
#define AU1300_DSCR_CMD0_UART1_RX      3
#define AU1300_DSCR_CMD0_UART2_TX      4
#define AU1300_DSCR_CMD0_UART2_RX      5
#define AU1300_DSCR_CMD0_UART3_TX      6
#define AU1300_DSCR_CMD0_UART3_RX      7
#define AU1300_DSCR_CMD0_SDMS_TX0      8
#define AU1300_DSCR_CMD0_SDMS_RX0      9
#define AU1300_DSCR_CMD0_SDMS_TX1      10
#define AU1300_DSCR_CMD0_SDMS_RX1      11
#define AU1300_DSCR_CMD0_AES_TX        12
#define AU1300_DSCR_CMD0_AES_RX        13
#define AU1300_DSCR_CMD0_PSC0_TX       14
#define AU1300_DSCR_CMD0_PSC0_RX       15
#define AU1300_DSCR_CMD0_PSC1_TX       16
#define AU1300_DSCR_CMD0_PSC1_RX       17
#define AU1300_DSCR_CMD0_PSC2_TX       18
#define AU1300_DSCR_CMD0_PSC2_RX       19
#define AU1300_DSCR_CMD0_PSC3_TX       20
#define AU1300_DSCR_CMD0_PSC3_RX       21
#define AU1300_DSCR_CMD0_LCD           22
#define AU1300_DSCR_CMD0_NAND_FLASH    23
#define AU1300_DSCR_CMD0_SDMS_TX2      24
#define AU1300_DSCR_CMD0_SDMS_RX2      25
#define AU1300_DSCR_CMD0_CIM_SYNC      26
#define AU1300_DSCR_CMD0_UDMA          27
#define AU1300_DSCR_CMD0_DMA_REQ0      28
#define AU1300_DSCR_CMD0_DMA_REQ1      29

L
Linus Torvalds 已提交
217 218 219
#define DSCR_CMD0_THROTTLE	30
#define DSCR_CMD0_ALWAYS	31
#define DSCR_NDEV_IDS		32
220 221 222 223
/* This macro is used to find/create custom device types */
#define DSCR_DEV2CUSTOM_ID(x, d) (((((x) & 0xFFFF) << 8) | 0x32000000) | \
				  ((d) & 0xFF))
#define DSCR_CUSTOM2DEV_ID(x)	((x) & 0xFF)
L
Linus Torvalds 已提交
224 225 226 227

#define DSCR_CMD0_SID(x)	(((x) & 0x1f) << 25)
#define DSCR_CMD0_DID(x)	(((x) & 0x1f) << 20)

228
/* Source/Destination transfer width. */
L
Linus Torvalds 已提交
229 230 231 232 233 234 235
#define DSCR_CMD0_BYTE		0
#define DSCR_CMD0_HALFWORD	1
#define DSCR_CMD0_WORD		2

#define DSCR_CMD0_SW(x)		(((x) & 0x3) << 18)
#define DSCR_CMD0_DW(x)		(((x) & 0x3) << 16)

236
/* DDMA Descriptor Type. */
L
Linus Torvalds 已提交
237 238 239 240 241 242
#define DSCR_CMD0_STANDARD	0
#define DSCR_CMD0_LITERAL	1
#define DSCR_CMD0_CMP_BRANCH	2

#define DSCR_CMD0_DT(x)		(((x) & 0x3) << 13)

243
/* Status Instruction. */
L
Linus Torvalds 已提交
244 245 246 247 248 249 250
#define DSCR_CMD0_ST_NOCHANGE	0	/* Don't change */
#define DSCR_CMD0_ST_CURRENT	1	/* Write current status */
#define DSCR_CMD0_ST_CMD0	2	/* Write cmd0 with V cleared */
#define DSCR_CMD0_ST_BYTECNT	3	/* Write remaining byte count */

#define DSCR_CMD0_ST(x)		(((x) & 0x3) << 0)

251
/* Descriptor Command 1. */
L
Linus Torvalds 已提交
252 253 254 255 256
#define DSCR_CMD1_SUPTR_MASK	(0xf << 28)	/* upper 4 bits of src addr */
#define DSCR_CMD1_DUPTR_MASK	(0xf << 24)	/* upper 4 bits of dest addr */
#define DSCR_CMD1_FL_MASK	(0x3 << 22)	/* Flag bits */
#define DSCR_CMD1_BC_MASK	(0x3fffff)	/* Byte count */

257
/* Flag description. */
L
Linus Torvalds 已提交
258 259 260 261 262 263
#define DSCR_CMD1_FL_MEM_STRIDE0	0
#define DSCR_CMD1_FL_MEM_STRIDE1	1
#define DSCR_CMD1_FL_MEM_STRIDE2	2

#define DSCR_CMD1_FL(x)		(((x) & 0x3) << 22)

264
/* Source1, 1-dimensional stride. */
L
Linus Torvalds 已提交
265 266 267 268 269 270 271
#define DSCR_SRC1_STS_MASK	(3 << 30)	/* Src xfer size */
#define DSCR_SRC1_SAM_MASK	(3 << 28)	/* Src xfer movement */
#define DSCR_SRC1_SB_MASK	(0x3fff << 14)	/* Block size */
#define DSCR_SRC1_SB(x)		(((x) & 0x3fff) << 14)
#define DSCR_SRC1_SS_MASK	(0x3fff << 0)	/* Stride */
#define DSCR_SRC1_SS(x)		(((x) & 0x3fff) << 0)

272
/* Dest1, 1-dimensional stride. */
L
Linus Torvalds 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
#define DSCR_DEST1_DTS_MASK	(3 << 30)	/* Dest xfer size */
#define DSCR_DEST1_DAM_MASK	(3 << 28)	/* Dest xfer movement */
#define DSCR_DEST1_DB_MASK	(0x3fff << 14)	/* Block size */
#define DSCR_DEST1_DB(x)	(((x) & 0x3fff) << 14)
#define DSCR_DEST1_DS_MASK	(0x3fff << 0)	/* Stride */
#define DSCR_DEST1_DS(x)	(((x) & 0x3fff) << 0)

#define DSCR_xTS_SIZE1		0
#define DSCR_xTS_SIZE2		1
#define DSCR_xTS_SIZE4		2
#define DSCR_xTS_SIZE8		3
#define DSCR_SRC1_STS(x)	(((x) & 3) << 30)
#define DSCR_DEST1_DTS(x)	(((x) & 3) << 30)

#define DSCR_xAM_INCREMENT	0
#define DSCR_xAM_DECREMENT	1
#define DSCR_xAM_STATIC		2
#define DSCR_xAM_BURST		3
#define DSCR_SRC1_SAM(x)	(((x) & 3) << 28)
#define DSCR_DEST1_DAM(x)	(((x) & 3) << 28)

294
/* The next descriptor pointer. */
L
Linus Torvalds 已提交
295 296 297 298 299
#define DSCR_NXTPTR_MASK	(0x07ffffff)
#define DSCR_NXTPTR(x)		((x) >> 5)
#define DSCR_GET_NXTPTR(x)	((x) << 5)
#define DSCR_NXTPTR_MS		(1 << 27)

300
/* The number of DBDMA channels. */
L
Linus Torvalds 已提交
301 302
#define NUM_DBDMA_CHANS	16

P
Pete Popov 已提交
303
/*
304
 * DDMA API definitions
P
Pete Popov 已提交
305 306 307
 * FIXME: may not fit to this header file
 */
typedef struct dbdma_device_table {
308 309 310 311 312 313 314
	u32	dev_id;
	u32	dev_flags;
	u32	dev_tsize;
	u32	dev_devwidth;
	u32	dev_physaddr;		/* If FIFO */
	u32	dev_intlevel;
	u32	dev_intpolarity;
P
Pete Popov 已提交
315 316 317 318 319 320 321 322 323 324 325 326
} dbdev_tab_t;


typedef struct dbdma_chan_config {
	spinlock_t      lock;

	u32			chan_flags;
	u32			chan_index;
	dbdev_tab_t		*chan_src;
	dbdev_tab_t		*chan_dest;
	au1x_dma_chan_t		*chan_ptr;
	au1x_ddma_desc_t	*chan_desc_base;
327
	u32			cdb_membase; /* kmalloc base of above */
P
Pete Popov 已提交
328 329
	au1x_ddma_desc_t	*get_ptr, *put_ptr, *cur_ptr;
	void			*chan_callparam;
330
	void			(*chan_callback)(int, void *);
P
Pete Popov 已提交
331 332 333 334 335 336
} chan_tab_t;

#define DEV_FLAGS_INUSE		(1 << 0)
#define DEV_FLAGS_ANYUSE	(1 << 1)
#define DEV_FLAGS_OUT		(1 << 2)
#define DEV_FLAGS_IN		(1 << 3)
337
#define DEV_FLAGS_BURSTABLE	(1 << 4)
P
Pete Popov 已提交
338
#define DEV_FLAGS_SYNC		(1 << 5)
339
/* end DDMA API definitions */
P
Pete Popov 已提交
340

341 342 343 344 345
/*
 * External functions for drivers to use.
 * Use this to allocate a DBDMA channel.  The device IDs are one of
 * the DSCR_CMD0 devices IDs, which is usually redefined to a more
 * meaningful name.  The 'callback' is called during DMA completion
L
Linus Torvalds 已提交
346 347
 * interrupt.
 */
348
extern u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
349 350
				   void (*callback)(int, void *),
				   void *callparam);
L
Linus Torvalds 已提交
351 352 353

#define DBDMA_MEM_CHAN	DSCR_CMD0_ALWAYS

354
/* Set the device width of an in/out FIFO. */
L
Linus Torvalds 已提交
355 356
u32 au1xxx_dbdma_set_devwidth(u32 chanid, int bits);

357
/* Allocate a ring of descriptors for DBDMA. */
L
Linus Torvalds 已提交
358 359
u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries);

360
/* Put buffers on source/destination descriptors. */
361 362
u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags);
L
Linus Torvalds 已提交
363

364
/* Get a buffer from the destination descriptor. */
L
Linus Torvalds 已提交
365 366 367 368 369 370 371 372 373 374
u32 au1xxx_dbdma_get_dest(u32 chanid, void **buf, int *nbytes);

void au1xxx_dbdma_stop(u32 chanid);
void au1xxx_dbdma_start(u32 chanid);
void au1xxx_dbdma_reset(u32 chanid);
u32 au1xxx_get_dma_residue(u32 chanid);

void au1xxx_dbdma_chan_free(u32 chanid);
void au1xxx_dbdma_dump(u32 chanid);

375
u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
P
Pete Popov 已提交
376

377
u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
378
extern void au1xxx_ddma_del_device(u32 devid);
379
void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
380

P
Pete Popov 已提交
381 382 383
/*
 *	Flags for the put_source/put_dest functions.
 */
384 385
#define DDMA_FLAGS_IE	(1 << 0)
#define DDMA_FLAGS_NOIE (1 << 1)
P
Pete Popov 已提交
386

L
Linus Torvalds 已提交
387 388
#endif /* _LANGUAGE_ASSEMBLY */
#endif /* _AU1000_DBDMA_H_ */