xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h (revision 622200ad88c6c6382403a01985a94e22484baac6)
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 2005 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
33 extern "C" {
34 #endif
35 
36 #pragma pack(1)
37 
38 typedef 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 */
62 typedef 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) */
68 typedef 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 
121 	/* offset 0x08 */
122 	uint32_t fish_sectexp_cyllowexp_cylhiexp_featuresexp;
123 
124 #define	SET_FIS_SECTOR_EXP(fis, sectorexp)	\
125 	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |=	\
126 		((sectorexp & 0xff)))
127 
128 #define	SET_FIS_CYL_LOW_EXP(fis, cyllowexp)			\
129 	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
130 		((cyllowexp & 0xff) << 8))
131 
132 #define	SET_FIS_CYL_HI_EXP(fis, cylhiexp)			\
133 	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
134 		((cylhiexp & 0xff) << 16))
135 
136 #define	SET_FIS_FEATURES_EXP(fis, features_exp)		\
137 	(fis.fish_sectexp_cyllowexp_cylhiexp_featuresexp |= 	\
138 		((features_exp & 0xff) << 24))
139 
140 	/* offset 0x0c */
141 	uint32_t fish_sectcount_sectcountexp_rsvd_devctl;
142 
143 #define	SET_FIS_SECTOR_COUNT(fis, sector_count)	\
144 	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((sector_count & 0xff)))
145 
146 #define	GET_FIS_SECTOR_COUNT(fis)	\
147 	(fis.fish_sectcount_sectcountexp_rsvd_devctl & 0xff)
148 
149 #define	SET_FIS_SECTOR_COUNT_EXP(fis, sector_count_exp)	\
150 	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= \
151 		((sector_count_exp & 0xff) << 8))
152 
153 #define	SET_FIS_SECTOR_DEVCTL(fis, devctl)	\
154 	(fis.fish_sectcount_sectcountexp_rsvd_devctl |= ((devctl & 0xff) << 24))
155 
156 	/* offset 0x10 */
157 	uint32_t fish_rsvd3;		/* should be zero */
158 } fis_reg_h2d_t;
159 
160 
161 
162 
163 /*
164  * Port Request Block
165  */
166 typedef struct si_prb {
167 	/* offset 0x00 */
168 	uint32_t prb_control_override;
169 
170 #define	SET_PRB_CONTROL_PKT_READ(prb)	\
171 	(prb->prb_control_override |= (0x1 << 4))
172 
173 #define	SET_PRB_CONTROL_PKT_WRITE(prb)	\
174 	(prb->prb_control_override |= (0x1 << 5))
175 
176 #define	SET_PRB_CONTROL_SOFT_RESET(prb)	\
177 	(prb->prb_control_override |= (0x1 << 7))
178 
179 	/* offset 0x04 */
180 	uint32_t prb_received_count;
181 
182 	/* offset 0x08 */
183 	fis_reg_h2d_t prb_fis; 			/* this is of 0x14 bytes size */
184 
185 	/* offset 0x1c */
186 	uint32_t prb_rsvd3;
187 
188 	/* offset 0x20 */
189 	si_sge_t prb_sge0;
190 
191 	/* offset 0x30 */
192 	si_sge_t prb_sge1;
193 
194 } si_prb_t;
195 
196 #pragma pack()
197 
198 
199 /* Various interrupt bits */
200 #define	INTR_COMMAND_COMPLETE		(0x1 << 0)
201 #define	INTR_COMMAND_ERROR		(0x1 << 1)
202 #define	INTR_PORT_READY			(0x1 << 2)
203 #define	INTR_POWER_CHANGE		(0x1 << 3)
204 #define	INTR_PHYRDY_CHANGE		(0x1 << 4)
205 #define	INTR_COMWAKE_RECEIVED		(0x1 << 5)
206 #define	INTR_UNRECOG_FIS		(0x1 << 6)
207 #define	INTR_DEV_XCHANGED		(0x1 << 7)
208 #define	INTR_8B10B_DECODE_ERROR		(0x1 << 8)
209 #define	INTR_CRC_ERROR			(0x1 << 9)
210 #define	INTR_HANDSHAKE_ERROR		(0x1 << 10)
211 #define	INTR_SETDEVBITS_NOTIFY		(0x1 << 11)
212 #define	INTR_MASK			(0xfff)
213 
214 /* Device signatures */
215 #define	SI_SIGNATURE_PORT_MULTIPLIER	0x96690101
216 #define	SI_SIGNATURE_ATAPI		0xeb140101
217 #define	SI_SIGNATURE_DISK		0x00000101
218 
219 
220 /* Global definitions */
221 #define	GLOBAL_OFFSET(si_ctlp)		(si_ctlp->sictl_global_addr)
222 #define	GLOBAL_CONTROL_REG(si_ctlp)	(GLOBAL_OFFSET(si_ctlp)+0x40)
223 #define	GLOBAL_INTERRUPT_STATUS(si_ctlp)	(GLOBAL_OFFSET(si_ctlp)+0x44)
224 
225 /* Per port definitions */
226 #define	PORT_OFFSET(si_ctlp, port)	(si_ctlp->sictl_port_addr + port*0x2000)
227 #define	PORT_LRAM(si_ctlp, port, slot)		\
228 			(PORT_OFFSET(si_ctlp, port) + 0x0 + slot*0x80)
229 #define	PORT_CONTROL_SET(si_ctlp, port)		\
230 			(PORT_OFFSET(si_ctlp, port) + 0x1000)
231 #define	PORT_STATUS(si_ctlp, port)		\
232 			(PORT_OFFSET(si_ctlp, port) + 0x1000)
233 #define	PORT_CONTROL_CLEAR(si_ctlp, port)		\
234 			(PORT_OFFSET(si_ctlp, port) + 0x1004)
235 #define	PORT_INTERRUPT_STATUS(si_ctlp, port)	\
236 			(PORT_OFFSET(si_ctlp, port) + 0x1008)
237 #define	PORT_INTERRUPT_ENABLE_SET(si_ctlp, port)	\
238 			(PORT_OFFSET(si_ctlp, port) + 0x1010)
239 #define	PORT_INTERRUPT_ENABLE_CLEAR(si_ctlp, port) \
240 			(PORT_OFFSET(si_ctlp, port) + 0x1014)
241 #define	PORT_COMMAND_ERROR(si_ctlp, port) 	\
242 			(PORT_OFFSET(si_ctlp, port) + 0x1024)
243 #define	PORT_SLOT_STATUS(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1800)
244 
245 #define	PORT_SCONTROL(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f00)
246 #define	PORT_SSTATUS(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f04)
247 #define	PORT_SERROR(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f08)
248 #define	PORT_SACTIVE(si_ctlp, port)	(PORT_OFFSET(si_ctlp, port) + 0x1f0c)
249 
250 #define	PORT_COMMAND_ACTIVATION(si_ctlp, port, slot)	\
251 			(PORT_OFFSET(si_ctlp, port) + 0x1c00 + slot*0x8)
252 
253 #define	PORT_SIGNATURE_MSB(si_ctlp, port, slot)		\
254 			(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x0c)
255 #define	PORT_SIGNATURE_LSB(si_ctlp, port, slot)		\
256 			(PORT_OFFSET(si_ctlp, port) + slot*0x80 + 0x14)
257 
258 /* Interesting bits of Port Control Set register */
259 #define	PORT_CONTROL_SET_BITS_PORT_RESET		0x1
260 #define	PORT_CONTROL_SET_BITS_DEV_RESET			0x2
261 #define	PORT_CONTROL_SET_BITS_PORT_INITIALIZE		0x4
262 #define	PORT_CONTROL_SET_BITS_PACKET_LEN		0x20
263 #define	PORT_CONTROL_SET_BITS_RESUME			0x40
264 #define	PORT_CONTROL_SET_BITS_PM_ENABLE			0x2000
265 
266 /* Interesting bits of Port Control Clear register */
267 #define	PORT_CONTROL_CLEAR_BITS_PORT_RESET		0x1
268 #define	PORT_CONTROL_CLEAR_BITS_INTR_NCoR		0x8
269 #define	PORT_CONTROL_CLEAR_BITS_PACKET_LEN		0x20
270 #define	PORT_CONTROL_CLEAR_BITS_RESUME			0x40
271 
272 /* Interesting bits of Port Status register */
273 #define	PORT_STATUS_BITS_PORT_READY		0x80000000
274 
275 /* Interesting bits of Global Control register */
276 #define	GLOBAL_CONTROL_REG_BITS_CLEAR		0x00000000
277 
278 #define	POST_PRB_ADDR(si_ctlp, si_portp, port, slot)			  \
279 	(void) ddi_dma_sync(si_portp->siport_prbpool_dma_handle,	  \
280 			slot * sizeof (si_prb_t),			  \
281 			sizeof (si_prb_t),				  \
282 			DDI_DMA_SYNC_FORDEV);				  \
283 									  \
284 	(void) ddi_dma_sync(si_portp->siport_sgbpool_dma_handle,	  \
285 			slot * sizeof (si_sgblock_t),			  \
286 			sizeof (si_sgblock_t),				  \
287 			DDI_DMA_SYNC_FORDEV);				  \
288 									  \
289 	ddi_put64(si_ctlp->sictl_port_acc_handle, 			  \
290 		(uint64_t *)PORT_COMMAND_ACTIVATION(si_ctlp, port, slot), \
291 		(uint64_t)(si_portp->siport_prbpool_physaddr + 		  \
292 		slot*sizeof (si_prb_t)));
293 
294 #define	SI_SLOT_MASK	0x7fffffff
295 #define	SI_NUM_SLOTS	0x1f		/* 31 */
296 
297 #define	ATTENTION_BIT	0x80000000
298 #define	IS_ATTENTION_RAISED(slot_status)	(slot_status & ATTENTION_BIT)
299 
300 #define	SI3124_DEV_ID	3124
301 #define	SI3132_DEV_ID	3132
302 
303 #define	PM_CSR(devid)	 ((devid == SI3124_DEV_ID) ? 0x68 : 0x58)
304 
305 #define	REGISTER_FIS_H2D	0x27
306 
307 #define	SI31xx_INTR_PORT_MASK	0xf
308 
309 /* PCI BAR registers */
310 #define	PCI_BAR0	1	/* Contains global register set */
311 #define	PCI_BAR1	2	/* Contains port register set */
312 
313 /* Port Status and Control Registers (from port multiplier spec) */
314 #define	PSCR_REG0	0
315 #define	PSCR_REG1	1
316 #define	PSCR_REG2	2
317 #define	PSCR_REG3	3
318 
319 /* SStatus bit fields */
320 #define	SSTATUS_DET_MASK	0x0000000f
321 #define	SSTATUS_SPD_MASK	0x000000f0
322 #define	SSTATUS_SPD_SHIFT	4
323 #define	SSTATUS_IPM_MASK	0x00000f00
324 #define	SSTATUS_IPM_SHIFT	8
325 
326 #define	SSTATUS_GET_DET(x)		\
327 	(x & SSTATUS_DET_MASK)
328 
329 #define	SSTATUS_SET_DET(x, new_val)	\
330 	(x = (x & ~SSTATUS_DET_MASK) | (new_val & SSTATUS_DET_MASK))
331 
332 #define	SSTATUS_DET_NODEV_NOPHY		 0x0 /* No device, no PHY */
333 #define	SSTATUS_DET_DEVPRESENT_NOPHY	 0x1 /* Dev present, no PHY */
334 #define	SSTATUS_DET_DEVPRESENT_PHYONLINE 0x3 /* Dev present, PHY online */
335 #define	SSTATUS_DET_PHYOFFLINE		 0x4 /* PHY offline */
336 
337 #define	SSTATUS_GET_IPM(x)	\
338 	((x & SSTATUS_IPM_MASK) >> SSTATUS_IPM_SHIFT)
339 
340 #define	SSTATUS_SET_IPM(x, new_val)					\
341 	(x = (x & ~SSTATUS_IPM_MASK) | 					\
342 		((new_val << SSTATUS_IPM_SHIFT) & SSTATUS_IPM_MASK))
343 
344 #define	SSTATUS_IPM_NODEV_NOPHY			0x0 /* No dev, no PHY */
345 #define	SSTATUS_IPM_INTERFACE_ACTIVE		0x1 /* Interface active */
346 #define	SSTATUS_IPM_INTERFACE_POWERPARTIAL	0x2 /* partial power mgmnt */
347 #define	SSTATUS_IPM_INTERFACE_POWERSLUMBER	0x6 /* slumber power mgmt */
348 
349 /* SControl bit fields */
350 #define	SCONTROL_DET_MASK	0x0000000f
351 
352 #define	SCONTROL_GET_DET(x)		\
353 	(x & SCONTROL_DET_MASK)
354 
355 #define	SCONTROL_SET_DET(x, new_val)	\
356 	(x = (x & ~SCONTROL_DET_MASK) | (new_val & SCONTROL_DET_MASK))
357 
358 #define	SCONTROL_DET_NOACTION		0x0 /* No action requested */
359 #define	SCONTROL_DET_COMRESET		0x1 /* Send COMRESET */
360 
361 /* Command Error codes */
362 #define	CMD_ERR_DEVICEERRROR		1
363 #define	CMD_ERR_SDBERROR		2
364 #define	CMD_ERR_DATAFISERROR		3
365 #define	CMD_ERR_SENDFISERROR		4
366 #define	CMD_ERR_INCONSISTENTSTATE	5
367 #define	CMD_ERR_DIRECTIONERROR		6
368 #define	CMD_ERR_UNDERRUNERROR		7
369 #define	CMD_ERR_OVERRUNERROR		8
370 #define	CMD_ERR_PACKETPROTOCOLERROR	11
371 #define	CMD_ERR_PLDSGTERRORBOUNDARY	16
372 #define	CMD_ERR_PLDSGTERRORTARETABORT	17
373 #define	CMD_ERR_PLDSGTERRORMASTERABORT	18
374 #define	CMD_ERR_PLDSGTERRORPCIERR	19
375 #define	CMD_ERR_PLDCMDERRORBOUNDARY	24
376 #define	CMD_ERR_PLDCMDERRORTARGETABORT	25
377 #define	CMD_ERR_PLDCMDERRORMASTERABORT	26
378 #define	CMD_ERR_PLDCMDERORPCIERR	27
379 #define	CMD_ERR_PSDERRORTARGETABORT	33
380 #define	CMD_ERR_PSDERRORMASTERABORT	34
381 #define	CMD_ERR_PSDERRORPCIERR		35
382 #define	CMD_ERR_SENDSERVICEERROR	36
383 
384 #ifdef	__cplusplus
385 }
386 #endif
387 
388 #endif /* _SI3124REG_H */
389