OpenSolaris_b135/uts/sun/sys/dmaga.h

Compare this file to the similar file:
Show the results in this format:

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1988-1996, by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _SYS_DMAGA_H
#define	_SYS_DMAGA_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * New SUN DMA gate array definitions, revisions 1 and 2.
 *
 * Generally, this dma engine is owned exclusively by a SCSI host
 * adapter chip (ESP or ESP-2). Strictly speaking, a lance chip
 * (AMD 7990 Local Area Ethernet Chip) is hung off of it as well,
 * but there is very little we can do to the gate array to affect
 * the lance.
 *
 * NOTE: On SS1 with DMA rev 1 it is essential that prior to accessing
 *	 the D-channel (esp) registers, the dma is disabled. If not
 *	 a watchdog reset or data access may follow
 */


struct dmaga {
	uint32_t dmaga_csr;	/* control/status register */
	/*
	 * Dma Address Register
	 *
	 * For DMA Rev1, strictly speaking, the msb is an 8 bit
	 * register and the 24 lsbs are a counter. This asssumes
	 * that no transfer will cross a 16mb boundary. This
	 * restriction does not apply for anything but DMA rev1.
	 */
	uint32_t dmaga_addr;
	uint32_t dmaga_count;	/* count register. Only the 24 lsbs matter */
	uint32_t dmaga_diag;	/* undefined - unused */
};

#define	SET_DMAESC_COUNT(dmar, val) (dmar)->dmaga_count = val

/* bits in the dma gate array status register */
#define	DMAGA_INTPEND	0x0001	/* (r)	Interrupt pending. */
				/* 	Clear when device drops INT. */
				/*	ESC: only ESP interrupt pending. */

#define	DMAGA_ERRPEND	0x0002	/* (r) error pending on memory exception */

/*
 * The following two defines apply only to rev1 (DMA) gate arrays
 */
#define	DMAGA_PACKCNT	0x000C	/* (r) number of bytes in pack register */
#define	DMAGA_NPACKED(x)	(((x)->dmaga_csr & DMAGA_PACKCNT) >> 2)

/*
 * The following define applies only to rev2 (DMA+), rev3 (DMA2),
 * and ESC gate arrays.
 */

#define	DMAGA_DRAINING	0x000C

#define	DMAGA_INTEN	0x0010	/* (r/w)	Interrupt enable. */
				/*	Sad but true: you have to turn this */
				/*	on to get any interrupts from the */
				/*	ESP SCSI chip..... */

#define	DMAGA_FLUSH	0x0020	/* (w) 1 == clears PACKCNT, ERRPEND and TC */

/*
 * The following define applies only to rev1 (DMA) gate arrays
 */
#define	DMAGA_DRAIN	0x0040	/* (r/w) 1 == pushes PACKCNT bytes to memory */
/*
 * The following define applies only to rev2 (DMA+), rev3 (DMA2),
 * and ESC gate arrays.
 */
#define	DMAGA_SLVERR	0x0040	/* (r) Set on slave size error. Reset on */
				/* csr read.  */

#define	DMAGA_RESET	0x0080	/* (r/w) 1 == reset dma gate array */
				/*	May or may not reset attached */
				/*	devices (e.g. ESP chip). */

#define	DMAGA_WRITE	0x0100	/* (r/w) DVMA direction */
				/*	1 == TO MEMORY */
				/*	0 == FROM MEMORY */

#define	DMAGA_ENDVMA	0x0200	/* (r/w) 1 == dmaga responds to dma requests */

/*
 * The following define applies only to rev1 (DMA) and ESC gate arrays
 */
#define	DMAGA_REQPEND	0x0400	/* (r) 1 == dma gate array active */
				/*	NO reset and flush allowed */

/*
 * The following defines thru DMAESC_EN_ADD apply only to ESC gate arrays
 */
#define	DMAESC_BSIZE	0x0800	/* (r/w) maximum burst size */
				/*	1 = 16 bytes */
				/*	0 = 32 bytes */
#define	DMAESC_SETBURST16(d)	(d)->dmaga_csr |= DMAESC_BSIZE
#define	DMAESC_SETBURST32(d)	(d)->dmaga_csr &= ~DMAESC_BSIZE

#define	DMAESC_TCZERO	0x1000	/* (r) set when transfer count becomes 0 */

#define	DMAESC_EN_TCI	0x2000	/* (r/w) enable interrupt generation on */
				/*	  expiration of count */

#define	DMAESC_INTPEND	0x4000	/* (r) interrupt summary - 3 sources: */
				/*	1) DMAESC_SCSI_INT - ESP interrupt */
				/*	2) DMAESC_TCZERO - transfer count 0 */
				/*	3) DMAESC_PERR -  parity error */

#define	DMAESC_PEN	0x8000	/* (r/w) sbus parity enable */

#define	DMAESC_PERR	0x00010000	/* (r) sbus parity error */

#define	DMAESC_DRAIN	0x00020000	/* (w) write 1 to drain data in */
					/*	buffer. */
					/*	ignored if DMAESC_EN_AD set */

#define	DMAESC_EN_ADD	0x00040000	/* (r/w) enable auto-drain */
					/* Note: overlap with DMA2 define */
					/* below. */

/*
 * The following two defines apply only to rev1 (DMA) gate arrays
 */
#define	DMAGA_BYTEADR	0x1800	/* (r) next byte to be accessed */
#define	DMAGA_NEXTBYTE(x)	(((x)->dmaga_csr & DMAGA_BYTEADR) >> 11)

#define	DMAGA_ENATC	0x2000	/* (r/w) enable byte counter */

/*
 * The following two defines apply only to rev1 (DMA) and rev 2 (DMA+)
 * gate arrays
 */
#define	DMAGA_TC	0x4000	/* (r) terminal count reached */

#define	DMAGA_ILACC	0x8000	/* 'new' ethernet chip enabled- modifies */
				/* lance DMA read cycle. This is not */
				/* currently implemented and is not available */
				/* for DMA2 or ESC. */

/*
 * The following define is available only for rev3 (DMA2) gate arrays
 *
 * Do not set NOBURST and BURST64 at the same time (this is reserved
 * and will have undefined effects). Instead, clear the BURSTMASK
 * field and set what you want.
 */

#define	DMAGA_BURSTMASK	0x000C0000	/* Burst size field. */
#define	DMAGA_BURST16	0x00000000	/* 16 Byte bursts (default). */
					/* Comaptible with DMA+.  */
#define	DMAGA_NOBURST	0x00080000	/* No bursts. */
#define	DMAGA_BURST32	0x00040000	/* 32 Byte bursts. */

#define	DMA2_SETNOBURST(d)	\
	(d)->dmaga_csr &= ~DMAGA_BURSTMASK, (d)->dmaga_csr |= DMAGA_NOBURST
#define	DMA2_SETBURST16(d)	(d)->dmaga_csr &= ~DMAGA_BURSTMASK
#define	DMA2_SETBURST32(d)	\
	(d)->dmaga_csr &= ~DMAGA_BURSTMASK, (d)->dmaga_csr |= DMAGA_BURST32

/*
 * The following defines up through the DMAGA_DEVID are valid only for
 * rev2 (DMA+) gate arrays.
 */


#define	DMAGA_ALE	0x00100000	/* (r/w) defines pin 27 as ALE */
					/* (address latch enable) or AS* */
					/* (address strobe). 1 = ALE, */
					/* 0 = AS* (defaults to 0). This */
					/* for different types of lance */
					/* dma handshaking. This is not */
					/* currently implemented and is */
					/* not available on DMA2 or ESC. */

#define	DMAGA_LERR	0x00200000	/* (r) Set when a memory error occurs */
					/* on a transfer to/from LANCE. */
					/* Clears on a slave write to LANCE. */
					/* This is not currently used by any */
					/* standard s/w, and is not */
					/* implemented on DMA2 or ESC. */

#define	DMAGA_TURBO	0x00400000	/* (r/w) turns on 'faster' mode for */
					/* use with the 53C90A scsi chip.  */

#define	DMAGA_NOTCINT	0x00800000	/* (r/w) Disable TC (terminal count) */
					/* interrupts (if set). Defaults to */
					/* 0. Note that in order to get TC */
					/* ints you have to enable the byte */
					/* counter by setting DMAGA_ENATC. */
					/* If you enable the byte counter, */
					/* but also set this bit, you can get */
					/* dma transfer limited by a byte */
					/* counter w/o dealing with */
					/* interrupts. */

/*
 * The following defines are valid only for rev3 (DMA2) gate arrays.
 */

#define	DMAGA_TWO_CYCLE 0x00200000


/*
 * The next three defines are for the 'Next-address' autoload mechanism
 *
 * This mechanism is a somewhat complicated mechanism for pipelining DMA
 * transfers. In the rev2 (DMA+) gate array, there are next_address and
 * next_bytecnt registers that hide at the same address as the address
 * and byte_count registers.
 *
 * The best way to describe how this works is to paraphrase from the S4-DMA+
 * chip document (prelim, 7/12/89):
 *
 *
 * If The DMAGA_ENANXT bit in dmaga_ csr is set, then a write to the
 * dmaga_addr register will will write to the NEXT_ADDR register instead.
 * If the DMAGA_ENANXT bit is set when the byte counter (dmaga_count)
 * expires, and the NEXT_ADDR regsiter has been written to since the last
 * time the byte counter expired, then the contents of the NEXT_ADDR
 * register are copied to the dmaga_addr register. If DMAGA_ENANXT is set
 * when the byte counter (dmaga_count) expires, but the NEXT_ADDR register
 * has not been written to since the last time the byte counter expired,
 * then DMA activity is stopped and DMA request from the ESP will be
 * ignored until NEXT_ADDR is written to, or DMAGA_ENANXT is cleared.
 * (Also, the DMAGA_DMAON bit will read as 0 while DMA is stopped because
 * of this). When DMA is re-enabled by writing to the NEXT_ADDR register,
 * the contents of the NEXT_ADDR register are copied to the dmaga_addr
 * register before DMA activity actually begins.
 *
 * ...
 *
 * If the DMAGA_ENANXT bit in dmaga_csr is set, then a write to dmaga_count
 * will write to the NEXT_BCNT register instead. If the NEXT_ADDR register
 * is being copied into dmaga_addr, and DMAGA_ENANXT is set, then the
 * NEXT_BCNT register will be copied into dmaga_count at the same time.
 *
 * (whew!)
 */

#define	DMAGA_ENANXT	0x01000000	/* (r/w) Enable 'next-address' */
					/* autoload mechanism (see above). */

#define	DMAGA_DMAON	0x02000000	/* (r) reads as 1 when: */
					/*  (DMAGA_ALOAD || DMAGA_NALOAD) && */
					/*	DMAGA_ENDVMA && */
					/*	!(DMAGA_ERRPEND) */

#define	DMAGA_ALOAD	0x04000000	/* (r) Address Loaded (see above). */

#define	DMAGA_NALOAD	0x08000000	/* (r) Next Address loaded */
					/* (see above). */

/*
 * burstsizes
 */
#define	BURST1		0x01
#define	BURST2		0x02
#define	BURST4		0x04
#define	BURST8		0x08
#define	BURST16		0x10
#define	BURST32		0x20
#define	BURST64		0x40
#define	BURSTSIZE_MASK	0x7f
#define	DEFAULT_BURSTSIZE	BURST16|BURST8|BURST4|BURST2|BURST1


/*
 * Gate Array id bits:
 */

#define	DMAGA_DEVID	0xF0000000	/* (r) Device ID */
#define	DMAGA_REV(x)	(((x)->dmaga_csr & DMAGA_DEVID) >> 28)

#define	DMA_REV1	0x8	/* DMA gate array */
#define	DMA_REV2	0x9	/* DMA+ gate array */
#define	ESC1_REV1	0x4	/* ESC gate array */
#define	DMA_REV3	0xA	/* DMA2 gate array */


/*
 * Compound conditions for interrupt and error checking.
 */

#define	DMAGA_CHK_MASK	(DMAGA_INTPEND | DMAGA_ERRPEND | DMAGA_REQPEND)
#define	DMAGA_INT_MASK	(DMAGA_INTPEND | DMAGA_ERRPEND)

/*
 * %b formatted error strings
 */

#define	DMAGA_BITS	\
"\20\20ILACC\17TC\13RQPND\12EN\11IN\10RST\7DRAIN\6FLSH\5INTEN\2ERRPEND\1INTPND"

#ifdef	_KERNEL

extern struct dmaga *dma_alloc(dev_info_t *cdev);
extern void dma_free(struct dmaga *regs);
extern int dma_affinity(dev_info_t *dma, dev_info_t *cdev);

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_DMAGA_H */