xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/si3124/si3124reg.h (revision 355b4669e025ff377602b6fc7caaf30dbc218371)
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
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 #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  */
181 typedef 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	0x3124
316 #define	SI3132_DEV_ID	0x3132
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