xref: /dflybsd-src/sys/dev/disk/sili/sili.h (revision c2a27f530d06e2122e22253a8f88f45c8e4720a8)
11ac8d5baSMatthew Dillon /*
21ac8d5baSMatthew Dillon  * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
31ac8d5baSMatthew Dillon  *
41ac8d5baSMatthew Dillon  * Permission to use, copy, modify, and distribute this software for any
51ac8d5baSMatthew Dillon  * purpose with or without fee is hereby granted, provided that the above
61ac8d5baSMatthew Dillon  * copyright notice and this permission notice appear in all copies.
71ac8d5baSMatthew Dillon  *
81ac8d5baSMatthew Dillon  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
91ac8d5baSMatthew Dillon  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
101ac8d5baSMatthew Dillon  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
111ac8d5baSMatthew Dillon  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
121ac8d5baSMatthew Dillon  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
131ac8d5baSMatthew Dillon  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
141ac8d5baSMatthew Dillon  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
151ac8d5baSMatthew Dillon  *
161ac8d5baSMatthew Dillon  * $OpenBSD: sili.c,v 1.147 2009/02/16 21:19:07 miod Exp $
171ac8d5baSMatthew Dillon  */
181ac8d5baSMatthew Dillon 
191ac8d5baSMatthew Dillon #if defined(__DragonFly__)
201ac8d5baSMatthew Dillon #include "sili_dragonfly.h"
211ac8d5baSMatthew Dillon #else
221ac8d5baSMatthew Dillon #error "build for OS unknown"
231ac8d5baSMatthew Dillon #endif
241ac8d5baSMatthew Dillon #include "pmreg.h"
251ac8d5baSMatthew Dillon #include "atascsi.h"
261ac8d5baSMatthew Dillon 
271ac8d5baSMatthew Dillon /* change to SILI_DEBUG for dmesg spam */
281ac8d5baSMatthew Dillon #define NO_SILI_DEBUG
291ac8d5baSMatthew Dillon 
301ac8d5baSMatthew Dillon #ifdef SILI_DEBUG
311ac8d5baSMatthew Dillon #define DPRINTF(m, f...) do { if ((silidebug & (m)) == (m)) kprintf(f); } \
321ac8d5baSMatthew Dillon     while (0)
331ac8d5baSMatthew Dillon #define SILI_D_TIMEOUT		0x00
341ac8d5baSMatthew Dillon #define SILI_D_VERBOSE		0x01
351ac8d5baSMatthew Dillon #define SILI_D_INTR		0x02
361ac8d5baSMatthew Dillon #define SILI_D_XFER		0x08
371ac8d5baSMatthew Dillon int silidebug = SILI_D_VERBOSE;
381ac8d5baSMatthew Dillon #else
391ac8d5baSMatthew Dillon #define DPRINTF(m, f...)
401ac8d5baSMatthew Dillon #endif
411ac8d5baSMatthew Dillon 
421ac8d5baSMatthew Dillon /*
431ac8d5baSMatthew Dillon  * BAR0 - Global Registers		128-byte aligned, 128-byte region
441ac8d5baSMatthew Dillon  * BAR1 - Port Registers and LRAM	32KB-aligned
451ac8d5baSMatthew Dillon  * BAR2 - Indirect I/O registers	(we don't use this)
461ac8d5baSMatthew Dillon  */
471ac8d5baSMatthew Dillon 
481ac8d5baSMatthew Dillon /*
491ac8d5baSMatthew Dillon  * Port-N Slot Status.
501ac8d5baSMatthew Dillon  *
511ac8d5baSMatthew Dillon  * NOTE: Mirrors SILI_PREG_SLOTST
521ac8d5baSMatthew Dillon  */
531ac8d5baSMatthew Dillon #define SILI_REG_SLOTST(n)	(0x0000 + ((n) * 4))
541ac8d5baSMatthew Dillon #define SILI_REG_SLOTST_ATTN	0x80000000	/* attention required */
551ac8d5baSMatthew Dillon 
561ac8d5baSMatthew Dillon #define SILI_REG_GCTL		0x0040		/* Global Control	*/
571ac8d5baSMatthew Dillon #define SILI_REG_GCTL_PORTEN(n)	(1 << (n))	/* Port interrupt ena	*/
581ac8d5baSMatthew Dillon #define SILI_REG_GCTL_300CAP	0x01000000	/* 3Gb/s capable (R)	*/
591ac8d5baSMatthew Dillon #define SILI_REG_GCTL_I2C_IEN	0x20000000	/* I2C Int enable	*/
601ac8d5baSMatthew Dillon #define SILI_REG_GCTL_MSIACK	0x40000000	/* MSI Ack W1C		*/
611ac8d5baSMatthew Dillon #define SILI_REG_GCTL_GRESET	0x80000000	/* global reset */
621ac8d5baSMatthew Dillon 
631ac8d5baSMatthew Dillon #define SILI_REG_GINT		0x0044		/* Global Interrupt Status */
641ac8d5baSMatthew Dillon #define SILI_REG_GINT_I2C	0x20000000	/* I2C Int Status	*/
651ac8d5baSMatthew Dillon #define SILI_REG_GINT_PORTST(n)	(1 << (n))	/* Port interrupt stat  */
661ac8d5baSMatthew Dillon #define SILI_REG_GINT_PORTMASK	0x0000FFFF
671ac8d5baSMatthew Dillon 
681ac8d5baSMatthew Dillon /*
691ac8d5baSMatthew Dillon  * Most bits in phyconf should not be modified.  Setting the low four bits
701ac8d5baSMatthew Dillon  * to 1's, all channel Tx outputs spread spectrum clocking.
711ac8d5baSMatthew Dillon  */
721ac8d5baSMatthew Dillon #define SILI_REG_PHYCONF	0x0048		/* PHY Configuration */
731ac8d5baSMatthew Dillon #define SILI_REG_PHYCONF_ALLSS	0x000F		/* spread spectrum tx */
741ac8d5baSMatthew Dillon 
751ac8d5baSMatthew Dillon /*
761ac8d5baSMatthew Dillon  * BIST_CTL_TEN -	Enable data paths for running data loopback BIST
771ac8d5baSMatthew Dillon  * BIST_CTL_TPAT -	Select repeating pattern (1) or pseudo-random
781ac8d5baSMatthew Dillon  *			pattern (0)
791ac8d5baSMatthew Dillon  * BIST_CTL_RXSEL-	Select the rx port for pattern comparison
801ac8d5baSMatthew Dillon  * BIST_CTL_TXSEL-	Select the tx ports that transmit loopback data
811ac8d5baSMatthew Dillon  */
821ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL	0x0050
831ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TEN	0x80000000
841ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TPAT	0x40000000
851ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_RXSEL(n) ((n) << 16)
861ac8d5baSMatthew Dillon #define SILI_REG_BIST_CTL_TXSEL(n) (1 << (n))
871ac8d5baSMatthew Dillon 
881ac8d5baSMatthew Dillon #define SILI_REG_BIST_PATTERN	0x0054	/* 32 bit pattern */
891ac8d5baSMatthew Dillon 
901ac8d5baSMatthew Dillon /*
911ac8d5baSMatthew Dillon  * GOOD is set to 1 on BIST initiation, and reset to 0 on the first
921ac8d5baSMatthew Dillon  * comparison failure.
931ac8d5baSMatthew Dillon  */
941ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS	0x0058
951ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS_CNT  0x000007FF	/* pattern counter */
961ac8d5baSMatthew Dillon #define SILI_REG_BIST_STATUS_GOOD 0x80000000	/* set to 0 on compare fail */
971ac8d5baSMatthew Dillon 
981ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL	0x0060
991ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_START	0x00000001
1001ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_STOP	0x00000002
1011ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_NACK	0x00000004	/* send nack on data byte rx */
1021ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_TFDATA	0x00000008	/* set to initiate txfer     */
1031ac8d5baSMatthew Dillon 						/* to/from data buffer	     */
1041ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_MABORT	0x00000010	/* set w/STOP to send stop   */
1051ac8d5baSMatthew Dillon 						/* without first xfering a   */
1061ac8d5baSMatthew Dillon 						/* byte			     */
1071ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_SCLEN	0x00000020	/* clock-en for master mode  */
1081ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_UNITEN	0x00000040	/* enable controller 	     */
1091ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_GCALLD	0x00000080	/* Disable detect of a       */
1101ac8d5baSMatthew Dillon 						/* general call address      */
1111ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_TXBEI	0x00000100	/* xmit buffer empty int en  */
1121ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_RXBFI	0x00000200	/* rx buffer full int en     */
1131ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_BERRI	0x00000400	/* bus error int en	     */
1141ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_STOPI	0x00000800	/* stop detect int en	     */
1151ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_ARBLI	0x00001000	/* arb loss int en	     */
1161ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_ARBDI	0x00002000	/* arb detect int en	     */
1171ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_UNITRS	0x00004000	/* reset I2C controller	     */
1181ac8d5baSMatthew Dillon #define SILI_REG_I2C_CTL_FASTM	0x00008000	/* 400kbit/s (else 100kbit/s)*/
1191ac8d5baSMatthew Dillon 
1201ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS	0x0064
1211ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_RW	0x00000001
1221ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_ACKSTS	0x00000002	/* ack/nack status(R) last   */
1231ac8d5baSMatthew Dillon 						/* ack or nack sent or rcvd  */
1241ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_UNTBSY	0x00000004	/* unit busy (R)	     */
1251ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_BUSBSY	0x00000008	/* bus busy with activity(R) */
1261ac8d5baSMatthew Dillon 						/* other then from controller*/
1271ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_STOPDT	0x00000010	/* stop detect (R/W1C)	     */
1281ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_ARBLD	0x00000020	/* arb loss detect   (R/W1C) */
1291ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_TXBED	0x00000040	/* tx buffer empty   (R)     */
1301ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_RXBFD	0x00000080	/* rx buffer full    (R/W1C) */
1311ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_GCALLD	0x00000100	/* Gen Call detect   (R/W1C) */
1321ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_SADDRD	0x00000200	/* Slave addr detect (R/W1C) */
1331ac8d5baSMatthew Dillon #define SILI_REG_I2C_STS_BERRD	0x00000400	/* Bus error detect  (R/W1C) */
1341ac8d5baSMatthew Dillon 
1351ac8d5baSMatthew Dillon #define SILI_REG_I2C_SADDR	0x0068		/* our slave address         */
1361ac8d5baSMatthew Dillon #define SILI_REG_I2C_SADDR_MASK	0x0000003F	/* 6 bits                    */
1371ac8d5baSMatthew Dillon 
1381ac8d5baSMatthew Dillon #define SILI_REG_I2C_DATA	0x006C		/* data buffer (8 bits)      */
1391ac8d5baSMatthew Dillon 
1401ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR	0x0070		/* Flash control & addr reg  */
1411ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMPRS 0x04000000	/* Flash memory present	     */
1421ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_GPIOEN 0x80000000	/* use flash data pins for   */
1431ac8d5baSMatthew Dillon 						/* GPIO */
1441ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMST  0x02000000	/* Mem Access Start (R/W)    */
1451ac8d5baSMatthew Dillon 						/* (clears on op complete)   */
1461ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MEMRD  0x01000000	/* 0=write, 1=read           */
1471ac8d5baSMatthew Dillon #define SILI_REG_FLASH_ADDR_MASK   0x0003FFFF	/* 18 bit memory address     */
1481ac8d5baSMatthew Dillon 
1491ac8d5baSMatthew Dillon /*
1501ac8d5baSMatthew Dillon  * NOTE: In order to set a GPIO pin to read the DATA bit must be written to
1511ac8d5baSMatthew Dillon  *       1and the DCTL (drain control) bit must be written to 1 as well
1521ac8d5baSMatthew Dillon  *       to make it open-drain only (drive on low only).
1531ac8d5baSMatthew Dillon  */
1541ac8d5baSMatthew Dillon #define SILI_REG_GPIO		0x0074
1551ac8d5baSMatthew Dillon #define SILI_REG_GPIO_DATA_SHIFT	0	/* 8 bits Flash or GPIO data */
1561ac8d5baSMatthew Dillon #define SILI_REG_GPIO_TDET_SHIFT	8	/* 8 bits transition detect  */
1571ac8d5baSMatthew Dillon #define SILI_REG_GPIO_DCTL_SHIFT	16	/* 8 bits drain control      */
1581ac8d5baSMatthew Dillon 
1591ac8d5baSMatthew Dillon /*
1601ac8d5baSMatthew Dillon  * Per-port registers
1611ac8d5baSMatthew Dillon  *
1621ac8d5baSMatthew Dillon  */
1631ac8d5baSMatthew Dillon 
1641ac8d5baSMatthew Dillon #define SILI_PORT_REGION(port)	(8192 * (port))
1651ac8d5baSMatthew Dillon #define SILI_PORT_SIZE		8192
1661ac8d5baSMatthew Dillon #define SILI_PREG_LRAM		0x0000		/* 0x0000-0x0F7F	     */
1671ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_SLOT(n)	(0x0000 + (128 * (n)))
1681ac8d5baSMatthew Dillon 
1691ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_SLOT_FIS	0x0000		/* Current FIS and Control   */
1701ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMA0	0x0020		/* DMA Entry 0 or ATAPI cmd  */
1711ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMA1	0x0030		/* DMA Entry 0 or ATAPI cmd  */
1721ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_CMDACT	0x0040		/* Cmd Act Reg (actual) 64b  */
1731ac8d5baSMatthew Dillon #define SILI_PREG_LRAM_DMATAB	0x0040		/* Scatter Gather Table      */
1741ac8d5baSMatthew Dillon 
1751ac8d5baSMatthew Dillon /*
1761ac8d5baSMatthew Dillon  * Each port has a port status and qactive register for each target behind
1771ac8d5baSMatthew Dillon  * the port multiplier, if there is a port multiplier.
1781ac8d5baSMatthew Dillon  *
1791ac8d5baSMatthew Dillon  * SERVICE - Service received from device, service command from controller
1801ac8d5baSMatthew Dillon  *	     not yet acknowledged.
1811ac8d5baSMatthew Dillon  *
1821ac8d5baSMatthew Dillon  * LEGACY  - One or more legacy queued commands is outstanding.
1831ac8d5baSMatthew Dillon  *
1841ac8d5baSMatthew Dillon  * NATIVE  - One or more NCQ queued commands is outstanding.
1851ac8d5baSMatthew Dillon  *
1861ac8d5baSMatthew Dillon  * VBSY    - A virtual device busy indicating that a command has been issued
1871ac8d5baSMatthew Dillon  *	     to the device and the device has not yet sent the final D2H
1881ac8d5baSMatthew Dillon  *	     register FIS, or that a data transfer is in progress.
1891ac8d5baSMatthew Dillon  *
1901ac8d5baSMatthew Dillon  * The PM_QACTIVE register contains a demultiplexed bitmap of slots queued
1911ac8d5baSMatthew Dillon  * to each target behind the port multiplier.
1921ac8d5baSMatthew Dillon  *
1931ac8d5baSMatthew Dillon  */
1941ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS(n)	(0x0F80 + (8 * (n)))
1951ac8d5baSMatthew Dillon #define SILI_PREG_PM_QACTIVE(n)	(0x0F84 + (8 * (n)))
1961ac8d5baSMatthew Dillon 
1971ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_SERVICE	0x00010000	/* Service pending */
1981ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_LEGACY	0x00008000	/* Legacy outstanding*/
1991ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_NATIVE	0x00004000	/* NCQ outstanding */
2001ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_VBSY	0x00002000	/* virtual dev busy */
2011ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_EXEC_SHIFT	8		/* last active slot */
2021ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_EXEC_MASK	0x1F
2031ac8d5baSMatthew Dillon #define SILI_PREG_PM_STATUS_PIO_MASK	0xFF		/* last PIO setup   */
2041ac8d5baSMatthew Dillon 
2051ac8d5baSMatthew Dillon /*
2061ac8d5baSMatthew Dillon  * NOTE: SILI_PREG_STATUS uses the same address as SILI_PREG_CTL_SET,
2071ac8d5baSMatthew Dillon  * but for read.
2081ac8d5baSMatthew Dillon  */
2091ac8d5baSMatthew Dillon #define SILI_PREG_STATUS	0x1000		/* Port Control Status (R)   */
2101ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_READY	0x80000000	/* Port Ready          (R)   */
2111ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_SLOT	0x001F0000	/* Active Slot         (R)   */
2121ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_SLOT_SHIFT	16	/* Shift value		     */
2131ac8d5baSMatthew Dillon #define SILI_PREG_STATUS_MASK	0x0200FFFF	/* see PREG_CTL_xxx          */
2141ac8d5baSMatthew Dillon 
2151ac8d5baSMatthew Dillon /*
2161ac8d5baSMatthew Dillon  * NOTE: Reset sequence.  Set CTL_RESET, Clear CTL_RESET, then Wait for
2171ac8d5baSMatthew Dillon  *       the port to become ready.
2181ac8d5baSMatthew Dillon  *
2191ac8d5baSMatthew Dillon  * NOTE: NOAUTOCC.  If set to 1 a 1 must be written to the command completion
2201ac8d5baSMatthew Dillon  *	 bit in the port interrupt status register to clear it.  When set to
2211ac8d5baSMatthew Dillon  *	 0 then reading the port slot status register will automatically clear
2221ac8d5baSMatthew Dillon  *       the command completion interrupt.
2231ac8d5baSMatthew Dillon  *
2241ac8d5baSMatthew Dillon  * NOTE: ATA16 controls whether a PACKET mode command is 12 or 16 bytes.
2251ac8d5baSMatthew Dillon  *
2261ac8d5baSMatthew Dillon  * NOTE: RESUME if set to 1 processing is enabled for outstanding commands
2271ac8d5baSMatthew Dillon  *       to additional targets connected to a port multiplier after a command
2281ac8d5baSMatthew Dillon  *	 error has occured.  When set the internal BUSY status will be set
2291ac8d5baSMatthew Dillon  *	 for the target that errored, preventing additional commands from
2301ac8d5baSMatthew Dillon  *       being sent until a Port Initialize operation is performed.
2311ac8d5baSMatthew Dillon  *
2321ac8d5baSMatthew Dillon  * NOTE: 32BITDMA if 1 causes a write to the low 32 bits of a Command
2331ac8d5baSMatthew Dillon  *	 Activation register to  copy PREG_32BIT_ACTUA to the upper 32
2341ac8d5baSMatthew Dillon  *       bits and start command execution.  If 0 you must write to the
2351ac8d5baSMatthew Dillon  *       low 32 bits and then the high 32 bits and your write to the
2361ac8d5baSMatthew Dillon  *       high 32 bits will start command execution.
2371ac8d5baSMatthew Dillon  *
2381ac8d5baSMatthew Dillon  * NOTE: OOB_BYP is set on global reset and not changed by a port reset.
2391ac8d5baSMatthew Dillon  */
2401ac8d5baSMatthew Dillon #define SILI_PREG_CTL_SET	0x1000		/* Port Control Set    (W1S) */
2411ac8d5baSMatthew Dillon #define SILI_PREG_CTL_CLR	0x1004		/* Port Control Clear  (W1C) */
2421ac8d5baSMatthew Dillon #define SILI_PREG_CTL_RESET	0x00000001	/* Hold port in reset        */
2431ac8d5baSMatthew Dillon #define SILI_PREG_CTL_DEVRESET	0x00000002	/* Device reset              */
2441ac8d5baSMatthew Dillon 						/* (Self clearing)           */
2451ac8d5baSMatthew Dillon #define SILI_PREG_CTL_INIT	0x00000004	/* Port initialize           */
2461ac8d5baSMatthew Dillon 						/* (Self clearing)           */
2471ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOAUTOCC	0x00000008
2481ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOLED	0x00000010	/* Disable the LED port      */
2491ac8d5baSMatthew Dillon 						/* activity indicator.       */
2501ac8d5baSMatthew Dillon #define SILI_PREG_CTL_ATA16	0x00000020	/* 0=12 byte 1=16 byte       */
2511ac8d5baSMatthew Dillon #define SILI_PREG_CTL_RESUME	0x00000040	/* PM special error handling */
2521ac8d5baSMatthew Dillon #define SILI_PREG_CTL_TXBIST	0x00000080	/* transmit a BIST FIS       */
2531ac8d5baSMatthew Dillon #define SILI_PREG_CTL_CONT_DIS	0x00000100	/* no CONT on repeat primitves*/
2541ac8d5baSMatthew Dillon #define SILI_PREG_CTL_NOSCRAM	0x00000200	/* Disable link scrambler    */
2551ac8d5baSMatthew Dillon #define SILI_PREG_CTL_32BITDMA	0x00000400	/* see above 		     */
2561ac8d5baSMatthew Dillon #define SILI_PREG_CTL_ACC_ILCK	0x00000800	/* accept interlocked FIS rx */
2571ac8d5baSMatthew Dillon 						/* (Self clearing)           */
2581ac8d5baSMatthew Dillon #define SILI_PREG_CTL_REJ_ILCK	0x00001000	/* reject interlocked FIS rx */
2591ac8d5baSMatthew Dillon 						/* (Self clearing)           */
2601ac8d5baSMatthew Dillon #define SILI_PREG_CTL_PMA	0x00002000	/* Enable PM support         */
2611ac8d5baSMatthew Dillon #define SILI_PREG_CTL_AUTO_ILCK	0x00004000	/* Auto interlock accept     */
2621ac8d5baSMatthew Dillon #define SILI_PREG_CTL_LEDON	0x00008000	/* LED on		     */
2631ac8d5baSMatthew Dillon #define SILI_PREG_CTL_OOB_BYP	0x02000000	/* Bypass OOB initialization */
2641ac8d5baSMatthew Dillon 
2651ac8d5baSMatthew Dillon /*
2661ac8d5baSMatthew Dillon  * Status bits in the upper half of the register report the actual condition
2671ac8d5baSMatthew Dillon  * while the status bits in the lower half of the register are masked by
2681ac8d5baSMatthew Dillon  * the interrupt enable bits or threshold registers.  Writing a 1 to either
2691ac8d5baSMatthew Dillon  * version will clear it.
2701ac8d5baSMatthew Dillon  *
2711ac8d5baSMatthew Dillon  * NOTE: The steering bits written to INT_ENABLE will not show up in the
2721ac8d5baSMatthew Dillon  *       status register.  The INT_ENABLE/INT_DISABLE registers are R+W1S
2731ac8d5baSMatthew Dillon  *	 or R+W1C and thus can be read.
2741ac8d5baSMatthew Dillon  *
2751ac8d5baSMatthew Dillon  * NOTE: PHYRDYCHG, COMWAKE, UNRECFIS, DEVEXCHG: Can be cleared by writing
2761ac8d5baSMatthew Dillon  *	 W1C either here or via the DIAG.xxx bit bit in SError.
2771ac8d5baSMatthew Dillon  */
2781ac8d5baSMatthew Dillon #define SILI_PREG_INT_STATUS	0x1008		/* Control clear	     */
2791ac8d5baSMatthew Dillon #define SILI_PREG_INT_ENABLE	0x1010		/* Interrupt Enable Set      */
2801ac8d5baSMatthew Dillon #define SILI_PREG_INT_DISABLE	0x1014		/* Interrupt Enable Clear    */
2811ac8d5baSMatthew Dillon 
2821ac8d5baSMatthew Dillon #define SILI_PREG_INT_STEER(n)	((n) << 30)	/* Port Int -> INTA...INTD   */
2831ac8d5baSMatthew Dillon #define SILI_PREG_INT_CCOMPLETE	0x00000001	/* one or more cmds completed*/
2841ac8d5baSMatthew Dillon #define SILI_PREG_INT_CERROR	0x00000002	/* read port error register  */
2851ac8d5baSMatthew Dillon 						/* to get error              */
2861ac8d5baSMatthew Dillon #define SILI_PREG_INT_READY	0x00000004	/* Port is ready for cmds    */
2871ac8d5baSMatthew Dillon #define SILI_PREG_INT_PMCHANGE	0x00000008	/* Change in power mng state */
2881ac8d5baSMatthew Dillon #define SILI_PREG_INT_PHYRDYCHG	0x00000010	/* Mirrors DIAG.N in SError  */
2891ac8d5baSMatthew Dillon #define SILI_PREG_INT_COMWAKE	0x00000020	/* Mirrors DIAG.W in SError  */
2901ac8d5baSMatthew Dillon #define SILI_PREG_INT_UNRECFIS	0x00000040	/* Mirrors DIAG.F in SError  */
2911ac8d5baSMatthew Dillon #define SILI_PREG_INT_DEVEXCHG	0x00000080	/* Mirrors DIAG.X in SError  */
2921ac8d5baSMatthew Dillon #define SILI_PREG_INT_DECODE	0x00000100	/* 8b/10b dec err  cnt > thr */
2931ac8d5baSMatthew Dillon #define SILI_PREG_INT_CRC	0x00000200	/* CRC err       count > thr */
2941ac8d5baSMatthew Dillon #define SILI_PREG_INT_HANDSHK	0x00000400	/* Handshake err count > thr */
2951ac8d5baSMatthew Dillon #define SILI_PREG_INT_SDB	0x00000800	/* Set Device Bits (SNotify) */
2961ac8d5baSMatthew Dillon #define SILI_PREG_INT_SHIFT	16		/* shift upper bits of status*/
2971ac8d5baSMatthew Dillon 
2981ac8d5baSMatthew Dillon #define SILI_PREG_IST_CCOMPLETE	0x00010000	/* one or more cmds completed*/
2991ac8d5baSMatthew Dillon #define SILI_PREG_IST_CERROR	0x00020000	/* read port error register  */
3001ac8d5baSMatthew Dillon 						/* to get error              */
3011ac8d5baSMatthew Dillon #define SILI_PREG_IST_READY	0x00040000	/* Port is ready for cmds    */
3021ac8d5baSMatthew Dillon #define SILI_PREG_IST_PMCHANGE	0x00080000	/* Change in power mng state */
3031ac8d5baSMatthew Dillon #define SILI_PREG_IST_PHYRDYCHG	0x00100000	/* Mirrors DIAG.N in SError  */
3041ac8d5baSMatthew Dillon #define SILI_PREG_IST_COMWAKE	0x00200000	/* Mirrors DIAG.W in SError  */
3051ac8d5baSMatthew Dillon #define SILI_PREG_IST_UNRECFIS	0x00400000	/* Mirrors DIAG.F in SError  */
3061ac8d5baSMatthew Dillon #define SILI_PREG_IST_DEVEXCHG	0x00800000	/* Mirrors DIAG.X in SError  */
3071ac8d5baSMatthew Dillon #define SILI_PREG_IST_DECODE	0x01000000	/* 8b/10b dec err  cnt > thr */
3081ac8d5baSMatthew Dillon #define SILI_PREG_IST_CRC	0x02000000	/* CRC err       count > thr */
3091ac8d5baSMatthew Dillon #define SILI_PREG_IST_HANDSHK	0x04000000	/* Handshake err count > thr */
3101ac8d5baSMatthew Dillon #define SILI_PREG_IST_SDB	0x08000000	/* Set Device Bits (SNotify) */
3111ac8d5baSMatthew Dillon 
3121ac8d5baSMatthew Dillon #define SILI_PREG_INT_MASK	(SILI_PREG_INT_CCOMPLETE |		\
3131ac8d5baSMatthew Dillon 				 SILI_PREG_INT_CERROR |			\
3141ac8d5baSMatthew Dillon 				 SILI_PREG_INT_READY |			\
3151ac8d5baSMatthew Dillon 				 SILI_PREG_INT_PMCHANGE |		\
3161ac8d5baSMatthew Dillon 				 SILI_PREG_INT_PHYRDYCHG |		\
3171ac8d5baSMatthew Dillon 				 SILI_PREG_INT_COMWAKE |		\
3181ac8d5baSMatthew Dillon 				 SILI_PREG_INT_UNRECFIS |		\
3191ac8d5baSMatthew Dillon 				 SILI_PREG_INT_DEVEXCHG |		\
3201ac8d5baSMatthew Dillon 				 SILI_PREG_INT_DECODE |			\
3211ac8d5baSMatthew Dillon 				 SILI_PREG_INT_CRC |			\
3221ac8d5baSMatthew Dillon 				 SILI_PREG_INT_HANDSHK |		\
3231ac8d5baSMatthew Dillon 				 SILI_PREG_INT_SDB)
3241ac8d5baSMatthew Dillon #define SILI_PREG_IST_MASK	(SILI_PREG_INT_MASK << 16)
3251ac8d5baSMatthew Dillon 
3261ac8d5baSMatthew Dillon #define SILI_PFMT_INT_STATUS	"\020" 			\
3271ac8d5baSMatthew Dillon 				"\034SDB"		\
3281ac8d5baSMatthew Dillon 				"\033HANDSHK"		\
3291ac8d5baSMatthew Dillon 				"\032CRC"		\
3301ac8d5baSMatthew Dillon 				"\031DECODE"		\
3311ac8d5baSMatthew Dillon 				"\030DEVEXCHG"		\
3321ac8d5baSMatthew Dillon 				"\027UNRECFIS"		\
3331ac8d5baSMatthew Dillon 				"\026COMWAKE"		\
3341ac8d5baSMatthew Dillon 				"\025PHYRDYCHG"		\
3351ac8d5baSMatthew Dillon 				"\024PMCHANGE"		\
3361ac8d5baSMatthew Dillon 				"\023READY"		\
3371ac8d5baSMatthew Dillon 				"\022ERROR"		\
3381ac8d5baSMatthew Dillon 				"\021COMPLETE"		\
3391ac8d5baSMatthew Dillon 							\
3401ac8d5baSMatthew Dillon 				"\014SDBm"		\
3411ac8d5baSMatthew Dillon 				"\013HANDSHKm"		\
3421ac8d5baSMatthew Dillon 				"\012CRCm"		\
3431ac8d5baSMatthew Dillon 				"\011DECODEm"		\
3441ac8d5baSMatthew Dillon 				"\010DEVEXCHGm"		\
3451ac8d5baSMatthew Dillon 				"\007UNRECFISm"		\
3461ac8d5baSMatthew Dillon 				"\006COMWAKEm"		\
3471ac8d5baSMatthew Dillon 				"\005PHYRDYCHGm"	\
3481ac8d5baSMatthew Dillon 				"\004PMCHANGEm"		\
3491ac8d5baSMatthew Dillon 				"\003READYm"		\
3501ac8d5baSMatthew Dillon 				"\002ERRORm"		\
3511ac8d5baSMatthew Dillon 				"\001COMPLETEm"
3521ac8d5baSMatthew Dillon 
3531ac8d5baSMatthew Dillon /*
3541ac8d5baSMatthew Dillon  * 32BIT_ACTUA is only used when DMA is 32 bits.  It is typically set to 0.
3551ac8d5baSMatthew Dillon  */
3561ac8d5baSMatthew Dillon #define SILI_PREG_32BIT_ACTUA	0x101C		/* 32b activation upper addr */
3571ac8d5baSMatthew Dillon 
3581ac8d5baSMatthew Dillon /*
3591ac8d5baSMatthew Dillon  * Writing a slot number 0-30 to CMD_FIFO starts the command from LRAM.
3601ac8d5baSMatthew Dillon  */
3611ac8d5baSMatthew Dillon #define SILI_PREG_CMD_FIFO	0x1020		/* Command execution FIFO    */
3621ac8d5baSMatthew Dillon 
3631ac8d5baSMatthew Dillon /*
3641ac8d5baSMatthew Dillon  * If the port is interrupted via INT_CERROR this register contains
3651ac8d5baSMatthew Dillon  * the error code.
3661ac8d5baSMatthew Dillon  *
3671ac8d5baSMatthew Dillon  * Most errors write the task file register back to the PRB slot for host
3681ac8d5baSMatthew Dillon  * scrutiny.
3691ac8d5baSMatthew Dillon  */
3701ac8d5baSMatthew Dillon #define SILI_PREG_CERROR	0x1024		/* Command error             */
3711ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DEVICE		1	/* ERR set in D2H FIS        */
3721ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SDBERROR	2	/* ERR set in SDB from device*/
3731ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DATAFISERR	3	/* Sil3132 error on send     */
3741ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SENDFISERR	4	/* Sil3132 error on send     */
3751ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_BADSTATE	5	/* Sil3132 inconsistency     */
3761ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_DIRECTION	6	/* DMA direction mismatch    */
3771ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_UNDERRUN	7	/* DMA SG H2D list too small */
3781ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_OVERRUN	8	/* DMA SG D2H list too small */
3791ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_LLOVERUN	9	/* Too much data from device */
3801ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PKTPROTO	11	/* Packet protocol error     */
3811ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_BADALIGN	16	/* Bad SG list, not 8-byte   */
3821ac8d5baSMatthew Dillon 						/* aligned                   */
3831ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT	17	/* PCI target abort received */
3841ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT	18	/* PCI master abort received */
3851ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIPARABRT	19	/* PCI parity abort received */
3861ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PRBALIGN	24	/* PRB addr not 8-byte algned*/
3871ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT2	25	/* During fetch of PRB       */
3881ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT2	26	/* During fetch of PRB       */
3891ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIPARABRT3	33	/* During data transfer      */
3901ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCITGTABRT3	34	/* During data transfer      */
3911ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_PCIMASABRT3	35	/* During data transfer      */
3921ac8d5baSMatthew Dillon #define SILI_PREG_CERROR_SERVICE	36	/* FIS received during tx    */
3931ac8d5baSMatthew Dillon 						/* phase                     */
3941ac8d5baSMatthew Dillon 
3951ac8d5baSMatthew Dillon /*
3961ac8d5baSMatthew Dillon  * Port FIS Configuration.  Fir each possible FIS type, a 2-bit code
3971ac8d5baSMatthew Dillon  * defines the desired reception behavior as follows.  Bits [1:0] define
3981ac8d5baSMatthew Dillon  * the code for all other FIS types not defined by [29:2].
3991ac8d5baSMatthew Dillon  *
4001ac8d5baSMatthew Dillon  *	00 Accept FIS without interlock
4011ac8d5baSMatthew Dillon  *	01 Reject FIS without interlock
4021ac8d5baSMatthew Dillon  *	10 Interlock FIS
4031ac8d5baSMatthew Dillon  *	11 (reserved)
4041ac8d5baSMatthew Dillon  *
4051ac8d5baSMatthew Dillon  * FIS Code	Name			Start	Default
4061ac8d5baSMatthew Dillon  * --------	------			------	-------
4071ac8d5baSMatthew Dillon  *    ----	(reserved)		30
4081ac8d5baSMatthew Dillon  *    0x27	Register (H2D)		28	01
4091ac8d5baSMatthew Dillon  *    0x34	Register (D2H)		26	00
4101ac8d5baSMatthew Dillon  *    0x39	DMA Activate		24	00
4111ac8d5baSMatthew Dillon  *    0x41	DMA Setup		22	00
4121ac8d5baSMatthew Dillon  *    0x46	Data			20	00
4131ac8d5baSMatthew Dillon  *    0x58	BIST Activate		18	00
4141ac8d5baSMatthew Dillon  *    0x5F	PIO Setup		16	00
4151ac8d5baSMatthew Dillon  *    0xA1	Set Device Bits		14	00
4161ac8d5baSMatthew Dillon  *    0xA6	(reserved)		12	01
4171ac8d5baSMatthew Dillon  *    0xB8	(reserved)		10	01
4181ac8d5baSMatthew Dillon  *    0xBF	(reserved)		8	01
4191ac8d5baSMatthew Dillon  *    0xC7	(reserved)		6	01
4201ac8d5baSMatthew Dillon  *    0xD4	(reserved)		4	01
4211ac8d5baSMatthew Dillon  *    0xD9	(reserved)		2	01
4221ac8d5baSMatthew Dillon  * ALL OTHERS	(reserved)		0	01
4231ac8d5baSMatthew Dillon  */
4241ac8d5baSMatthew Dillon #define SILI_PREG_FIS_CONFIG	0x1028		/* FIS configuration         */
4251ac8d5baSMatthew Dillon 
4261ac8d5baSMatthew Dillon /*
4271ac8d5baSMatthew Dillon  * The data FIFO is 2KBytes in each direction.
4281ac8d5baSMatthew Dillon  *
4291ac8d5baSMatthew Dillon  * When DMAing from the device the Write Request Threshold is used.
4301ac8d5baSMatthew Dillon  * When DMAing to the device the Read Request Threshold is used.
4311ac8d5baSMatthew Dillon  *
4321ac8d5baSMatthew Dillon  * The threshold can be set from 1-2040 bytes (write 0-2039), in multiples
4331ac8d5baSMatthew Dillon  * of 8 bits.  The low 3 bits are hardwired to 0.  A value of 0 causes a
4341ac8d5baSMatthew Dillon  * request whenever possible.
4351ac8d5baSMatthew Dillon  */
4361ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL	0x102C		/* PCIex request FIFO thresh */
4371ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_READ_SHIFT	0
4381ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_WRITE_SHIFT	16
4391ac8d5baSMatthew Dillon #define SILI_PREG_FIFO_CTL_MASK	0xFF
4402102f407SMatthew Dillon #define SILI_PREG_FIFO_CTL_ENCODE(rlevel, wlevel)  (rlevel | (wlevel << 16))
4411ac8d5baSMatthew Dillon 
4421ac8d5baSMatthew Dillon /*
4431ac8d5baSMatthew Dillon  * Error counters and thresholds.  The counter occupies the low 16 bits
4441ac8d5baSMatthew Dillon  * and the threshold occupies the high 16 bits.  The appropriate interrupt
4451ac8d5baSMatthew Dillon  * occurs when the counter exceeds the threshold.  Clearing the interrupt
4461ac8d5baSMatthew Dillon  * clears the counter as well.  A threshold of 0 disables the interrupt
4471ac8d5baSMatthew Dillon  * assertion and masks the interrupt status bit in the port interrupt status
4481ac8d5baSMatthew Dillon  * register.
4491ac8d5baSMatthew Dillon  */
4501ac8d5baSMatthew Dillon #define SILI_PREG_CTR_DECODE	0x1040		/* 8B/10B Decode Error Ctr   */
4511ac8d5baSMatthew Dillon #define SILI_PREG_CTR_CRC	0x1044		/* CRC Error Counter         */
4521ac8d5baSMatthew Dillon #define SILI_PREG_CTR_HANDSHK	0x1048		/* Handshake Error Counter   */
4531ac8d5baSMatthew Dillon 
4541ac8d5baSMatthew Dillon /*
4551ac8d5baSMatthew Dillon  * NOTE: This register is reset only by the global reset and will not be
4561ac8d5baSMatthew Dillon  * 	 reset by a port reset.
4571ac8d5baSMatthew Dillon  *
4581ac8d5baSMatthew Dillon  * NOTE: Bits 15:5 configure the PHY and should not be changed unless you
4591ac8d5baSMatthew Dillon  *	 want to blow up the part.
4601ac8d5baSMatthew Dillon  *
4611ac8d5baSMatthew Dillon  *	 Bits 4:0 define the nominal output swing for the transmitter
4621ac8d5baSMatthew Dillon  *	 and are set to 0x0C by default.  Generally speaking, don't mess
4631ac8d5baSMatthew Dillon  *	 with them.
4641ac8d5baSMatthew Dillon  */
4651ac8d5baSMatthew Dillon #define SILI_PREG_PHY_CONFIG	0x1050		/* Handshake Error Counter   */
4661ac8d5baSMatthew Dillon #define SILI_PREG_PHY_CONFIG_AMP_MASK	0x1F
4671ac8d5baSMatthew Dillon 
4681ac8d5baSMatthew Dillon #define SILI_PREG_SLOTST	0x1800		/* Slot Status		     */
4691ac8d5baSMatthew Dillon #define SILI_PREG_SLOTST_ATTN	0x80000000	/* 0-30 bit for each slot */
4701ac8d5baSMatthew Dillon 
4711ac8d5baSMatthew Dillon /*
4721ac8d5baSMatthew Dillon  * Shadow command activation register, shadows low or high 32 bits
4731ac8d5baSMatthew Dillon  * of actual command activation register.
4741ac8d5baSMatthew Dillon  */
4752102f407SMatthew Dillon #define SILI_PREG_CMDACT(n)	(0x1C00 + (8 * (n)))
4761ac8d5baSMatthew Dillon 
4771ac8d5baSMatthew Dillon /*
4781ac8d5baSMatthew Dillon  * Port Context Register.  Contains the port multipler target (0-15) and
4791ac8d5baSMatthew Dillon  * the command slot (0-31) for the PM port state machine.
4801ac8d5baSMatthew Dillon  *
4811ac8d5baSMatthew Dillon  * Upon a processing halt due to a device specific error, the port multipler
4821ac8d5baSMatthew Dillon  * target is the one that returned the error status.
4831ac8d5baSMatthew Dillon  *
4841ac8d5baSMatthew Dillon  * The command slot is NOT deterministic in this case and should not be
4851ac8d5baSMatthew Dillon  * assumed valid.  Use READ LOG EXTENDED to determine the tag number.
4861ac8d5baSMatthew Dillon  * However, the documentation does appear to indicate that for non-NCQ
4871ac8d5baSMatthew Dillon  * errors the command slot does contain the tag that errored (since there
4881ac8d5baSMatthew Dillon  * will be only one truely active).
4891ac8d5baSMatthew Dillon  */
4901ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT		0x1E04
4911ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_SLOT_MASK	0x1F
4921ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_PMPORT_MASK	0x0F
4931ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_SLOT_SHIFT	0
4941ac8d5baSMatthew Dillon #define SILI_PREG_CONTEXT_PMPORT_SHIFT	5
4951ac8d5baSMatthew Dillon 
4961ac8d5baSMatthew Dillon /*
4971ac8d5baSMatthew Dillon  * SControl register - power management, speed negotiation, and COMRESET
4981ac8d5baSMatthew Dillon  *		       operation.
4991ac8d5baSMatthew Dillon  */
5001ac8d5baSMatthew Dillon #define SILI_PREG_SCTL			0x1F00
5011ac8d5baSMatthew Dillon 
5021ac8d5baSMatthew Dillon /*
5031ac8d5baSMatthew Dillon  * PMP: Identify the PM port for accessing the SActive register and some
5041ac8d5baSMatthew Dillon  *	bit fields of the Diagnostic registers.
5051ac8d5baSMatthew Dillon  */
5061ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_PMP		0x000F0000
5071ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_PMP_SHIFT	16
5081ac8d5baSMatthew Dillon 
5091ac8d5baSMatthew Dillon /*
5101ac8d5baSMatthew Dillon  * SPM: It is unclear from mode 4 is.  "Transition from a power management
5111ac8d5baSMatthew Dillon  *	state initiate (ComWake asserted)".  When setting a state, the field
5121ac8d5baSMatthew Dillon  *	will self-reset to 0 as soon as the action is initiated.
5131ac8d5baSMatthew Dillon  */
5141ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_SPM		0x0000F000
5151ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_SPM_NONE	0x00000000
5161ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_SPM_PARTIAL	0x00010000
5171ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_SPM_SLUMBER	0x00020000
5181ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_SPM_FROM	0x00040000
5191ac8d5baSMatthew Dillon 
5201ac8d5baSMatthew Dillon /*
5211ac8d5baSMatthew Dillon  * IPM: Identify interface power management states not supported (bits).
5221ac8d5baSMatthew Dillon  */
5231ac8d5baSMatthew Dillon #define SILI_PREG_SCTL_IPM		0x00000F00
5241ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_IPM_NONE	0x00000000
5251ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_IPM_NPARTIAL	0x00000100
5261ac8d5baSMatthew Dillon #define  SILI_PREG_SCTL_IPM_NSLUMBER	0x00000200
5271ac8d5baSMatthew Dillon 
5281ac8d5baSMatthew Dillon /*
5291ac8d5baSMatthew Dillon  * SPD: Limit speed negotiation (0000 for no restrictions)
5301ac8d5baSMatthew Dillon  */
5311ac8d5baSMatthew Dillon #define	SILI_PREG_SCTL_SPD		0x000000F0
5321ac8d5baSMatthew Dillon #define	 SILI_PREG_SCTL_SPD_NONE	0x00000000
5331ac8d5baSMatthew Dillon #define	 SILI_PREG_SCTL_SPD_GEN1	0x00000010
5341ac8d5baSMatthew Dillon #define	 SILI_PREG_SCTL_SPD_GEN2	0x00000020
5351ac8d5baSMatthew Dillon 
5361ac8d5baSMatthew Dillon /*
5371ac8d5baSMatthew Dillon  * DET: Control host adapter device detection and interface initialization
5381ac8d5baSMatthew Dillon  */
5391ac8d5baSMatthew Dillon #define	SILI_PREG_SCTL_DET		0x0000000F
5401ac8d5baSMatthew Dillon #define	 SILI_PREG_SCTL_DET_NONE	0x00000000	/* nop/complete     */
5411ac8d5baSMatthew Dillon #define	 SILI_PREG_SCTL_DET_INIT	0x00000001	/* hold in COMRESET */
5421ac8d5baSMatthew Dillon 
5431ac8d5baSMatthew Dillon /*
5441ac8d5baSMatthew Dillon  * SStatus register - Probe status
5451ac8d5baSMatthew Dillon  */
5461ac8d5baSMatthew Dillon #define SILI_PREG_SSTS			0x1F04
5471ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_IPM		0x00000F00
5481ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_IPM_NOCOMM	0x00000000
5491ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_IPM_ACTIVE	0x00000100
5501ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_IPM_PARTIAL	0x00000200
5511ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_IPM_SLUMBER	0x00000600
5521ac8d5baSMatthew Dillon 
5531ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_SPD		0x000000F0
5541ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_SPD_NONE	0x00000000
5551ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_SPD_GEN1	0x00000010
5561ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_SPD_GEN2	0x00000020
5571ac8d5baSMatthew Dillon 
5581ac8d5baSMatthew Dillon #define SILI_PREG_SSTS_DET		0x0000000F
5591ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_DET_NOPHY	0x00000000	/* no dev, no phy */
5601ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_DET_DEV_NE	0x00000001	/* dev, no phy	*/
5611ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_DET_DEV		0x00000003	/* dev and phy	*/
5621ac8d5baSMatthew Dillon #define  SILI_PREG_SSTS_DET_OFFLINE	0x00000004	/* BIST/LOOPBACK */
5631ac8d5baSMatthew Dillon 
5641ac8d5baSMatthew Dillon /*
5651ac8d5baSMatthew Dillon  * These are mostly R/W1C bits.  "B", "C", and "H" operate independantly
5661ac8d5baSMatthew Dillon  * and depend on the corresponding error counter register.
5671ac8d5baSMatthew Dillon  */
5681ac8d5baSMatthew Dillon #define SILI_PREG_SERR			0x1F08
5691ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_I		(1<<0) /* Recovered Data Integrity */
5701ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_M		(1<<1) /* Recovered Communications */
5711ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_T		(1<<8) /* Transient Data Integrity */
5721ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_C		(1<<9) /* Persistent Comm/Data */
5731ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_P		(1<<10) /* Protocol */
5741ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_ERR_E		(1<<11) /* Internal */
5751ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_N		(1<<16) /* PhyRdy Change */
5761ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_I		(1<<17) /* Phy Internal Error */
5771ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_W		(1<<18) /* Comm Wake */
5781ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_B		(1<<19) /* 10B to 8B Decode Error */
5791ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_D		(1<<20) /* Disparity Error */
5801ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_C		(1<<21) /* CRC Error */
5811ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_H		(1<<22) /* Handshake Error */
5821ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_S		(1<<23) /* Link Sequence Error */
5831ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_T		(1<<24) /* Transport State Trans Err */
5841ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_F		(1<<25) /* Unknown FIS Type */
5851ac8d5baSMatthew Dillon #define  SILI_PREG_SERR_DIAG_X		(1<<26) /* Exchanged */
5861ac8d5baSMatthew Dillon 
5871ac8d5baSMatthew Dillon #define  SILI_PFMT_SERR	"\020" 	\
5881ac8d5baSMatthew Dillon 			"\033DIAG.X" "\032DIAG.F" "\031DIAG.T" "\030DIAG.S" \
5891ac8d5baSMatthew Dillon 			"\027DIAG.H" "\026DIAG.C" "\025DIAG.D" "\024DIAG.B" \
5901ac8d5baSMatthew Dillon 			"\023DIAG.W" "\022DIAG.I" "\021DIAG.N"		    \
5911ac8d5baSMatthew Dillon 			"\014ERR.E" "\013ERR.P" "\012ERR.C" "\011ERR.T"	    \
5921ac8d5baSMatthew Dillon 			"\002ERR.M" "\001ERR.I"
5931ac8d5baSMatthew Dillon 
5941ac8d5baSMatthew Dillon /*
5951ac8d5baSMatthew Dillon  * SACT provides indirect access to the Port Device QActive registers.
5961ac8d5baSMatthew Dillon  * We have direct access and do not have to use this.
5971ac8d5baSMatthew Dillon  */
5981ac8d5baSMatthew Dillon #define SILI_PREG_SACT			0x1F0C
5991ac8d5baSMatthew Dillon 
6001ac8d5baSMatthew Dillon /*
6011ac8d5baSMatthew Dillon  * Indicate which devices have sent a Set Device Bits FIS with Notifcation
6021ac8d5baSMatthew Dillon  * set.  R/W1C
6031ac8d5baSMatthew Dillon  */
6041ac8d5baSMatthew Dillon #define SILI_PREG_SNTF			0x1F10
6051ac8d5baSMatthew Dillon 
6061ac8d5baSMatthew Dillon /*
6071ac8d5baSMatthew Dillon  * Internal register space indirect register access via the PCI I/O space.
6081ac8d5baSMatthew Dillon  * (This is for BIOSes running in 16-bit mode, we use the direct map).
6091ac8d5baSMatthew Dillon  *
6101ac8d5baSMatthew Dillon  * All offsets must be 4-byte aligned
6111ac8d5baSMatthew Dillon  */
6121ac8d5baSMatthew Dillon #define SILI_BAR2_GRO			0x0000	/* Global Register Offset */
6131ac8d5baSMatthew Dillon #define SILI_BAR2_GRD			0x0004	/* Global Register Data */
6141ac8d5baSMatthew Dillon #define SILI_BAR2_PRO			0x0008	/* Port Register Offset */
6151ac8d5baSMatthew Dillon #define SILI_BAR2_PRD			0x000C	/* Port Register Data */
6161ac8d5baSMatthew Dillon 
6171ac8d5baSMatthew Dillon /*
6181ac8d5baSMatthew Dillon  * SILI mapped structures
6191ac8d5baSMatthew Dillon  */
6201ac8d5baSMatthew Dillon struct sili_sge {
6211ac8d5baSMatthew Dillon 	u_int64_t		sge_paddr;
6221ac8d5baSMatthew Dillon 	u_int32_t		sge_count;
6231ac8d5baSMatthew Dillon 	u_int32_t		sge_flags;
6241ac8d5baSMatthew Dillon } __packed;
6251ac8d5baSMatthew Dillon 
6261ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_TRM	0x80000000	/* last SGE associated w/cmd */
6271ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_LNK	0x40000000	/* link to SGE array	*/
6281ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_DRD	0x20000000	/* discard (ign sge_paddr) */
6291ac8d5baSMatthew Dillon #define SILI_SGE_FLAGS_XCF	0x10000000	/* external cmd fetch	*/
6301ac8d5baSMatthew Dillon 
6311ac8d5baSMatthew Dillon /*
632f606d6ecSFrançois Tigeot  * Each sge is 16 bytes.
6332102f407SMatthew Dillon  *
6342102f407SMatthew Dillon  * We want our prb structure to be power-of-2 aligned (it is required to be
6352102f407SMatthew Dillon  * at least 8-byte aligned).  the prb base header is 4 SGE's but includes 2
6362102f407SMatthew Dillon  * SGE's within it.
637f606d6ecSFrançois Tigeot  * The prb structure also can't cross a 64KB boundary, and thus can only
638f606d6ecSFrançois Tigeot  * have a maximum size of 65536 / 16 / 32  == ~128 entries (128 - 4)
6392102f407SMatthew Dillon  */
640f606d6ecSFrançois Tigeot #define SILI_MAX_SGET		(128 - 4)
6412102f407SMatthew Dillon #define SILI_MAX_PMPORTS	16
642f606d6ecSFrançois Tigeot #define SILI_MAXPHYS		(256 * 1024)	/* 256 KB */
6432102f407SMatthew Dillon 
644f606d6ecSFrançois Tigeot #if SILI_MAXPHYS / PAGE_SIZE + 1 > (SILI_MAX_SGET * 3 / 4)
6452102f407SMatthew Dillon #error "SILI_MAX_SGET is not big enough"
6462102f407SMatthew Dillon #endif
6472102f407SMatthew Dillon 
6482102f407SMatthew Dillon 
6492102f407SMatthew Dillon /*
6501ac8d5baSMatthew Dillon  * The PRB
6511ac8d5baSMatthew Dillon  *
6521ac8d5baSMatthew Dillon  * NOTE: ATAPI PACKETS.  The packet is stored in prb_sge[0] and sge[1]
6531ac8d5baSMatthew Dillon  *			 is the first SGE.
6542102f407SMatthew Dillon  *
6552102f407SMatthew Dillon  * NOTE: LRAM PRB.  The PRB layout in the LRAM includes a single struct
6562102f407SMatthew Dillon  *	 sili_sge[4].  We could use the LRAM for the PRB and host memory
6572102f407SMatthew Dillon  *	 for an external SGE array, but LRAM in general has some serious
6582102f407SMatthew Dillon  *	 hardware bugs.
6592102f407SMatthew Dillon  *
6602102f407SMatthew Dillon  *	 From linux: Reading the LRAM for a port while a command is
6612102f407SMatthew Dillon  *	 outstanding can corrupt DMA.  So we use a completely external PRB.
6621ac8d5baSMatthew Dillon  */
6631ac8d5baSMatthew Dillon struct sili_prb {
6641ac8d5baSMatthew Dillon 	u_int16_t		prb_control;
6651ac8d5baSMatthew Dillon 	u_int16_t		prb_override;
6661ac8d5baSMatthew Dillon 	u_int32_t		prb_xfer_count;
6671ac8d5baSMatthew Dillon 	union {
6681ac8d5baSMatthew Dillon 		struct ata_fis_h2d	h2d;
6691ac8d5baSMatthew Dillon 		struct ata_fis_d2h	d2h;
6701ac8d5baSMatthew Dillon 	} prb_fis;
6711ac8d5baSMatthew Dillon 	u_int32_t		prb_reserved1c;
6722102f407SMatthew Dillon 	struct sili_sge		prb_sge_base[2];
6732102f407SMatthew Dillon 	struct sili_sge		prb_sge[SILI_MAX_SGET];
6741ac8d5baSMatthew Dillon } __packed;
6751ac8d5baSMatthew Dillon 
6761ac8d5baSMatthew Dillon #define prb_h2d		prb_fis.h2d
6771ac8d5baSMatthew Dillon #define prb_d2h		prb_fis.d2h
6781ac8d5baSMatthew Dillon #define prb_activation	prb_ext[0].sge_paddr
6791ac8d5baSMatthew Dillon #define prb_packet(prb)	((u_int8_t *)&(prb)->prb_sge[0])
6802102f407SMatthew Dillon #define prb_sge_normal	prb_sge_base[0]
6812102f407SMatthew Dillon #define prb_sge_packet	prb_sge_base[1]
6821ac8d5baSMatthew Dillon 
6831ac8d5baSMatthew Dillon /*
6841ac8d5baSMatthew Dillon  * NOTE: override may be left 0 and the SIL3132 will decode the
6851ac8d5baSMatthew Dillon  *	 8-bit ATA command and use the correct protocol.
6861ac8d5baSMatthew Dillon  */
6871ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_OVERRIDE	0x0001	/* use protocol field override	*/
6881ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_REXMIT	0x0002	/* ok to rexmit ext command	*/
6891ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_EXTCMD	0x0004	/* FIS fetched from host memory */
6901ac8d5baSMatthew Dillon 					/* (else from LRAM)		*/
6911ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_RECEIVE	0x0008	/* Reserve cmd slot to receive	*/
6921ac8d5baSMatthew Dillon 					/* an interlocked FIS		*/
6931ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_READ	0x0010	/* device to host data		*/
6941ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_WRITE	0x0020	/* host to device data		*/
6951ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_NOINT	0x0040	/* do not post int on completion*/
6961ac8d5baSMatthew Dillon #define SILI_PRB_CTRL_SOFTRESET	0x0080	/* issue soft reset (special)	*/
6971ac8d5baSMatthew Dillon 
6981ac8d5baSMatthew Dillon #define SILI_PRB_OVER_ATAPI	0x0001
6991ac8d5baSMatthew Dillon #define SILI_PRB_OVER_ATA	0x0002
7001ac8d5baSMatthew Dillon #define SILI_PRB_OVER_NCQ	0x0004
7011ac8d5baSMatthew Dillon #define SILI_PRB_OVER_READ	0x0008	/* device to host data */
7021ac8d5baSMatthew Dillon #define SILI_PRB_OVER_WRITE	0x0010	/* host to device data */
7031ac8d5baSMatthew Dillon #define SILI_PRB_OVER_RAW	0x0020	/* no protocol special case */
7041ac8d5baSMatthew Dillon 
7051ac8d5baSMatthew Dillon #define SILI_MAX_PORTS		16
7061ac8d5baSMatthew Dillon #define SILI_MAX_CMDS		31	/* not 32 */
7071ac8d5baSMatthew Dillon 
7081ac8d5baSMatthew Dillon struct sili_dmamem {
7091ac8d5baSMatthew Dillon 	bus_dma_tag_t		adm_tag;
7101ac8d5baSMatthew Dillon 	bus_dmamap_t		adm_map;
7111ac8d5baSMatthew Dillon 	bus_dma_segment_t	adm_seg;
7121ac8d5baSMatthew Dillon 	bus_addr_t		adm_busaddr;
7131ac8d5baSMatthew Dillon 	caddr_t			adm_kva;
7141ac8d5baSMatthew Dillon };
7151ac8d5baSMatthew Dillon #define SILI_DMA_MAP(_adm)	((_adm)->adm_map)
7161ac8d5baSMatthew Dillon #define SILI_DMA_DVA(_adm)	((_adm)->adm_busaddr)
7171ac8d5baSMatthew Dillon #define SILI_DMA_KVA(_adm)	((void *)(_adm)->adm_kva)
7181ac8d5baSMatthew Dillon 
7191ac8d5baSMatthew Dillon struct sili_softc;
7201ac8d5baSMatthew Dillon struct sili_port;
7211ac8d5baSMatthew Dillon struct sili_device;
7221ac8d5baSMatthew Dillon 
7231ac8d5baSMatthew Dillon struct sili_ccb {
7241ac8d5baSMatthew Dillon 	/* ATA xfer associated with this CCB.  Must be 1st struct member. */
7251ac8d5baSMatthew Dillon 	struct ata_xfer		ccb_xa;
7261ac8d5baSMatthew Dillon 	struct callout          ccb_timeout;
7271ac8d5baSMatthew Dillon 
7281ac8d5baSMatthew Dillon 	int			ccb_slot;
7291ac8d5baSMatthew Dillon 	struct sili_port	*ccb_port;
7301ac8d5baSMatthew Dillon 
7311ac8d5baSMatthew Dillon 	bus_dmamap_t		ccb_dmamap;
7321ac8d5baSMatthew Dillon 	struct sili_prb		*ccb_prb;
7334383d440SMatthew Dillon 	struct sili_prb		*ccb_prb_lram;
7342102f407SMatthew Dillon 	u_int64_t		ccb_prb_paddr;	/* phys addr of prb */
7351ac8d5baSMatthew Dillon 
7361ac8d5baSMatthew Dillon 	void			(*ccb_done)(struct sili_ccb *);
7371ac8d5baSMatthew Dillon 
7381ac8d5baSMatthew Dillon 	TAILQ_ENTRY(sili_ccb)	ccb_entry;
7391ac8d5baSMatthew Dillon };
7401ac8d5baSMatthew Dillon 
7411ac8d5baSMatthew Dillon struct sili_port {
7421ac8d5baSMatthew Dillon 	struct sili_softc	*ap_sc;
7431ac8d5baSMatthew Dillon 	bus_space_handle_t	ap_ioh;
7441ac8d5baSMatthew Dillon 
7451ac8d5baSMatthew Dillon 	int			ap_num;
7461ac8d5baSMatthew Dillon 	int			ap_pmcount;
7471ac8d5baSMatthew Dillon 	int			ap_flags;
7481ac8d5baSMatthew Dillon #define AP_F_BUS_REGISTERED	0x0001
7491ac8d5baSMatthew Dillon #define AP_F_CAM_ATTACHED	0x0002
7501ac8d5baSMatthew Dillon #define AP_F_IN_RESET		0x0004
7511ac8d5baSMatthew Dillon #define AP_F_SCAN_RUNNING	0x0008
7521ac8d5baSMatthew Dillon #define AP_F_SCAN_REQUESTED	0x0010
7531ac8d5baSMatthew Dillon #define AP_F_SCAN_COMPLETED	0x0020
7541ac8d5baSMatthew Dillon #define AP_F_IGNORE_IFS		0x0040
7554383d440SMatthew Dillon #define AP_F_UNUSED0200		0x0200
7561ac8d5baSMatthew Dillon #define AP_F_ERR_CCB_RESERVED	0x0400
757187cac04SMatthew Dillon #define AP_F_REINIT_ACTIVE	0x0800
7581ac8d5baSMatthew Dillon 	int			ap_signal;	/* os per-port thread sig */
7591ac8d5baSMatthew Dillon 	thread_t		ap_thread;	/* os per-port thread */
7601ac8d5baSMatthew Dillon 	struct lock		ap_lock;	/* os per-port lock */
761fb00c6edSMatthew Dillon 	struct lock		ap_sim_lock;	/* cam sim lock */
762fb00c6edSMatthew Dillon 	struct lock		ap_sig_lock;	/* signal thread */
7631ac8d5baSMatthew Dillon #define AP_SIGF_INIT		0x0001
7641ac8d5baSMatthew Dillon #define AP_SIGF_TIMEOUT		0x0002
7651ac8d5baSMatthew Dillon #define AP_SIGF_PORTINT		0x0004
7661ac8d5baSMatthew Dillon #define AP_SIGF_STOP		0x8000
7671ac8d5baSMatthew Dillon 	struct cam_sim		*ap_sim;
7681ac8d5baSMatthew Dillon 
7692102f407SMatthew Dillon 	struct sili_prb		*ap_prbs;
7701ac8d5baSMatthew Dillon 
7712102f407SMatthew Dillon 	struct sili_dmamem	*ap_dmamem_prbs;/* separate sge tables	*/
7721ac8d5baSMatthew Dillon 
7731ac8d5baSMatthew Dillon 	u_int32_t		ap_active;	/* active bmask		*/
7741ac8d5baSMatthew Dillon 	u_int32_t		ap_active_cnt;	/* active count		*/
7751ac8d5baSMatthew Dillon 	u_int32_t		ap_expired;	/* deferred expired bmask */
7761ac8d5baSMatthew Dillon 	struct sili_ccb		*ap_ccbs;
7771ac8d5baSMatthew Dillon 	struct sili_ccb		*ap_err_ccb;	/* used to read LOG page  */
7786f3b9849SMatthew Dillon 	int			ap_run_flags;	/* used to check excl mode */
7791ac8d5baSMatthew Dillon 
7801ac8d5baSMatthew Dillon 	TAILQ_HEAD(, sili_ccb)	ap_ccb_free;
7811ac8d5baSMatthew Dillon 	TAILQ_HEAD(, sili_ccb)	ap_ccb_pending;
7821ac8d5baSMatthew Dillon 	struct lock		ap_ccb_lock;
7831ac8d5baSMatthew Dillon 
7841ac8d5baSMatthew Dillon 	int			ap_type;	/* ATA_PORT_T_xxx */
7851ac8d5baSMatthew Dillon 	int			ap_probe;	/* ATA_PROBE_xxx */
7861ac8d5baSMatthew Dillon 	struct ata_port		*ap_ata;
7871ac8d5baSMatthew Dillon 
7881ac8d5baSMatthew Dillon 	u_int32_t		ap_state;
7891ac8d5baSMatthew Dillon #define AP_S_NORMAL			0
7901ac8d5baSMatthew Dillon #define AP_S_FATAL_ERROR		1
7911ac8d5baSMatthew Dillon 
7921ac8d5baSMatthew Dillon 	/* For error recovery. */
7936f3b9849SMatthew Dillon 	u_int8_t		*ap_err_scratch;
7941ac8d5baSMatthew Dillon 
7951ac8d5baSMatthew Dillon 	char			ap_name[16];
7961ac8d5baSMatthew Dillon };
7971ac8d5baSMatthew Dillon 
7981ac8d5baSMatthew Dillon #define PORTNAME(_ap)		((_ap)->ap_name)
7991ac8d5baSMatthew Dillon #define ATANAME(_ap, _at)	((_at) ? (_at)->at_name : (_ap)->ap_name)
8001ac8d5baSMatthew Dillon 
8011ac8d5baSMatthew Dillon struct sili_softc {
8021ac8d5baSMatthew Dillon 	device_t		sc_dev;
8031ac8d5baSMatthew Dillon 	const struct sili_device *sc_ad;	/* special casing */
8041ac8d5baSMatthew Dillon 
8051ac8d5baSMatthew Dillon 	struct resource		*sc_irq;	/* bus resources */
8061ac8d5baSMatthew Dillon 	struct resource		*sc_regs;	/* bus resources */
8071ac8d5baSMatthew Dillon 	struct resource		*sc_pregs;	/* bus resources */
8081ac8d5baSMatthew Dillon 	bus_space_tag_t		sc_iot;		/* split from sc_regs */
8091ac8d5baSMatthew Dillon 	bus_space_handle_t	sc_ioh;		/* split from sc_regs */
8101ac8d5baSMatthew Dillon 	bus_space_tag_t		sc_piot;	/* split from sc_pregs */
8111ac8d5baSMatthew Dillon 	bus_space_handle_t	sc_pioh;	/* split from sc_pregs */
8121ac8d5baSMatthew Dillon 
813*c2a27f53SSepherosa Ziehau 	int			sc_irq_type;
8141ac8d5baSMatthew Dillon 	int			sc_rid_irq;	/* saved bus RIDs */
8151ac8d5baSMatthew Dillon 	int			sc_rid_regs;
8161ac8d5baSMatthew Dillon 	int			sc_rid_pregs;
8171ac8d5baSMatthew Dillon 
8181ac8d5baSMatthew Dillon 	void			*sc_irq_handle;	/* installed irq vector */
8191ac8d5baSMatthew Dillon 
8202102f407SMatthew Dillon 	bus_dma_tag_t		sc_tag_prbs;
8211ac8d5baSMatthew Dillon 	bus_dma_tag_t		sc_tag_data;
8221ac8d5baSMatthew Dillon 
8231ac8d5baSMatthew Dillon 	int			sc_flags;
8241ac8d5baSMatthew Dillon #define SILI_F_NO_NCQ			0x0001
8251ac8d5baSMatthew Dillon #define SILI_F_IGN_FR			0x0002
8261ac8d5baSMatthew Dillon #define SILI_F_INT_GOOD			0x0004
8271ac8d5baSMatthew Dillon #define SILI_F_64BIT			0x0008
8281ac8d5baSMatthew Dillon #define SILI_F_300			0x0010
8291ac8d5baSMatthew Dillon #define SILI_F_NCQ			0x0020
8301ac8d5baSMatthew Dillon #define SILI_F_SSNTF			0x0040
8311ac8d5baSMatthew Dillon #define SILI_F_SPM			0x0080
8321ac8d5baSMatthew Dillon 
8331ac8d5baSMatthew Dillon 	u_int			sc_ncmds;	/* max 31, NOT 32 */
8341ac8d5baSMatthew Dillon 
8351ac8d5baSMatthew Dillon 	struct sili_port	*sc_ports[SILI_MAX_PORTS];
8361ac8d5baSMatthew Dillon };
8371ac8d5baSMatthew Dillon #define DEVNAME(_s)		((_s)->sc_dev.dv_xname)
8381ac8d5baSMatthew Dillon 
8391ac8d5baSMatthew Dillon struct sili_device {
8401ac8d5baSMatthew Dillon 	pci_vendor_id_t		ad_vendor;
8411ac8d5baSMatthew Dillon 	pci_product_id_t	ad_product;
8421ac8d5baSMatthew Dillon 	int			ad_nports;
8431ac8d5baSMatthew Dillon 	int			(*ad_attach)(device_t dev);
8441ac8d5baSMatthew Dillon 	int			(*ad_detach)(device_t dev);
8451ac8d5baSMatthew Dillon 	char			*name;
8461ac8d5baSMatthew Dillon };
8471ac8d5baSMatthew Dillon 
848a35ddbb4SMatthew Dillon /* Wait for all bits in _b to be cleared */
849a35ddbb4SMatthew Dillon #define sili_pwait_clr(_ap, _r, _b) \
850a35ddbb4SMatthew Dillon 	sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), 0)
851a35ddbb4SMatthew Dillon #define sili_pwait_clr_to(_ap, _to,  _r, _b) \
852a35ddbb4SMatthew Dillon 	sili_pwait_eq((_ap), _to, (_r), (_b), 0)
853a35ddbb4SMatthew Dillon 
854a35ddbb4SMatthew Dillon /* Wait for all bits in _b to be set */
855a35ddbb4SMatthew Dillon #define sili_pwait_set(_ap, _r, _b) \
856a35ddbb4SMatthew Dillon 	sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), (_b))
857a35ddbb4SMatthew Dillon #define sili_pwait_set_to(_ap, _to, _r, _b) \
858a35ddbb4SMatthew Dillon 	sili_pwait_eq((_ap), _to, (_r), (_b), (_b))
859a35ddbb4SMatthew Dillon 
860187cac04SMatthew Dillon /*
861187cac04SMatthew Dillon  * Misc defines
862187cac04SMatthew Dillon  */
863a35ddbb4SMatthew Dillon #define SILI_PWAIT_TIMEOUT      1000
864a35ddbb4SMatthew Dillon 
865187cac04SMatthew Dillon /*
866187cac04SMatthew Dillon  * Prototypes
867187cac04SMatthew Dillon  */
8681ac8d5baSMatthew Dillon const struct sili_device *sili_lookup_device(device_t dev);
8691ac8d5baSMatthew Dillon int	sili_init(struct sili_softc *);
870a35ddbb4SMatthew Dillon int	sili_port_init(struct sili_port *ap);
8711ac8d5baSMatthew Dillon int	sili_port_alloc(struct sili_softc *, u_int);
8721ac8d5baSMatthew Dillon void	sili_port_state_machine(struct sili_port *ap, int initial);
8731ac8d5baSMatthew Dillon void	sili_port_free(struct sili_softc *, u_int);
8741ac8d5baSMatthew Dillon int	sili_port_reset(struct sili_port *, struct ata_port *at, int);
875187cac04SMatthew Dillon void	sili_exclusive_access(struct sili_port *ap);
8761ac8d5baSMatthew Dillon 
8771ac8d5baSMatthew Dillon u_int32_t sili_read(struct sili_softc *, bus_size_t);
8781ac8d5baSMatthew Dillon void	sili_write(struct sili_softc *, bus_size_t, u_int32_t);
8791ac8d5baSMatthew Dillon int	sili_wait_ne(struct sili_softc *, bus_size_t, u_int32_t, u_int32_t);
8801ac8d5baSMatthew Dillon u_int32_t sili_pread(struct sili_port *, bus_size_t);
8811ac8d5baSMatthew Dillon void	sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
8821ac8d5baSMatthew Dillon int	sili_pwait_eq(struct sili_port *, int, bus_size_t,
8831ac8d5baSMatthew Dillon 			u_int32_t, u_int32_t);
8841ac8d5baSMatthew Dillon void	sili_intr(void *);
8851ac8d5baSMatthew Dillon void	sili_port_intr(struct sili_port *ap, int blockable);
8861ac8d5baSMatthew Dillon 
8871ac8d5baSMatthew Dillon int	sili_cam_attach(struct sili_port *ap);
8881ac8d5baSMatthew Dillon void	sili_cam_changed(struct sili_port *ap, struct ata_port *at, int found);
8891ac8d5baSMatthew Dillon void	sili_cam_detach(struct sili_port *ap);
8901ac8d5baSMatthew Dillon int	sili_cam_probe(struct sili_port *ap, struct ata_port *at);
8911ac8d5baSMatthew Dillon 
8921ac8d5baSMatthew Dillon struct ata_xfer *sili_ata_get_xfer(struct sili_port *ap, struct ata_port *at);
8931ac8d5baSMatthew Dillon void	sili_ata_put_xfer(struct ata_xfer *xa);
8941ac8d5baSMatthew Dillon int	sili_ata_cmd(struct ata_xfer *xa);
8951ac8d5baSMatthew Dillon 
896a35ddbb4SMatthew Dillon int	sili_pm_port_probe(struct sili_port *ap, int);
897a35ddbb4SMatthew Dillon int	sili_pm_port_init(struct sili_port *ap, struct ata_port *at);
8986f3b9849SMatthew Dillon int	sili_pm_identify(struct sili_port *ap);
8991ac8d5baSMatthew Dillon int	sili_pm_set_feature(struct sili_port *ap, int feature, int enable);
9001ac8d5baSMatthew Dillon int	sili_pm_hardreset(struct sili_port *ap, int target, int hard);
9011ac8d5baSMatthew Dillon int	sili_pm_softreset(struct sili_port *ap, int target);
9021ac8d5baSMatthew Dillon int	sili_pm_phy_status(struct sili_port *ap, int target, u_int32_t *datap);
9031ac8d5baSMatthew Dillon int	sili_pm_read(struct sili_port *ap, int target,
9041ac8d5baSMatthew Dillon 			int which, u_int32_t *res);
9051ac8d5baSMatthew Dillon int	sili_pm_write(struct sili_port *ap, int target,
9061ac8d5baSMatthew Dillon 			int which, u_int32_t data);
9071ac8d5baSMatthew Dillon void	sili_pm_check_good(struct sili_port *ap, int target);
9081ac8d5baSMatthew Dillon void	sili_ata_cmd_timeout(struct sili_ccb *ccb);
909a35ddbb4SMatthew Dillon void	sili_quick_timeout(struct sili_ccb *ccb);
9101ac8d5baSMatthew Dillon struct sili_ccb *sili_get_ccb(struct sili_port *ap);
9111ac8d5baSMatthew Dillon void	sili_put_ccb(struct sili_ccb *ccb);
9121ac8d5baSMatthew Dillon struct sili_ccb *sili_get_err_ccb(struct sili_port *);
9131ac8d5baSMatthew Dillon void	sili_put_err_ccb(struct sili_ccb *);
9141ac8d5baSMatthew Dillon int	sili_poll(struct sili_ccb *ccb, int timeout,
9151ac8d5baSMatthew Dillon 			void (*timeout_fn)(struct sili_ccb *));
9161ac8d5baSMatthew Dillon 
9171ac8d5baSMatthew Dillon int     sili_port_signature(struct sili_port *ap, struct ata_port *at,
9181ac8d5baSMatthew Dillon 			u_int32_t sig);
9191ac8d5baSMatthew Dillon void	sili_port_thread_core(struct sili_port *ap, int mask);
9201ac8d5baSMatthew Dillon 
9211ac8d5baSMatthew Dillon void	sili_os_sleep(int ms);
9221ac8d5baSMatthew Dillon void	sili_os_hardsleep(int us);
9231ac8d5baSMatthew Dillon int	sili_os_softsleep(void);
9241ac8d5baSMatthew Dillon void	sili_os_start_port(struct sili_port *ap);
9251ac8d5baSMatthew Dillon void	sili_os_stop_port(struct sili_port *ap);
9261ac8d5baSMatthew Dillon void	sili_os_signal_port_thread(struct sili_port *ap, int mask);
9271ac8d5baSMatthew Dillon void	sili_os_lock_port(struct sili_port *ap);
9281ac8d5baSMatthew Dillon int	sili_os_lock_port_nb(struct sili_port *ap);
9291ac8d5baSMatthew Dillon void	sili_os_unlock_port(struct sili_port *ap);
9301ac8d5baSMatthew Dillon 
9311ac8d5baSMatthew Dillon extern u_int32_t SiliForceGen1;
9321ac8d5baSMatthew Dillon extern u_int32_t SiliNoFeatures;
933