si3124reg.h revision 1612:f22bd5bc2aff
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _SI3124REG_H
28#define	_SI3124REG_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36#pragma pack(1)
37
38typedef struct si_sge {
39	/* offset 0x00 */
40	union {
41		uint64_t _sge_addr_ll;
42		uint32_t _sge_addr_la[2];
43	} _sge_addr_un;
44
45#define	sge_addr_low	_sge_addr_un._sge_addr_la[0]
46#define	sge_addr_high	_sge_addr_un._sge_addr_la[1]
47#define	sge_addr	_sge_addr_un._sge_addr_ll
48
49	/* offset 0x08 */
50	uint32_t sge_data_count;
51
52	/* offset 0x0c */
53	uint32_t sge_trm_lnk_drd_xcf_rsvd;
54
55#define	SET_SGE_LNK(sge)	(sge.sge_trm_lnk_drd_xcf_rsvd = 0x40000000)
56#define	SET_SGE_TRM(sge)	(sge.sge_trm_lnk_drd_xcf_rsvd = 0x80000000)
57#define	IS_SGE_TRM_SET(sge)	(sge.sge_trm_lnk_drd_xcf_rsvd & 0x80000000)
58
59} si_sge_t;
60
61/* Scatter Gather Table consists of four SGE entries */
62typedef struct si_sgt {
63	si_sge_t sgt_sge[4];
64} si_sgt_t;
65
66
67/* Register - Host to Device FIS (from SATA spec) */
68typedef struct fis_reg_h2d {
69	/* offset 0x00 */
70	uint32_t fish_type_pmp_rsvd_cmddevctl_cmd_features;
71
72#define	SET_FIS_TYPE(fis, type)	\
73	(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= (type & 0xff))
74
75#define	SET_FIS_PMP(fis, pmp)	\
76	(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |= ((pmp & 0xf) << 8))
77
78#define	SET_FIS_CDMDEVCTL(fis, cmddevctl)	\
79	(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |=	\
80		((cmddevctl & 0x1) << 15))
81
82#define	SET_FIS_COMMAND(fis, command)	\
83	(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |=	\
84		((command & 0xff) << 16))
85
86#define	GET_FIS_COMMAND(fis)	\
87	((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 16) & 0xff)
88
89#define	SET_FIS_FEATURES(fis, features)	\
90	(fis.fish_type_pmp_rsvd_cmddevctl_cmd_features |=	\
91		((features & 0xff) << 24))
92
93#define	GET_FIS_FEATURES(fis)	\
94	((fis.fish_type_pmp_rsvd_cmddevctl_cmd_features >> 24) & 0xff)
95
96	/* offset 0x04 */
97	uint32_t fish_sector_cyllow_cylhi_devhead;
98
99#define	SET_FIS_SECTOR(fis, sector)	\
100	(fis.fish_sector_cyllow_cylhi_devhead |= ((sector & 0xff)))
101
102#define	GET_FIS_SECTOR(fis)	\
103	(fis.fish_sector_cyllow_cylhi_devhead & 0xff)
104
105#define	SET_FIS_CYL_LOW(fis, cyl_low)	\
106	(fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_low & 0xff) << 8))
107
108#define	GET_FIS_CYL_LOW(fis)	\
109	((fis.fish_sector_cyllow_cylhi_devhead >> 8) & 0xff)
110
111#define	SET_FIS_CYL_HI(fis, cyl_hi)	\
112	(fis.fish_sector_cyllow_cylhi_devhead |= ((cyl_hi & 0xff) << 16))
113
114#define	GET_FIS_CYL_HI(fis)	\
115	((fis.fish_sector_cyllow_cylhi_devhead >> 16) & 0xff)
116
117#define	SET_FIS_DEV_HEAD(fis, dev_head)	\
118	(fis.fish_sector_cyllow_cylhi_devhead |= ((dev_head & 0xff) << 24))
119
120#define	GET_FIS_DEV_HEAD(fis)	\
121	((fis.fish_sector_cyllow_cylhi_devhead >> 24) & 0xff)
122
123
124	/* offset 0x08 */
125	uint32_t fish_sectexp_cyllowexp_cylhiexp_featuresexp;
126
127#define	SET_FIS_SECTOR_EXP(fis, sectorexp)	\
128	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
129		((sectorexp & 0xff)))
130
131#define	GET_FIS_SECTOR_EXP(fis)	\
132	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp  & 0xff)
133
134#define	SET_FIS_CYL_LOW_EXP(fis, cyllowexp)			\
135	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
136		((cyllowexp & 0xff) << 8))
137
138#define	GET_FIS_CYL_LOW_EXP(fis)			\
139	((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 8) & 0xff)
140
141#define	SET_FIS_CYL_HI_EXP(fis, cylhiexp)			\
142	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
143		((cylhiexp & 0xff) << 16))
144
145#define	GET_FIS_CYL_HI_EXP(fis)			\
146	((fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp >> 16) & 0xff)
147
148#define	SET_FIS_FEATURES_EXP(fis, features_exp)		\
149	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
150		((features_exp & 0xff) << 24))
151
152	/* offset 0x0c */
153	uint32_t fish_sectcount_sectcountexp_rsvd_devctl;
154
155#define	SET_FIS_SECTOR_COUNT(fis, sector_count)	\
156	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((sector_count & 0xff)))
157
158#define	GET_FIS_SECTOR_COUNT(fis)	\
159	(fis.fish_sectcount_sectcountexp_rsvd_devctl & 0xff)
160
161#define	SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp)	\
162	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= \
163		((sector_count_exp & 0xff) << 8))
164
165#define	GET_FIS_SECTOR_COUNT_EXP(fis)	\
166	((fis.fish_sectcount_sectcountexp_rsvd_devctl >> 8) & 0xff)
167
168#define	SET_FIS_SECTOR_DEVCTL(fis, devctl)	\
169	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((devctl & 0xff) << 24))
170
171	/* offset 0x10 */
172	uint32_t fish_rsvd3;		/* should be zero */
173} fis_reg_h2d_t;
174
175
176
177
178/*
179 * Port Request Block
180 */
181typedef struct si_prb {
182	/* offset 0x00 */
183	uint32_t prb_control_override;
184
185#define	SET_PRB_CONTROL_PKT_READ(prb)	\
186	(prb->prb_control_override |= (0x1 << 4))
187
188#define	SET_PRB_CONTROL_PKT_WRITE(prb)	\
189	(prb->prb_control_override |= (0x1 << 5))
190
191#define	SET_PRB_CONTROL_SOFT_RESET(prb)	\
192	(prb->prb_control_override |= (0x1 << 7))
193
194	/* offset 0x04 */
195	uint32_t prb_received_count;
196
197	/* offset 0x08 */
198	fis_reg_h2d_t prb_fis; 			/* this is of 0x14 bytes size */
199
200	/* offset 0x1c */
201	uint32_t prb_rsvd3;
202
203	/* offset 0x20 */
204	si_sge_t prb_sge0;
205
206	/* offset 0x30 */
207	si_sge_t prb_sge1;
208
209} si_prb_t;
210
211#pragma pack()
212
213
214/* Various interrupt bits */
215#define	INTR_COMMAND_COMPLETE		(0x1 << 0)
216#define	INTR_COMMAND_ERROR		(0x1 << 1)
217#define	INTR_PORT_READY			(0x1 << 2)
218#define	INTR_POWER_CHANGE		(0x1 << 3)
219#define	INTR_PHYRDY_CHANGE		(0x1 << 4)
220#define	INTR_COMWAKE_RECEIVED		(0x1 << 5)
221#define	INTR_UNRECOG_FIS		(0x1 << 6)
222#define	INTR_DEV_XCHANGED		(0x1 << 7)
223#define	INTR_8B10B_DECODE_ERROR		(0x1 << 8)
224#define	INTR_CRC_ERROR			(0x1 << 9)
225#define	INTR_HANDSHAKE_ERROR		(0x1 << 10)
226#define	INTR_SETDEVBITS_NOTIFY		(0x1 << 11)
227#define	INTR_MASK			(0xfff)
228
229/* Device signatures */
230#define	SI_SIGNATURE_PORT_MULTIPLIER	0x96690101
231#define	SI_SIGNATURE_ATAPI		0xeb140101
232#define	SI_SIGNATURE_DISK		0x00000101
233
234
235/* Global definitions */
236#define	GLOBAL_OFFSET(si_ctlp)		(si_ctlp->sictl_global_addr)
237#define	GLOBAL_CONTROL_REG(si_ctlp)	(GLOBAL_OFFSET(si_ctlp)+0x40)
238#define	GLOBAL_INTERRUPT_STATUS(si_ctlp)	(GLOBAL_OFFSET(si_ctlp)+0x44)
239
240/* Per port definitions */
241#define	PORT_OFFSET(si_ctlp, port)	(si_ctlp->sictl_port_addr + port*0x2000)
242#define	PORT_LRAM(si_ctlp, port, slot)		\
243			(PORT_OFFSET(si_ctlp, port) + 0x0 + slot*0x80)
244#define	PORT_CONTROL_SET(si_ctlp, port)		\
245			(PORT_OFFSET(si_ctlp, port) + 0x1000)
246#define	PORT_STATUS(si_ctlp, port)		\
247			(PORT_OFFSET(si_ctlp, port) + 0x1000)
248#define	PORT_CONTROL_CLEAR(si_ctlp, port)		\
249			(PORT_OFFSET(si_ctlp, port) + 0x1004)
250#define	PORT_INTERRUPT_STATUS(si_ctlp, port)	\
251			(PORT_OFFSET(si_ctlp, port) + 0x1008)
252#define	PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)	\
253			(PORT_OFFSET(si_ctlp, port) + 0x1010)
254#define	PORT_INTERRUPT_ENABLE_CLEAR(si_ctlp, port) \
255			(PORT_OFFSET(si_ctlp, port) + 0x1014)
256#define	PORT_COMMAND_ERROR(si_ctlp, port) 	\
257			(PORT_OFFSET(si_ctlp, port) + 0x1024)
258#define	PORT_SLOT_STATUS(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1800)
259
260#define	PORT_SCONTROL(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f00)
261#define	PORT_SSTATUS(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f04)
262#define	PORT_SERROR(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f08)
263#define	PORT_SACTIVE(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f0c)
264
265#define	PORT_COMMAND_ACTIVATION(si_ctlp, port, slot)	\
266			(PORT_OFFSET(si_ctlp, port) + 0x1c00 + slot*0x8)
267
268#define	PORT_SIGNATURE_MSB(si_ctlp, port, slot)		\
269			(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x0c)
270#define	PORT_SIGNATURE_LSB(si_ctlp, port, slot)		\
271			(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x14)
272
273/* Interesting bits of Port Control Set register */
274#define	PORT_CONTROL_SET_BITS_PORT_RESET		0x1
275#define	PORT_CONTROL_SET_BITS_DEV_RESET			0x2
276#define	PORT_CONTROL_SET_BITS_PORT_INITIALIZE		0x4
277#define	PORT_CONTROL_SET_BITS_PACKET_LEN		0x20
278#define	PORT_CONTROL_SET_BITS_RESUME			0x40
279#define	PORT_CONTROL_SET_BITS_PM_ENABLE			0x2000
280
281/* Interesting bits of Port Control Clear register */
282#define	PORT_CONTROL_CLEAR_BITS_PORT_RESET		0x1
283#define	PORT_CONTROL_CLEAR_BITS_INTR_NCoR		0x8
284#define	PORT_CONTROL_CLEAR_BITS_PACKET_LEN		0x20
285#define	PORT_CONTROL_CLEAR_BITS_RESUME			0x40
286
287/* Interesting bits of Port Status register */
288#define	PORT_STATUS_BITS_PORT_READY		0x80000000
289
290/* Interesting bits of Global Control register */
291#define	GLOBAL_CONTROL_REG_BITS_CLEAR		0x00000000
292
293#define	POST_PRB_ADDR(si_ctlp, si_portp, port, slot)			  \
294	(void) ddi_dma_sync(si_portp->siport_prbpool_dma_handle,	  \
295			slot * sizeof (si_prb_t),			  \
296			sizeof (si_prb_t),				  \
297			DDI_DMA_SYNC_FORDEV);				  \
298									  \
299	(void) ddi_dma_sync(si_portp->siport_sgbpool_dma_handle,	  \
300			slot * sizeof (si_sgblock_t),			  \
301			sizeof (si_sgblock_t),				  \
302			DDI_DMA_SYNC_FORDEV);				  \
303									  \
304	ddi_put64(si_ctlp->sictl_port_acc_handle, 			  \
305		(uint64_t *)PORT_COMMAND_ACTIVATION(si_ctlp, port, slot), \
306		(uint64_t)(si_portp->siport_prbpool_physaddr + 		  \
307		slot*sizeof (si_prb_t)));
308
309#define	SI_SLOT_MASK	0x7fffffff
310#define	SI_NUM_SLOTS	0x1f		/* 31 */
311
312#define	ATTENTION_BIT	0x80000000
313#define	IS_ATTENTION_RAISED(slot_status)	(slot_status & ATTENTION_BIT)
314
315#define	SI3124_DEV_ID	3124
316#define	SI3132_DEV_ID	3132
317
318#define	PM_CSR(devid)	 ((devid == SI3124_DEV_ID) ? 0x68 : 0x58)
319
320#define	REGISTER_FIS_H2D	0x27
321
322#define	SI31xx_INTR_PORT_MASK	0xf
323
324/* PCI BAR registers */
325#define	PCI_BAR0	1	/* Contains global register set */
326#define	PCI_BAR1	2	/* Contains port register set */
327
328/* Port Status and Control Registers (from port multiplier spec) */
329#define	PSCR_REG0	0
330#define	PSCR_REG1	1
331#define	PSCR_REG2	2
332#define	PSCR_REG3	3
333
334/* SStatus bit fields */
335#define	SSTATUS_DET_MASK	0x0000000f
336#define	SSTATUS_SPD_MASK	0x000000f0
337#define	SSTATUS_SPD_SHIFT	4
338#define	SSTATUS_IPM_MASK	0x00000f00
339#define	SSTATUS_IPM_SHIFT	8
340
341#define	SSTATUS_GET_DET(x)		\
342	(x & SSTATUS_DET_MASK)
343
344#define	SSTATUS_SET_DET(x, new_val)	\
345	(x = (x & ~SSTATUS_DET_MASK) | (new_val & SSTATUS_DET_MASK))
346
347#define	SSTATUS_DET_NODEV_NOPHY		 0x0 /* No device, no PHY */
348#define	SSTATUS_DET_DEVPRESENT_NOPHY	 0x1 /* Dev present, no PHY */
349#define	SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* Dev present, PHY online */
350#define	SSTATUS_DET_PHYOFFLINE		 0x4 /* PHY offline */
351
352#define	SSTATUS_GET_IPM(x)	\
353	((x & SSTATUS_IPM_MASK) >> SSTATUS_IPM_SHIFT)
354
355#define	SSTATUS_SET_IPM(x, new_val)					\
356	(x = (x & ~SSTATUS_IPM_MASK) | 					\
357		((new_val << SSTATUS_IPM_SHIFT) & SSTATUS_IPM_MASK))
358
359#define	SSTATUS_IPM_NODEV_NOPHY			0x0 /* No dev, no PHY */
360#define	SSTATUS_IPM_INTERFACE_ACTIVE		0x1 /* Interface active */
361#define	SSTATUS_IPM_INTERFACE_POWERPARTIAL	0x2 /* partial power mgmnt */
362#define	SSTATUS_IPM_INTERFACE_POWERSLUMBER	0x6 /* slumber power mgmt */
363
364/* SControl bit fields */
365#define	SCONTROL_DET_MASK	0x0000000f
366
367#define	SCONTROL_GET_DET(x)		\
368	(x & SCONTROL_DET_MASK)
369
370#define	SCONTROL_SET_DET(x, new_val)	\
371	(x = (x & ~SCONTROL_DET_MASK) | (new_val & SCONTROL_DET_MASK))
372
373#define	SCONTROL_DET_NOACTION		0x0 /* No action requested */
374#define	SCONTROL_DET_COMRESET		0x1 /* Send COMRESET */
375
376/* Command Error codes */
377#define	CMD_ERR_DEVICEERRROR		1
378#define	CMD_ERR_SDBERROR		2
379#define	CMD_ERR_DATAFISERROR		3
380#define	CMD_ERR_SENDFISERROR		4
381#define	CMD_ERR_INCONSISTENTSTATE	5
382#define	CMD_ERR_DIRECTIONERROR		6
383#define	CMD_ERR_UNDERRUNERROR		7
384#define	CMD_ERR_OVERRUNERROR		8
385#define	CMD_ERR_PACKETPROTOCOLERROR	11
386#define	CMD_ERR_PLDSGTERRORBOUNDARY	16
387#define	CMD_ERR_PLDSGTERRORTARETABORT	17
388#define	CMD_ERR_PLDSGTERRORMASTERABORT	18
389#define	CMD_ERR_PLDSGTERRORPCIERR	19
390#define	CMD_ERR_PLDCMDERRORBOUNDARY	24
391#define	CMD_ERR_PLDCMDERRORTARGETABORT	25
392#define	CMD_ERR_PLDCMDERRORMASTERABORT	26
393#define	CMD_ERR_PLDCMDERORPCIERR	27
394#define	CMD_ERR_PSDERRORTARGETABORT	33
395#define	CMD_ERR_PSDERRORMASTERABORT	34
396#define	CMD_ERR_PSDERRORPCIERR		35
397#define	CMD_ERR_SENDSERVICEERROR	36
398
399#ifdef	__cplusplus
400}
401#endif
402
403#endif /* _SI3124REG_H */
404