SILI - Minor fixes and adjustments.
[dragonfly.git] / sys / dev / disk / sili / sili.h
CommitLineData
1ac8d5ba
MD
1/*
2 * Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * $OpenBSD: sili.c,v 1.147 2009/02/16 21:19:07 miod Exp $
17 */
18
19#if defined(__DragonFly__)
20#include "sili_dragonfly.h"
21#else
22#error "build for OS unknown"
23#endif
24#include "pmreg.h"
25#include "atascsi.h"
26
27/* change to SILI_DEBUG for dmesg spam */
28#define NO_SILI_DEBUG
29
30#ifdef SILI_DEBUG
31#define DPRINTF(m, f...) do { if ((silidebug & (m)) == (m)) kprintf(f); } \
32 while (0)
33#define SILI_D_TIMEOUT 0x00
34#define SILI_D_VERBOSE 0x01
35#define SILI_D_INTR 0x02
36#define SILI_D_XFER 0x08
37int silidebug = SILI_D_VERBOSE;
38#else
39#define DPRINTF(m, f...)
40#endif
41
42/*
43 * BAR0 - Global Registers 128-byte aligned, 128-byte region
44 * BAR1 - Port Registers and LRAM 32KB-aligned
45 * BAR2 - Indirect I/O registers (we don't use this)
46 */
47
48/*
49 * Port-N Slot Status.
50 *
51 * NOTE: Mirrors SILI_PREG_SLOTST
52 */
53#define SILI_REG_SLOTST(n) (0x0000 + ((n) * 4))
54#define SILI_REG_SLOTST_ATTN 0x80000000 /* attention required */
55
56#define SILI_REG_GCTL 0x0040 /* Global Control */
57#define SILI_REG_GCTL_PORTEN(n) (1 << (n)) /* Port interrupt ena */
58#define SILI_REG_GCTL_300CAP 0x01000000 /* 3Gb/s capable (R) */
59#define SILI_REG_GCTL_I2C_IEN 0x20000000 /* I2C Int enable */
60#define SILI_REG_GCTL_MSIACK 0x40000000 /* MSI Ack W1C */
61#define SILI_REG_GCTL_GRESET 0x80000000 /* global reset */
62
63#define SILI_REG_GINT 0x0044 /* Global Interrupt Status */
64#define SILI_REG_GINT_I2C 0x20000000 /* I2C Int Status */
65#define SILI_REG_GINT_PORTST(n) (1 << (n)) /* Port interrupt stat */
66#define SILI_REG_GINT_PORTMASK 0x0000FFFF
67
68/*
69 * Most bits in phyconf should not be modified. Setting the low four bits
70 * to 1's, all channel Tx outputs spread spectrum clocking.
71 */
72#define SILI_REG_PHYCONF 0x0048 /* PHY Configuration */
73#define SILI_REG_PHYCONF_ALLSS 0x000F /* spread spectrum tx */
74
75/*
76 * BIST_CTL_TEN - Enable data paths for running data loopback BIST
77 * BIST_CTL_TPAT - Select repeating pattern (1) or pseudo-random
78 * pattern (0)
79 * BIST_CTL_RXSEL- Select the rx port for pattern comparison
80 * BIST_CTL_TXSEL- Select the tx ports that transmit loopback data
81 */
82#define SILI_REG_BIST_CTL 0x0050
83#define SILI_REG_BIST_CTL_TEN 0x80000000
84#define SILI_REG_BIST_CTL_TPAT 0x40000000
85#define SILI_REG_BIST_CTL_RXSEL(n) ((n) << 16)
86#define SILI_REG_BIST_CTL_TXSEL(n) (1 << (n))
87
88#define SILI_REG_BIST_PATTERN 0x0054 /* 32 bit pattern */
89
90/*
91 * GOOD is set to 1 on BIST initiation, and reset to 0 on the first
92 * comparison failure.
93 */
94#define SILI_REG_BIST_STATUS 0x0058
95#define SILI_REG_BIST_STATUS_CNT 0x000007FF /* pattern counter */
96#define SILI_REG_BIST_STATUS_GOOD 0x80000000 /* set to 0 on compare fail */
97
98#define SILI_REG_I2C_CTL 0x0060
99#define SILI_REG_I2C_CTL_START 0x00000001
100#define SILI_REG_I2C_CTL_STOP 0x00000002
101#define SILI_REG_I2C_CTL_NACK 0x00000004 /* send nack on data byte rx */
102#define SILI_REG_I2C_CTL_TFDATA 0x00000008 /* set to initiate txfer */
103 /* to/from data buffer */
104#define SILI_REG_I2C_CTL_MABORT 0x00000010 /* set w/STOP to send stop */
105 /* without first xfering a */
106 /* byte */
107#define SILI_REG_I2C_CTL_SCLEN 0x00000020 /* clock-en for master mode */
108#define SILI_REG_I2C_CTL_UNITEN 0x00000040 /* enable controller */
109#define SILI_REG_I2C_CTL_GCALLD 0x00000080 /* Disable detect of a */
110 /* general call address */
111#define SILI_REG_I2C_CTL_TXBEI 0x00000100 /* xmit buffer empty int en */
112#define SILI_REG_I2C_CTL_RXBFI 0x00000200 /* rx buffer full int en */
113#define SILI_REG_I2C_CTL_BERRI 0x00000400 /* bus error int en */
114#define SILI_REG_I2C_CTL_STOPI 0x00000800 /* stop detect int en */
115#define SILI_REG_I2C_CTL_ARBLI 0x00001000 /* arb loss int en */
116#define SILI_REG_I2C_CTL_ARBDI 0x00002000 /* arb detect int en */
117#define SILI_REG_I2C_CTL_UNITRS 0x00004000 /* reset I2C controller */
118#define SILI_REG_I2C_CTL_FASTM 0x00008000 /* 400kbit/s (else 100kbit/s)*/
119
120#define SILI_REG_I2C_STS 0x0064
121#define SILI_REG_I2C_STS_RW 0x00000001
122#define SILI_REG_I2C_STS_ACKSTS 0x00000002 /* ack/nack status(R) last */
123 /* ack or nack sent or rcvd */
124#define SILI_REG_I2C_STS_UNTBSY 0x00000004 /* unit busy (R) */
125#define SILI_REG_I2C_STS_BUSBSY 0x00000008 /* bus busy with activity(R) */
126 /* other then from controller*/
127#define SILI_REG_I2C_STS_STOPDT 0x00000010 /* stop detect (R/W1C) */
128#define SILI_REG_I2C_STS_ARBLD 0x00000020 /* arb loss detect (R/W1C) */
129#define SILI_REG_I2C_STS_TXBED 0x00000040 /* tx buffer empty (R) */
130#define SILI_REG_I2C_STS_RXBFD 0x00000080 /* rx buffer full (R/W1C) */
131#define SILI_REG_I2C_STS_GCALLD 0x00000100 /* Gen Call detect (R/W1C) */
132#define SILI_REG_I2C_STS_SADDRD 0x00000200 /* Slave addr detect (R/W1C) */
133#define SILI_REG_I2C_STS_BERRD 0x00000400 /* Bus error detect (R/W1C) */
134
135#define SILI_REG_I2C_SADDR 0x0068 /* our slave address */
136#define SILI_REG_I2C_SADDR_MASK 0x0000003F /* 6 bits */
137
138#define SILI_REG_I2C_DATA 0x006C /* data buffer (8 bits) */
139
140#define SILI_REG_FLASH_ADDR 0x0070 /* Flash control & addr reg */
141#define SILI_REG_FLASH_ADDR_MEMPRS 0x04000000 /* Flash memory present */
142#define SILI_REG_FLASH_ADDR_GPIOEN 0x80000000 /* use flash data pins for */
143 /* GPIO */
144#define SILI_REG_FLASH_ADDR_MEMST 0x02000000 /* Mem Access Start (R/W) */
145 /* (clears on op complete) */
146#define SILI_REG_FLASH_ADDR_MEMRD 0x01000000 /* 0=write, 1=read */
147#define SILI_REG_FLASH_ADDR_MASK 0x0003FFFF /* 18 bit memory address */
148
149/*
150 * NOTE: In order to set a GPIO pin to read the DATA bit must be written to
151 * 1and the DCTL (drain control) bit must be written to 1 as well
152 * to make it open-drain only (drive on low only).
153 */
154#define SILI_REG_GPIO 0x0074
155#define SILI_REG_GPIO_DATA_SHIFT 0 /* 8 bits Flash or GPIO data */
156#define SILI_REG_GPIO_TDET_SHIFT 8 /* 8 bits transition detect */
157#define SILI_REG_GPIO_DCTL_SHIFT 16 /* 8 bits drain control */
158
159/*
160 * Per-port registers
161 *
162 */
163
164#define SILI_PORT_REGION(port) (8192 * (port))
165#define SILI_PORT_SIZE 8192
166#define SILI_PREG_LRAM 0x0000 /* 0x0000-0x0F7F */
167#define SILI_PREG_LRAM_SLOT(n) (0x0000 + (128 * (n)))
168
169#define SILI_PREG_LRAM_SLOT_FIS 0x0000 /* Current FIS and Control */
170#define SILI_PREG_LRAM_DMA0 0x0020 /* DMA Entry 0 or ATAPI cmd */
171#define SILI_PREG_LRAM_DMA1 0x0030 /* DMA Entry 0 or ATAPI cmd */
172#define SILI_PREG_LRAM_CMDACT 0x0040 /* Cmd Act Reg (actual) 64b */
173#define SILI_PREG_LRAM_DMATAB 0x0040 /* Scatter Gather Table */
174
175/*
176 * Each port has a port status and qactive register for each target behind
177 * the port multiplier, if there is a port multiplier.
178 *
179 * SERVICE - Service received from device, service command from controller
180 * not yet acknowledged.
181 *
182 * LEGACY - One or more legacy queued commands is outstanding.
183 *
184 * NATIVE - One or more NCQ queued commands is outstanding.
185 *
186 * VBSY - A virtual device busy indicating that a command has been issued
187 * to the device and the device has not yet sent the final D2H
188 * register FIS, or that a data transfer is in progress.
189 *
190 * The PM_QACTIVE register contains a demultiplexed bitmap of slots queued
191 * to each target behind the port multiplier.
192 *
193 */
194#define SILI_PREG_PM_STATUS(n) (0x0F80 + (8 * (n)))
195#define SILI_PREG_PM_QACTIVE(n) (0x0F84 + (8 * (n)))
196
197#define SILI_PREG_PM_STATUS_SERVICE 0x00010000 /* Service pending */
198#define SILI_PREG_PM_STATUS_LEGACY 0x00008000 /* Legacy outstanding*/
199#define SILI_PREG_PM_STATUS_NATIVE 0x00004000 /* NCQ outstanding */
200#define SILI_PREG_PM_STATUS_VBSY 0x00002000 /* virtual dev busy */
201#define SILI_PREG_PM_STATUS_EXEC_SHIFT 8 /* last active slot */
202#define SILI_PREG_PM_STATUS_EXEC_MASK 0x1F
203#define SILI_PREG_PM_STATUS_PIO_MASK 0xFF /* last PIO setup */
204
205/*
206 * NOTE: SILI_PREG_STATUS uses the same address as SILI_PREG_CTL_SET,
207 * but for read.
208 */
209#define SILI_PREG_STATUS 0x1000 /* Port Control Status (R) */
210#define SILI_PREG_STATUS_READY 0x80000000 /* Port Ready (R) */
211#define SILI_PREG_STATUS_SLOT 0x001F0000 /* Active Slot (R) */
212#define SILI_PREG_STATUS_SLOT_SHIFT 16 /* Shift value */
213#define SILI_PREG_STATUS_MASK 0x0200FFFF /* see PREG_CTL_xxx */
214
215/*
216 * NOTE: Reset sequence. Set CTL_RESET, Clear CTL_RESET, then Wait for
217 * the port to become ready.
218 *
219 * NOTE: NOAUTOCC. If set to 1 a 1 must be written to the command completion
220 * bit in the port interrupt status register to clear it. When set to
221 * 0 then reading the port slot status register will automatically clear
222 * the command completion interrupt.
223 *
224 * NOTE: ATA16 controls whether a PACKET mode command is 12 or 16 bytes.
225 *
226 * NOTE: RESUME if set to 1 processing is enabled for outstanding commands
227 * to additional targets connected to a port multiplier after a command
228 * error has occured. When set the internal BUSY status will be set
229 * for the target that errored, preventing additional commands from
230 * being sent until a Port Initialize operation is performed.
231 *
232 * NOTE: 32BITDMA if 1 causes a write to the low 32 bits of a Command
233 * Activation register to copy PREG_32BIT_ACTUA to the upper 32
234 * bits and start command execution. If 0 you must write to the
235 * low 32 bits and then the high 32 bits and your write to the
236 * high 32 bits will start command execution.
237 *
238 * NOTE: OOB_BYP is set on global reset and not changed by a port reset.
239 */
240#define SILI_PREG_CTL_SET 0x1000 /* Port Control Set (W1S) */
241#define SILI_PREG_CTL_CLR 0x1004 /* Port Control Clear (W1C) */
242#define SILI_PREG_CTL_RESET 0x00000001 /* Hold port in reset */
243#define SILI_PREG_CTL_DEVRESET 0x00000002 /* Device reset */
244 /* (Self clearing) */
245#define SILI_PREG_CTL_INIT 0x00000004 /* Port initialize */
246 /* (Self clearing) */
247#define SILI_PREG_CTL_NOAUTOCC 0x00000008
248#define SILI_PREG_CTL_NOLED 0x00000010 /* Disable the LED port */
249 /* activity indicator. */
250#define SILI_PREG_CTL_ATA16 0x00000020 /* 0=12 byte 1=16 byte */
251#define SILI_PREG_CTL_RESUME 0x00000040 /* PM special error handling */
252#define SILI_PREG_CTL_TXBIST 0x00000080 /* transmit a BIST FIS */
253#define SILI_PREG_CTL_CONT_DIS 0x00000100 /* no CONT on repeat primitves*/
254#define SILI_PREG_CTL_NOSCRAM 0x00000200 /* Disable link scrambler */
255#define SILI_PREG_CTL_32BITDMA 0x00000400 /* see above */
256#define SILI_PREG_CTL_ACC_ILCK 0x00000800 /* accept interlocked FIS rx */
257 /* (Self clearing) */
258#define SILI_PREG_CTL_REJ_ILCK 0x00001000 /* reject interlocked FIS rx */
259 /* (Self clearing) */
260#define SILI_PREG_CTL_PMA 0x00002000 /* Enable PM support */
261#define SILI_PREG_CTL_AUTO_ILCK 0x00004000 /* Auto interlock accept */
262#define SILI_PREG_CTL_LEDON 0x00008000 /* LED on */
263#define SILI_PREG_CTL_OOB_BYP 0x02000000 /* Bypass OOB initialization */
264
265/*
266 * Status bits in the upper half of the register report the actual condition
267 * while the status bits in the lower half of the register are masked by
268 * the interrupt enable bits or threshold registers. Writing a 1 to either
269 * version will clear it.
270 *
271 * NOTE: The steering bits written to INT_ENABLE will not show up in the
272 * status register. The INT_ENABLE/INT_DISABLE registers are R+W1S
273 * or R+W1C and thus can be read.
274 *
275 * NOTE: PHYRDYCHG, COMWAKE, UNRECFIS, DEVEXCHG: Can be cleared by writing
276 * W1C either here or via the DIAG.xxx bit bit in SError.
277 */
278#define SILI_PREG_INT_STATUS 0x1008 /* Control clear */
279#define SILI_PREG_INT_ENABLE 0x1010 /* Interrupt Enable Set */
280#define SILI_PREG_INT_DISABLE 0x1014 /* Interrupt Enable Clear */
281
282#define SILI_PREG_INT_STEER(n) ((n) << 30) /* Port Int -> INTA...INTD */
283#define SILI_PREG_INT_CCOMPLETE 0x00000001 /* one or more cmds completed*/
284#define SILI_PREG_INT_CERROR 0x00000002 /* read port error register */
285 /* to get error */
286#define SILI_PREG_INT_READY 0x00000004 /* Port is ready for cmds */
287#define SILI_PREG_INT_PMCHANGE 0x00000008 /* Change in power mng state */
288#define SILI_PREG_INT_PHYRDYCHG 0x00000010 /* Mirrors DIAG.N in SError */
289#define SILI_PREG_INT_COMWAKE 0x00000020 /* Mirrors DIAG.W in SError */
290#define SILI_PREG_INT_UNRECFIS 0x00000040 /* Mirrors DIAG.F in SError */
291#define SILI_PREG_INT_DEVEXCHG 0x00000080 /* Mirrors DIAG.X in SError */
292#define SILI_PREG_INT_DECODE 0x00000100 /* 8b/10b dec err cnt > thr */
293#define SILI_PREG_INT_CRC 0x00000200 /* CRC err count > thr */
294#define SILI_PREG_INT_HANDSHK 0x00000400 /* Handshake err count > thr */
295#define SILI_PREG_INT_SDB 0x00000800 /* Set Device Bits (SNotify) */
296#define SILI_PREG_INT_SHIFT 16 /* shift upper bits of status*/
297
298#define SILI_PREG_IST_CCOMPLETE 0x00010000 /* one or more cmds completed*/
299#define SILI_PREG_IST_CERROR 0x00020000 /* read port error register */
300 /* to get error */
301#define SILI_PREG_IST_READY 0x00040000 /* Port is ready for cmds */
302#define SILI_PREG_IST_PMCHANGE 0x00080000 /* Change in power mng state */
303#define SILI_PREG_IST_PHYRDYCHG 0x00100000 /* Mirrors DIAG.N in SError */
304#define SILI_PREG_IST_COMWAKE 0x00200000 /* Mirrors DIAG.W in SError */
305#define SILI_PREG_IST_UNRECFIS 0x00400000 /* Mirrors DIAG.F in SError */
306#define SILI_PREG_IST_DEVEXCHG 0x00800000 /* Mirrors DIAG.X in SError */
307#define SILI_PREG_IST_DECODE 0x01000000 /* 8b/10b dec err cnt > thr */
308#define SILI_PREG_IST_CRC 0x02000000 /* CRC err count > thr */
309#define SILI_PREG_IST_HANDSHK 0x04000000 /* Handshake err count > thr */
310#define SILI_PREG_IST_SDB 0x08000000 /* Set Device Bits (SNotify) */
311
312#define SILI_PREG_INT_MASK (SILI_PREG_INT_CCOMPLETE | \
313 SILI_PREG_INT_CERROR | \
314 SILI_PREG_INT_READY | \
315 SILI_PREG_INT_PMCHANGE | \
316 SILI_PREG_INT_PHYRDYCHG | \
317 SILI_PREG_INT_COMWAKE | \
318 SILI_PREG_INT_UNRECFIS | \
319 SILI_PREG_INT_DEVEXCHG | \
320 SILI_PREG_INT_DECODE | \
321 SILI_PREG_INT_CRC | \
322 SILI_PREG_INT_HANDSHK | \
323 SILI_PREG_INT_SDB)
324#define SILI_PREG_IST_MASK (SILI_PREG_INT_MASK << 16)
325
326#define SILI_PFMT_INT_STATUS "\020" \
327 "\034SDB" \
328 "\033HANDSHK" \
329 "\032CRC" \
330 "\031DECODE" \
331 "\030DEVEXCHG" \
332 "\027UNRECFIS" \
333 "\026COMWAKE" \
334 "\025PHYRDYCHG" \
335 "\024PMCHANGE" \
336 "\023READY" \
337 "\022ERROR" \
338 "\021COMPLETE" \
339 \
340 "\014SDBm" \
341 "\013HANDSHKm" \
342 "\012CRCm" \
343 "\011DECODEm" \
344 "\010DEVEXCHGm" \
345 "\007UNRECFISm" \
346 "\006COMWAKEm" \
347 "\005PHYRDYCHGm" \
348 "\004PMCHANGEm" \
349 "\003READYm" \
350 "\002ERRORm" \
351 "\001COMPLETEm"
352
353/*
354 * 32BIT_ACTUA is only used when DMA is 32 bits. It is typically set to 0.
355 */
356#define SILI_PREG_32BIT_ACTUA 0x101C /* 32b activation upper addr */
357
358/*
359 * Writing a slot number 0-30 to CMD_FIFO starts the command from LRAM.
360 */
361#define SILI_PREG_CMD_FIFO 0x1020 /* Command execution FIFO */
362
363/*
364 * If the port is interrupted via INT_CERROR this register contains
365 * the error code.
366 *
367 * Most errors write the task file register back to the PRB slot for host
368 * scrutiny.
369 */
370#define SILI_PREG_CERROR 0x1024 /* Command error */
371#define SILI_PREG_CERROR_DEVICE 1 /* ERR set in D2H FIS */
372#define SILI_PREG_CERROR_SDBERROR 2 /* ERR set in SDB from device*/
373#define SILI_PREG_CERROR_DATAFISERR 3 /* Sil3132 error on send */
374#define SILI_PREG_CERROR_SENDFISERR 4 /* Sil3132 error on send */
375#define SILI_PREG_CERROR_BADSTATE 5 /* Sil3132 inconsistency */
376#define SILI_PREG_CERROR_DIRECTION 6 /* DMA direction mismatch */
377#define SILI_PREG_CERROR_UNDERRUN 7 /* DMA SG H2D list too small */
378#define SILI_PREG_CERROR_OVERRUN 8 /* DMA SG D2H list too small */
379#define SILI_PREG_CERROR_LLOVERUN 9 /* Too much data from device */
380#define SILI_PREG_CERROR_PKTPROTO 11 /* Packet protocol error */
381#define SILI_PREG_CERROR_BADALIGN 16 /* Bad SG list, not 8-byte */
382 /* aligned */
383#define SILI_PREG_CERROR_PCITGTABRT 17 /* PCI target abort received */
384#define SILI_PREG_CERROR_PCIMASABRT 18 /* PCI master abort received */
385#define SILI_PREG_CERROR_PCIPARABRT 19 /* PCI parity abort received */
386#define SILI_PREG_CERROR_PRBALIGN 24 /* PRB addr not 8-byte algned*/
387#define SILI_PREG_CERROR_PCITGTABRT2 25 /* During fetch of PRB */
388#define SILI_PREG_CERROR_PCIMASABRT2 26 /* During fetch of PRB */
389#define SILI_PREG_CERROR_PCIPARABRT3 33 /* During data transfer */
390#define SILI_PREG_CERROR_PCITGTABRT3 34 /* During data transfer */
391#define SILI_PREG_CERROR_PCIMASABRT3 35 /* During data transfer */
392#define SILI_PREG_CERROR_SERVICE 36 /* FIS received during tx */
393 /* phase */
394
395/*
396 * Port FIS Configuration. Fir each possible FIS type, a 2-bit code
397 * defines the desired reception behavior as follows. Bits [1:0] define
398 * the code for all other FIS types not defined by [29:2].
399 *
400 * 00 Accept FIS without interlock
401 * 01 Reject FIS without interlock
402 * 10 Interlock FIS
403 * 11 (reserved)
404 *
405 * FIS Code Name Start Default
406 * -------- ------ ------ -------
407 * ---- (reserved) 30
408 * 0x27 Register (H2D) 28 01
409 * 0x34 Register (D2H) 26 00
410 * 0x39 DMA Activate 24 00
411 * 0x41 DMA Setup 22 00
412 * 0x46 Data 20 00
413 * 0x58 BIST Activate 18 00
414 * 0x5F PIO Setup 16 00
415 * 0xA1 Set Device Bits 14 00
416 * 0xA6 (reserved) 12 01
417 * 0xB8 (reserved) 10 01
418 * 0xBF (reserved) 8 01
419 * 0xC7 (reserved) 6 01
420 * 0xD4 (reserved) 4 01
421 * 0xD9 (reserved) 2 01
422 * ALL OTHERS (reserved) 0 01
423 */
424#define SILI_PREG_FIS_CONFIG 0x1028 /* FIS configuration */
425
426/*
427 * The data FIFO is 2KBytes in each direction.
428 *
429 * When DMAing from the device the Write Request Threshold is used.
430 * When DMAing to the device the Read Request Threshold is used.
431 *
432 * The threshold can be set from 1-2040 bytes (write 0-2039), in multiples
433 * of 8 bits. The low 3 bits are hardwired to 0. A value of 0 causes a
434 * request whenever possible.
435 */
436#define SILI_PREG_FIFO_CTL 0x102C /* PCIex request FIFO thresh */
437#define SILI_PREG_FIFO_CTL_READ_SHIFT 0
438#define SILI_PREG_FIFO_CTL_WRITE_SHIFT 16
439#define SILI_PREG_FIFO_CTL_MASK 0xFF
2102f407 440#define SILI_PREG_FIFO_CTL_ENCODE(rlevel, wlevel) (rlevel | (wlevel << 16))
1ac8d5ba
MD
441
442/*
443 * Error counters and thresholds. The counter occupies the low 16 bits
444 * and the threshold occupies the high 16 bits. The appropriate interrupt
445 * occurs when the counter exceeds the threshold. Clearing the interrupt
446 * clears the counter as well. A threshold of 0 disables the interrupt
447 * assertion and masks the interrupt status bit in the port interrupt status
448 * register.
449 */
450#define SILI_PREG_CTR_DECODE 0x1040 /* 8B/10B Decode Error Ctr */
451#define SILI_PREG_CTR_CRC 0x1044 /* CRC Error Counter */
452#define SILI_PREG_CTR_HANDSHK 0x1048 /* Handshake Error Counter */
453
454/*
455 * NOTE: This register is reset only by the global reset and will not be
456 * reset by a port reset.
457 *
458 * NOTE: Bits 15:5 configure the PHY and should not be changed unless you
459 * want to blow up the part.
460 *
461 * Bits 4:0 define the nominal output swing for the transmitter
462 * and are set to 0x0C by default. Generally speaking, don't mess
463 * with them.
464 */
465#define SILI_PREG_PHY_CONFIG 0x1050 /* Handshake Error Counter */
466#define SILI_PREG_PHY_CONFIG_AMP_MASK 0x1F
467
468#define SILI_PREG_SLOTST 0x1800 /* Slot Status */
469#define SILI_PREG_SLOTST_ATTN 0x80000000 /* 0-30 bit for each slot */
470
471/*
472 * Shadow command activation register, shadows low or high 32 bits
473 * of actual command activation register.
474 */
2102f407 475#define SILI_PREG_CMDACT(n) (0x1C00 + (8 * (n)))
1ac8d5ba
MD
476
477/*
478 * Port Context Register. Contains the port multipler target (0-15) and
479 * the command slot (0-31) for the PM port state machine.
480 *
481 * Upon a processing halt due to a device specific error, the port multipler
482 * target is the one that returned the error status.
483 *
484 * The command slot is NOT deterministic in this case and should not be
485 * assumed valid. Use READ LOG EXTENDED to determine the tag number.
486 * However, the documentation does appear to indicate that for non-NCQ
487 * errors the command slot does contain the tag that errored (since there
488 * will be only one truely active).
489 */
490#define SILI_PREG_CONTEXT 0x1E04
491#define SILI_PREG_CONTEXT_SLOT_MASK 0x1F
492#define SILI_PREG_CONTEXT_PMPORT_MASK 0x0F
493#define SILI_PREG_CONTEXT_SLOT_SHIFT 0
494#define SILI_PREG_CONTEXT_PMPORT_SHIFT 5
495
496/*
497 * SControl register - power management, speed negotiation, and COMRESET
498 * operation.
499 */
500#define SILI_PREG_SCTL 0x1F00
501
502/*
503 * PMP: Identify the PM port for accessing the SActive register and some
504 * bit fields of the Diagnostic registers.
505 */
506#define SILI_PREG_SCTL_PMP 0x000F0000
507#define SILI_PREG_SCTL_PMP_SHIFT 16
508
509/*
510 * SPM: It is unclear from mode 4 is. "Transition from a power management
511 * state initiate (ComWake asserted)". When setting a state, the field
512 * will self-reset to 0 as soon as the action is initiated.
513 */
514#define SILI_PREG_SCTL_SPM 0x0000F000
515#define SILI_PREG_SCTL_SPM_NONE 0x00000000
516#define SILI_PREG_SCTL_SPM_PARTIAL 0x00010000
517#define SILI_PREG_SCTL_SPM_SLUMBER 0x00020000
518#define SILI_PREG_SCTL_SPM_FROM 0x00040000
519
520/*
521 * IPM: Identify interface power management states not supported (bits).
522 */
523#define SILI_PREG_SCTL_IPM 0x00000F00
524#define SILI_PREG_SCTL_IPM_NONE 0x00000000
525#define SILI_PREG_SCTL_IPM_NPARTIAL 0x00000100
526#define SILI_PREG_SCTL_IPM_NSLUMBER 0x00000200
527
528/*
529 * SPD: Limit speed negotiation (0000 for no restrictions)
530 */
531#define SILI_PREG_SCTL_SPD 0x000000F0
532#define SILI_PREG_SCTL_SPD_NONE 0x00000000
533#define SILI_PREG_SCTL_SPD_GEN1 0x00000010
534#define SILI_PREG_SCTL_SPD_GEN2 0x00000020
535
536/*
537 * DET: Control host adapter device detection and interface initialization
538 */
539#define SILI_PREG_SCTL_DET 0x0000000F
540#define SILI_PREG_SCTL_DET_NONE 0x00000000 /* nop/complete */
541#define SILI_PREG_SCTL_DET_INIT 0x00000001 /* hold in COMRESET */
542
543/*
544 * SStatus register - Probe status
545 */
546#define SILI_PREG_SSTS 0x1F04
547#define SILI_PREG_SSTS_IPM 0x00000F00
548#define SILI_PREG_SSTS_IPM_NOCOMM 0x00000000
549#define SILI_PREG_SSTS_IPM_ACTIVE 0x00000100
550#define SILI_PREG_SSTS_IPM_PARTIAL 0x00000200
551#define SILI_PREG_SSTS_IPM_SLUMBER 0x00000600
552
553#define SILI_PREG_SSTS_SPD 0x000000F0
554#define SILI_PREG_SSTS_SPD_NONE 0x00000000
555#define SILI_PREG_SSTS_SPD_GEN1 0x00000010
556#define SILI_PREG_SSTS_SPD_GEN2 0x00000020
557
558#define SILI_PREG_SSTS_DET 0x0000000F
559#define SILI_PREG_SSTS_DET_NOPHY 0x00000000 /* no dev, no phy */
560#define SILI_PREG_SSTS_DET_DEV_NE 0x00000001 /* dev, no phy */
561#define SILI_PREG_SSTS_DET_DEV 0x00000003 /* dev and phy */
562#define SILI_PREG_SSTS_DET_OFFLINE 0x00000004 /* BIST/LOOPBACK */
563
564/*
565 * These are mostly R/W1C bits. "B", "C", and "H" operate independantly
566 * and depend on the corresponding error counter register.
567 */
568#define SILI_PREG_SERR 0x1F08
569#define SILI_PREG_SERR_ERR_I (1<<0) /* Recovered Data Integrity */
570#define SILI_PREG_SERR_ERR_M (1<<1) /* Recovered Communications */
571#define SILI_PREG_SERR_ERR_T (1<<8) /* Transient Data Integrity */
572#define SILI_PREG_SERR_ERR_C (1<<9) /* Persistent Comm/Data */
573#define SILI_PREG_SERR_ERR_P (1<<10) /* Protocol */
574#define SILI_PREG_SERR_ERR_E (1<<11) /* Internal */
575#define SILI_PREG_SERR_DIAG_N (1<<16) /* PhyRdy Change */
576#define SILI_PREG_SERR_DIAG_I (1<<17) /* Phy Internal Error */
577#define SILI_PREG_SERR_DIAG_W (1<<18) /* Comm Wake */
578#define SILI_PREG_SERR_DIAG_B (1<<19) /* 10B to 8B Decode Error */
579#define SILI_PREG_SERR_DIAG_D (1<<20) /* Disparity Error */
580#define SILI_PREG_SERR_DIAG_C (1<<21) /* CRC Error */
581#define SILI_PREG_SERR_DIAG_H (1<<22) /* Handshake Error */
582#define SILI_PREG_SERR_DIAG_S (1<<23) /* Link Sequence Error */
583#define SILI_PREG_SERR_DIAG_T (1<<24) /* Transport State Trans Err */
584#define SILI_PREG_SERR_DIAG_F (1<<25) /* Unknown FIS Type */
585#define SILI_PREG_SERR_DIAG_X (1<<26) /* Exchanged */
586
587#define SILI_PFMT_SERR "\020" \
588 "\033DIAG.X" "\032DIAG.F" "\031DIAG.T" "\030DIAG.S" \
589 "\027DIAG.H" "\026DIAG.C" "\025DIAG.D" "\024DIAG.B" \
590 "\023DIAG.W" "\022DIAG.I" "\021DIAG.N" \
591 "\014ERR.E" "\013ERR.P" "\012ERR.C" "\011ERR.T" \
592 "\002ERR.M" "\001ERR.I"
593
594/*
595 * SACT provides indirect access to the Port Device QActive registers.
596 * We have direct access and do not have to use this.
597 */
598#define SILI_PREG_SACT 0x1F0C
599
600/*
601 * Indicate which devices have sent a Set Device Bits FIS with Notifcation
602 * set. R/W1C
603 */
604#define SILI_PREG_SNTF 0x1F10
605
606/*
607 * Internal register space indirect register access via the PCI I/O space.
608 * (This is for BIOSes running in 16-bit mode, we use the direct map).
609 *
610 * All offsets must be 4-byte aligned
611 */
612#define SILI_BAR2_GRO 0x0000 /* Global Register Offset */
613#define SILI_BAR2_GRD 0x0004 /* Global Register Data */
614#define SILI_BAR2_PRO 0x0008 /* Port Register Offset */
615#define SILI_BAR2_PRD 0x000C /* Port Register Data */
616
617/*
618 * SILI mapped structures
619 */
620struct sili_sge {
621 u_int64_t sge_paddr;
622 u_int32_t sge_count;
623 u_int32_t sge_flags;
624} __packed;
625
626#define SILI_SGE_FLAGS_TRM 0x80000000 /* last SGE associated w/cmd */
627#define SILI_SGE_FLAGS_LNK 0x40000000 /* link to SGE array */
628#define SILI_SGE_FLAGS_DRD 0x20000000 /* discard (ign sge_paddr) */
629#define SILI_SGE_FLAGS_XCF 0x10000000 /* external cmd fetch */
630
631/*
2102f407
MD
632 * Each sge is 16 bytes. We need to accomodate MAXPHYS (128K) which is
633 * at least 32 entries, plus one for page slop, plus one more for every
634 * 3 entries for the link entry.
635 *
636 * We want our prb structure to be power-of-2 aligned (it is required to be
637 * at least 8-byte aligned). the prb base header is 4 SGE's but includes 2
638 * SGE's within it.
639 */
640#define SILI_MAX_SGET (64 - 4)
641#define SILI_MAX_PMPORTS 16
642
643#if MAXPHYS / PAGE_SIZE + 1 > (SILI_MAX_SGET * 3 / 4)
644#error "SILI_MAX_SGET is not big enough"
645#endif
646
647
648/*
1ac8d5ba
MD
649 * The PRB
650 *
651 * NOTE: ATAPI PACKETS. The packet is stored in prb_sge[0] and sge[1]
652 * is the first SGE.
2102f407
MD
653 *
654 * NOTE: LRAM PRB. The PRB layout in the LRAM includes a single struct
655 * sili_sge[4]. We could use the LRAM for the PRB and host memory
656 * for an external SGE array, but LRAM in general has some serious
657 * hardware bugs.
658 *
659 * From linux: Reading the LRAM for a port while a command is
660 * outstanding can corrupt DMA. So we use a completely external PRB.
1ac8d5ba
MD
661 */
662struct sili_prb {
663 u_int16_t prb_control;
664 u_int16_t prb_override;
665 u_int32_t prb_xfer_count;
666 union {
667 struct ata_fis_h2d h2d;
668 struct ata_fis_d2h d2h;
669 } prb_fis;
670 u_int32_t prb_reserved1c;
2102f407
MD
671 struct sili_sge prb_sge_base[2];
672 struct sili_sge prb_sge[SILI_MAX_SGET];
1ac8d5ba
MD
673} __packed;
674
675#define prb_h2d prb_fis.h2d
676#define prb_d2h prb_fis.d2h
677#define prb_activation prb_ext[0].sge_paddr
678#define prb_packet(prb) ((u_int8_t *)&(prb)->prb_sge[0])
2102f407
MD
679#define prb_sge_normal prb_sge_base[0]
680#define prb_sge_packet prb_sge_base[1]
1ac8d5ba
MD
681
682/*
683 * NOTE: override may be left 0 and the SIL3132 will decode the
684 * 8-bit ATA command and use the correct protocol.
685 */
686#define SILI_PRB_CTRL_OVERRIDE 0x0001 /* use protocol field override */
687#define SILI_PRB_CTRL_REXMIT 0x0002 /* ok to rexmit ext command */
688#define SILI_PRB_CTRL_EXTCMD 0x0004 /* FIS fetched from host memory */
689 /* (else from LRAM) */
690#define SILI_PRB_CTRL_RECEIVE 0x0008 /* Reserve cmd slot to receive */
691 /* an interlocked FIS */
692#define SILI_PRB_CTRL_READ 0x0010 /* device to host data */
693#define SILI_PRB_CTRL_WRITE 0x0020 /* host to device data */
694#define SILI_PRB_CTRL_NOINT 0x0040 /* do not post int on completion*/
695#define SILI_PRB_CTRL_SOFTRESET 0x0080 /* issue soft reset (special) */
696
697#define SILI_PRB_OVER_ATAPI 0x0001
698#define SILI_PRB_OVER_ATA 0x0002
699#define SILI_PRB_OVER_NCQ 0x0004
700#define SILI_PRB_OVER_READ 0x0008 /* device to host data */
701#define SILI_PRB_OVER_WRITE 0x0010 /* host to device data */
702#define SILI_PRB_OVER_RAW 0x0020 /* no protocol special case */
703
1ac8d5ba
MD
704#define SILI_MAX_PORTS 16
705#define SILI_MAX_CMDS 31 /* not 32 */
706
707struct sili_dmamem {
708 bus_dma_tag_t adm_tag;
709 bus_dmamap_t adm_map;
710 bus_dma_segment_t adm_seg;
711 bus_addr_t adm_busaddr;
712 caddr_t adm_kva;
713};
714#define SILI_DMA_MAP(_adm) ((_adm)->adm_map)
715#define SILI_DMA_DVA(_adm) ((_adm)->adm_busaddr)
716#define SILI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva)
717
718struct sili_softc;
719struct sili_port;
720struct sili_device;
721
722struct sili_ccb {
723 /* ATA xfer associated with this CCB. Must be 1st struct member. */
724 struct ata_xfer ccb_xa;
725 struct callout ccb_timeout;
726
727 int ccb_slot;
728 struct sili_port *ccb_port;
729
730 bus_dmamap_t ccb_dmamap;
731 struct sili_prb *ccb_prb;
4383d440 732 struct sili_prb *ccb_prb_lram;
2102f407 733 u_int64_t ccb_prb_paddr; /* phys addr of prb */
1ac8d5ba
MD
734
735 void (*ccb_done)(struct sili_ccb *);
736
737 TAILQ_ENTRY(sili_ccb) ccb_entry;
738};
739
740struct sili_port {
741 struct sili_softc *ap_sc;
742 bus_space_handle_t ap_ioh;
743
744 int ap_num;
745 int ap_pmcount;
746 int ap_flags;
747#define AP_F_BUS_REGISTERED 0x0001
748#define AP_F_CAM_ATTACHED 0x0002
749#define AP_F_IN_RESET 0x0004
750#define AP_F_SCAN_RUNNING 0x0008
751#define AP_F_SCAN_REQUESTED 0x0010
752#define AP_F_SCAN_COMPLETED 0x0020
753#define AP_F_IGNORE_IFS 0x0040
4383d440 754#define AP_F_UNUSED0200 0x0200
1ac8d5ba
MD
755#define AP_F_ERR_CCB_RESERVED 0x0400
756 int ap_signal; /* os per-port thread sig */
757 thread_t ap_thread; /* os per-port thread */
758 struct lock ap_lock; /* os per-port lock */
759#define AP_SIGF_INIT 0x0001
760#define AP_SIGF_TIMEOUT 0x0002
761#define AP_SIGF_PORTINT 0x0004
762#define AP_SIGF_STOP 0x8000
763 struct cam_sim *ap_sim;
764
2102f407 765 struct sili_prb *ap_prbs;
1ac8d5ba 766
2102f407 767 struct sili_dmamem *ap_dmamem_prbs;/* separate sge tables */
1ac8d5ba
MD
768
769 u_int32_t ap_active; /* active bmask */
770 u_int32_t ap_active_cnt; /* active count */
771 u_int32_t ap_expired; /* deferred expired bmask */
772 struct sili_ccb *ap_ccbs;
773 struct sili_ccb *ap_err_ccb; /* used to read LOG page */
6f3b9849 774 int ap_run_flags; /* used to check excl mode */
1ac8d5ba
MD
775
776 TAILQ_HEAD(, sili_ccb) ap_ccb_free;
777 TAILQ_HEAD(, sili_ccb) ap_ccb_pending;
778 struct lock ap_ccb_lock;
779
780 int ap_type; /* ATA_PORT_T_xxx */
781 int ap_probe; /* ATA_PROBE_xxx */
782 struct ata_port *ap_ata;
783
784 u_int32_t ap_state;
785#define AP_S_NORMAL 0
786#define AP_S_FATAL_ERROR 1
787
788 /* For error recovery. */
789#ifdef DIAGNOSTIC
790 int ap_err_busy;
791#endif
6f3b9849 792 u_int8_t *ap_err_scratch;
1ac8d5ba
MD
793
794 char ap_name[16];
795};
796
797#define PORTNAME(_ap) ((_ap)->ap_name)
798#define ATANAME(_ap, _at) ((_at) ? (_at)->at_name : (_ap)->ap_name)
799
800struct sili_softc {
801 device_t sc_dev;
802 const struct sili_device *sc_ad; /* special casing */
803
804 struct resource *sc_irq; /* bus resources */
805 struct resource *sc_regs; /* bus resources */
806 struct resource *sc_pregs; /* bus resources */
807 bus_space_tag_t sc_iot; /* split from sc_regs */
808 bus_space_handle_t sc_ioh; /* split from sc_regs */
809 bus_space_tag_t sc_piot; /* split from sc_pregs */
810 bus_space_handle_t sc_pioh; /* split from sc_pregs */
811
812 int sc_rid_irq; /* saved bus RIDs */
813 int sc_rid_regs;
814 int sc_rid_pregs;
815
816 void *sc_irq_handle; /* installed irq vector */
817
2102f407 818 bus_dma_tag_t sc_tag_prbs;
1ac8d5ba
MD
819 bus_dma_tag_t sc_tag_data;
820
821 int sc_flags;
822#define SILI_F_NO_NCQ 0x0001
823#define SILI_F_IGN_FR 0x0002
824#define SILI_F_INT_GOOD 0x0004
825#define SILI_F_64BIT 0x0008
826#define SILI_F_300 0x0010
827#define SILI_F_NCQ 0x0020
828#define SILI_F_SSNTF 0x0040
829#define SILI_F_SPM 0x0080
830
831 u_int sc_ncmds; /* max 31, NOT 32 */
832
833 struct sili_port *sc_ports[SILI_MAX_PORTS];
834};
835#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
836
837struct sili_device {
838 pci_vendor_id_t ad_vendor;
839 pci_product_id_t ad_product;
840 int ad_nports;
841 int (*ad_attach)(device_t dev);
842 int (*ad_detach)(device_t dev);
843 char *name;
844};
845
a35ddbb4
MD
846/* Wait for all bits in _b to be cleared */
847#define sili_pwait_clr(_ap, _r, _b) \
848 sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), 0)
849#define sili_pwait_clr_to(_ap, _to, _r, _b) \
850 sili_pwait_eq((_ap), _to, (_r), (_b), 0)
851
852/* Wait for all bits in _b to be set */
853#define sili_pwait_set(_ap, _r, _b) \
854 sili_pwait_eq((_ap), SILI_PWAIT_TIMEOUT, (_r), (_b), (_b))
855#define sili_pwait_set_to(_ap, _to, _r, _b) \
856 sili_pwait_eq((_ap), _to, (_r), (_b), (_b))
857
858#define SILI_PWAIT_TIMEOUT 1000
859
1ac8d5ba
MD
860const struct sili_device *sili_lookup_device(device_t dev);
861int sili_init(struct sili_softc *);
a35ddbb4 862int sili_port_init(struct sili_port *ap);
1ac8d5ba
MD
863int sili_port_alloc(struct sili_softc *, u_int);
864void sili_port_state_machine(struct sili_port *ap, int initial);
865void sili_port_free(struct sili_softc *, u_int);
866int sili_port_reset(struct sili_port *, struct ata_port *at, int);
867
868u_int32_t sili_read(struct sili_softc *, bus_size_t);
869void sili_write(struct sili_softc *, bus_size_t, u_int32_t);
870int sili_wait_ne(struct sili_softc *, bus_size_t, u_int32_t, u_int32_t);
871u_int32_t sili_pread(struct sili_port *, bus_size_t);
872void sili_pwrite(struct sili_port *, bus_size_t, u_int32_t);
873int sili_pwait_eq(struct sili_port *, int, bus_size_t,
874 u_int32_t, u_int32_t);
875void sili_intr(void *);
876void sili_port_intr(struct sili_port *ap, int blockable);
877
878int sili_cam_attach(struct sili_port *ap);
879void sili_cam_changed(struct sili_port *ap, struct ata_port *at, int found);
880void sili_cam_detach(struct sili_port *ap);
881int sili_cam_probe(struct sili_port *ap, struct ata_port *at);
882
883struct ata_xfer *sili_ata_get_xfer(struct sili_port *ap, struct ata_port *at);
884void sili_ata_put_xfer(struct ata_xfer *xa);
885int sili_ata_cmd(struct ata_xfer *xa);
886
a35ddbb4 887int sili_pm_port_probe(struct sili_port *ap, int);
a35ddbb4 888int sili_pm_port_init(struct sili_port *ap, struct ata_port *at);
6f3b9849 889int sili_pm_identify(struct sili_port *ap);
1ac8d5ba
MD
890int sili_pm_set_feature(struct sili_port *ap, int feature, int enable);
891int sili_pm_hardreset(struct sili_port *ap, int target, int hard);
892int sili_pm_softreset(struct sili_port *ap, int target);
893int sili_pm_phy_status(struct sili_port *ap, int target, u_int32_t *datap);
894int sili_pm_read(struct sili_port *ap, int target,
895 int which, u_int32_t *res);
896int sili_pm_write(struct sili_port *ap, int target,
897 int which, u_int32_t data);
898void sili_pm_check_good(struct sili_port *ap, int target);
899void sili_ata_cmd_timeout(struct sili_ccb *ccb);
a35ddbb4 900void sili_quick_timeout(struct sili_ccb *ccb);
1ac8d5ba
MD
901struct sili_ccb *sili_get_ccb(struct sili_port *ap);
902void sili_put_ccb(struct sili_ccb *ccb);
903struct sili_ccb *sili_get_err_ccb(struct sili_port *);
904void sili_put_err_ccb(struct sili_ccb *);
905int sili_poll(struct sili_ccb *ccb, int timeout,
906 void (*timeout_fn)(struct sili_ccb *));
907
908int sili_port_signature(struct sili_port *ap, struct ata_port *at,
909 u_int32_t sig);
910void sili_port_thread_core(struct sili_port *ap, int mask);
911
912void sili_os_sleep(int ms);
913void sili_os_hardsleep(int us);
914int sili_os_softsleep(void);
915void sili_os_start_port(struct sili_port *ap);
916void sili_os_stop_port(struct sili_port *ap);
917void sili_os_signal_port_thread(struct sili_port *ap, int mask);
918void sili_os_lock_port(struct sili_port *ap);
919int sili_os_lock_port_nb(struct sili_port *ap);
920void sili_os_unlock_port(struct sili_port *ap);
921
922extern u_int32_t SiliForceGen1;
923extern u_int32_t SiliNoFeatures;