dmaga.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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 */