xref: /illumos-gate/usr/src/uts/common/io/1394/adapters/hci1394_csr.c (revision 2570281cf351044b6936651ce26dbe1f801dcbd8)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * hci1394_csr.c
29*7c478bd9Sstevel@tonic-gate  *    This code contains the code for the CSR registers handled by the HAL in
30*7c478bd9Sstevel@tonic-gate  *    SW.  The HW implemented CSR registers are in hci1394_ohci.c
31*7c478bd9Sstevel@tonic-gate  *
32*7c478bd9Sstevel@tonic-gate  *   For more information on CSR registers, see
33*7c478bd9Sstevel@tonic-gate  *	IEEE 1212
34*7c478bd9Sstevel@tonic-gate  *	IEEE 1394-1995
35*7c478bd9Sstevel@tonic-gate  *		section 8.3.2
36*7c478bd9Sstevel@tonic-gate  *	IEEE P1394A Draft 3.0
37*7c478bd9Sstevel@tonic-gate  *		sections 10.32,10.33
38*7c478bd9Sstevel@tonic-gate  *
39*7c478bd9Sstevel@tonic-gate  * NOTE: A read/write to a CSR SW based register will first go to the Services
40*7c478bd9Sstevel@tonic-gate  *    Layer which will do some filtering and then come through the s1394if. Look
41*7c478bd9Sstevel@tonic-gate  *    in hci1394_s1394if.c to see which registers are implemented in HW and
42*7c478bd9Sstevel@tonic-gate  *    which are implemented in SW.
43*7c478bd9Sstevel@tonic-gate  */
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate #include <sys/conf.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
50*7c478bd9Sstevel@tonic-gate #include <sys/cmn_err.h>
51*7c478bd9Sstevel@tonic-gate #include <sys/kmem.h>
52*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
55*7c478bd9Sstevel@tonic-gate #include <sys/1394/adapters/hci1394_extern.h>
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate /*
59*7c478bd9Sstevel@tonic-gate  * The split_timeout_lo register cannot be set below 800 and above 7999.  The
60*7c478bd9Sstevel@tonic-gate  * split_timeout_hi register cannot be set above 7.
61*7c478bd9Sstevel@tonic-gate  */
62*7c478bd9Sstevel@tonic-gate #define	CSR_MIN_SPLIT_TIMEOUT_LO	800
63*7c478bd9Sstevel@tonic-gate #define	CSR_MAX_SPLIT_TIMEOUT_LO	7999
64*7c478bd9Sstevel@tonic-gate #define	CSR_MAX_SPLIT_TIMEOUT_HI	7
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate /*
67*7c478bd9Sstevel@tonic-gate  * We will convert the split_timeout_lo to return the data in most significant
68*7c478bd9Sstevel@tonic-gate  * 13 bits on the fly.
69*7c478bd9Sstevel@tonic-gate  */
70*7c478bd9Sstevel@tonic-gate #define	CSR_SPLIT_TIMEOUT_LO_SHIFT	19
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate /*
73*7c478bd9Sstevel@tonic-gate  * This is what we report to the services layer as our node capabilities.
74*7c478bd9Sstevel@tonic-gate  * See IEEE 1212_1994, section 8.4.11
75*7c478bd9Sstevel@tonic-gate  *
76*7c478bd9Sstevel@tonic-gate  * Split Timeout Registers are implemented (bit 15)
77*7c478bd9Sstevel@tonic-gate  * This node uses 64-bit addressing (bit 9)
78*7c478bd9Sstevel@tonic-gate  * This node uses fixed addressing scheme (bit 8)
79*7c478bd9Sstevel@tonic-gate  * STATE_BITS.lost is implemented
80*7c478bd9Sstevel@tonic-gate  * STATE_BITS.dreq is implemented
81*7c478bd9Sstevel@tonic-gate  */
82*7c478bd9Sstevel@tonic-gate #define	CSR_INITIAL_NODE_CAPABILITIES	0x000083C0
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate /*
85*7c478bd9Sstevel@tonic-gate  * macro to calculate split_timeout based on split_timeout_lo and
86*7c478bd9Sstevel@tonic-gate  * split_timeout_hi
87*7c478bd9Sstevel@tonic-gate  */
88*7c478bd9Sstevel@tonic-gate #define	CSR_SPLIT_TIMEOUT(split_hi, split_lo) \
89*7c478bd9Sstevel@tonic-gate 	((split_hi * IEEE1394_BUS_CYCLES_PER_SEC) + split_lo)
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate static void hci1394_csr_state_init(hci1394_csr_t *csr);
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate /*
96*7c478bd9Sstevel@tonic-gate  * hci1394_csr_init()
97*7c478bd9Sstevel@tonic-gate  *    Initialize CSR state and CSR SW based registers.
98*7c478bd9Sstevel@tonic-gate  */
99*7c478bd9Sstevel@tonic-gate void
hci1394_csr_init(hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t ohci,hci1394_csr_handle_t * csr_handle)100*7c478bd9Sstevel@tonic-gate hci1394_csr_init(hci1394_drvinfo_t *drvinfo, hci1394_ohci_handle_t ohci,
101*7c478bd9Sstevel@tonic-gate     hci1394_csr_handle_t *csr_handle)
102*7c478bd9Sstevel@tonic-gate {
103*7c478bd9Sstevel@tonic-gate 	hci1394_csr_t *csr;
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate 	ASSERT(drvinfo != NULL);
107*7c478bd9Sstevel@tonic-gate 	ASSERT(ohci != NULL);
108*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate 	/* alloc the space to keep track of the csr registers */
111*7c478bd9Sstevel@tonic-gate 	csr = kmem_alloc(sizeof (hci1394_csr_t), KM_SLEEP);
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	/* setup the return parameter */
114*7c478bd9Sstevel@tonic-gate 	*csr_handle = csr;
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	/* Initialize the csr structure */
117*7c478bd9Sstevel@tonic-gate 	csr->csr_drvinfo = drvinfo;
118*7c478bd9Sstevel@tonic-gate 	csr->csr_ohci = ohci;
119*7c478bd9Sstevel@tonic-gate 	mutex_init(&csr->csr_mutex, NULL, MUTEX_DRIVER,
120*7c478bd9Sstevel@tonic-gate 	    drvinfo->di_iblock_cookie);
121*7c478bd9Sstevel@tonic-gate 	hci1394_csr_state_init(csr);
122*7c478bd9Sstevel@tonic-gate }
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate /*
126*7c478bd9Sstevel@tonic-gate  * hci1394_csr_fini()
127*7c478bd9Sstevel@tonic-gate  *    Free up any space allocated and any mutexes used.
128*7c478bd9Sstevel@tonic-gate  */
129*7c478bd9Sstevel@tonic-gate void
hci1394_csr_fini(hci1394_csr_handle_t * csr_handle)130*7c478bd9Sstevel@tonic-gate hci1394_csr_fini(hci1394_csr_handle_t *csr_handle)
131*7c478bd9Sstevel@tonic-gate {
132*7c478bd9Sstevel@tonic-gate 	hci1394_csr_t *csr;
133*7c478bd9Sstevel@tonic-gate 
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 	csr = (hci1394_csr_t *)*csr_handle;
138*7c478bd9Sstevel@tonic-gate 	mutex_destroy(&csr->csr_mutex);
139*7c478bd9Sstevel@tonic-gate 	kmem_free(csr, sizeof (hci1394_csr_t));
140*7c478bd9Sstevel@tonic-gate 	*csr_handle = NULL;
141*7c478bd9Sstevel@tonic-gate }
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate /*
145*7c478bd9Sstevel@tonic-gate  * hci1394_csr_resume()
146*7c478bd9Sstevel@tonic-gate  *    When resuming power on a workstation, re-setup our CSR registers.
147*7c478bd9Sstevel@tonic-gate  */
148*7c478bd9Sstevel@tonic-gate void
hci1394_csr_resume(hci1394_csr_handle_t csr_handle)149*7c478bd9Sstevel@tonic-gate hci1394_csr_resume(hci1394_csr_handle_t csr_handle)
150*7c478bd9Sstevel@tonic-gate {
151*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
152*7c478bd9Sstevel@tonic-gate 	hci1394_csr_state_init(csr_handle);
153*7c478bd9Sstevel@tonic-gate }
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate /*
157*7c478bd9Sstevel@tonic-gate  * hci1394_csr_node_capabilities()
158*7c478bd9Sstevel@tonic-gate  *    Return the CSR node capabilities.
159*7c478bd9Sstevel@tonic-gate  */
160*7c478bd9Sstevel@tonic-gate void
hci1394_csr_node_capabilities(hci1394_csr_handle_t csr_handle,uint32_t * capabilities)161*7c478bd9Sstevel@tonic-gate hci1394_csr_node_capabilities(hci1394_csr_handle_t csr_handle,
162*7c478bd9Sstevel@tonic-gate     uint32_t *capabilities)
163*7c478bd9Sstevel@tonic-gate {
164*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
165*7c478bd9Sstevel@tonic-gate 	ASSERT(capabilities != NULL);
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
168*7c478bd9Sstevel@tonic-gate 	*capabilities = csr_handle->csr_capabilities;
169*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
170*7c478bd9Sstevel@tonic-gate }
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate /*
174*7c478bd9Sstevel@tonic-gate  * hci1394_csr_state_get()
175*7c478bd9Sstevel@tonic-gate  *    Read the CSR state register. Currently we only support the dreq, cmstr,
176*7c478bd9Sstevel@tonic-gate  *    and abdicate bits in the CSR state register.  See the specs mentioned
177*7c478bd9Sstevel@tonic-gate  *    above for the behavior of these bits.
178*7c478bd9Sstevel@tonic-gate  */
179*7c478bd9Sstevel@tonic-gate void
hci1394_csr_state_get(hci1394_csr_handle_t csr_handle,uint32_t * state)180*7c478bd9Sstevel@tonic-gate hci1394_csr_state_get(hci1394_csr_handle_t csr_handle, uint32_t *state)
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
183*7c478bd9Sstevel@tonic-gate 	ASSERT(state != NULL);
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
186*7c478bd9Sstevel@tonic-gate 	*state = csr_handle->csr_state;
187*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
188*7c478bd9Sstevel@tonic-gate }
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 
191*7c478bd9Sstevel@tonic-gate /*
192*7c478bd9Sstevel@tonic-gate  * hci1394_csr_state_bset()
193*7c478bd9Sstevel@tonic-gate  *    Perform a bit set on the CSR state register.  The value of state will be
194*7c478bd9Sstevel@tonic-gate  *    or'd with the CSR state register. Currently we only support the dreq,
195*7c478bd9Sstevel@tonic-gate  *    cmstr, and abdicate bits in the CSR state register.  See the specs
196*7c478bd9Sstevel@tonic-gate  *    mentioned above for the behavior of these bits.
197*7c478bd9Sstevel@tonic-gate  */
198*7c478bd9Sstevel@tonic-gate void
hci1394_csr_state_bset(hci1394_csr_handle_t csr_handle,uint32_t state)199*7c478bd9Sstevel@tonic-gate hci1394_csr_state_bset(hci1394_csr_handle_t csr_handle, uint32_t state)
200*7c478bd9Sstevel@tonic-gate {
201*7c478bd9Sstevel@tonic-gate 	uint32_t supported_state;
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	/* only support dreq, cmstr, and abdicate bits */
209*7c478bd9Sstevel@tonic-gate 	supported_state = state & (IEEE1394_CSR_STATE_ABDICATE |
210*7c478bd9Sstevel@tonic-gate 	    IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ);
211*7c478bd9Sstevel@tonic-gate 
212*7c478bd9Sstevel@tonic-gate 	/*
213*7c478bd9Sstevel@tonic-gate 	 * If we are setting the Cycle Master bit and we are the root node,
214*7c478bd9Sstevel@tonic-gate 	 * enable Cycle Start Packets.
215*7c478bd9Sstevel@tonic-gate 	 */
216*7c478bd9Sstevel@tonic-gate 	if ((supported_state & IEEE1394_CSR_STATE_CMSTR) &&
217*7c478bd9Sstevel@tonic-gate 	    (hci1394_ohci_root_check(csr_handle->csr_ohci))) {
218*7c478bd9Sstevel@tonic-gate 		hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci);
219*7c478bd9Sstevel@tonic-gate 	}
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate 	/* set the supported bits in csr_state */
222*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_state |= supported_state;
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
225*7c478bd9Sstevel@tonic-gate }
226*7c478bd9Sstevel@tonic-gate 
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate /*
229*7c478bd9Sstevel@tonic-gate  * hci1394_csr_state_bclr()
230*7c478bd9Sstevel@tonic-gate  *     Perform a bit clear on the CSR state register. The inverted value of
231*7c478bd9Sstevel@tonic-gate  *     state will be and'd with CSR state register. Currently we only support
232*7c478bd9Sstevel@tonic-gate  *     the dreq, cmstr, and abdicate bits in the CSR state register.  See the
233*7c478bd9Sstevel@tonic-gate  *     specs mentioned above for the behavior of these bits.
234*7c478bd9Sstevel@tonic-gate  */
235*7c478bd9Sstevel@tonic-gate void
hci1394_csr_state_bclr(hci1394_csr_handle_t csr_handle,uint32_t state)236*7c478bd9Sstevel@tonic-gate hci1394_csr_state_bclr(hci1394_csr_handle_t csr_handle, uint32_t state)
237*7c478bd9Sstevel@tonic-gate {
238*7c478bd9Sstevel@tonic-gate 	uint32_t supported_state;
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 	/* only support dreq, cmstr, and abdicate bits */
246*7c478bd9Sstevel@tonic-gate 	supported_state = state & (IEEE1394_CSR_STATE_ABDICATE |
247*7c478bd9Sstevel@tonic-gate 	    IEEE1394_CSR_STATE_CMSTR | IEEE1394_CSR_STATE_DREQ);
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 	/*
250*7c478bd9Sstevel@tonic-gate 	 * If we are clearing the Cycle Master bit and we are the root node,
251*7c478bd9Sstevel@tonic-gate 	 * disable Cycle Start Packets.
252*7c478bd9Sstevel@tonic-gate 	 */
253*7c478bd9Sstevel@tonic-gate 	if ((supported_state & IEEE1394_CSR_STATE_CMSTR) &&
254*7c478bd9Sstevel@tonic-gate 	    (hci1394_ohci_root_check(csr_handle->csr_ohci))) {
255*7c478bd9Sstevel@tonic-gate 		hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci);
256*7c478bd9Sstevel@tonic-gate 	}
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	/* Clear the supported bits in csr_state */
259*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_state &= ~state;
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
262*7c478bd9Sstevel@tonic-gate }
263*7c478bd9Sstevel@tonic-gate 
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate /*
266*7c478bd9Sstevel@tonic-gate  * hci1394_csr_split_timeout_hi_get()
267*7c478bd9Sstevel@tonic-gate  *    Read the CSR split_timeout_hi register.
268*7c478bd9Sstevel@tonic-gate  */
269*7c478bd9Sstevel@tonic-gate void
hci1394_csr_split_timeout_hi_get(hci1394_csr_handle_t csr_handle,uint32_t * split_timeout_hi)270*7c478bd9Sstevel@tonic-gate hci1394_csr_split_timeout_hi_get(hci1394_csr_handle_t csr_handle,
271*7c478bd9Sstevel@tonic-gate     uint32_t *split_timeout_hi)
272*7c478bd9Sstevel@tonic-gate {
273*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
274*7c478bd9Sstevel@tonic-gate 	ASSERT(split_timeout_hi != NULL);
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
277*7c478bd9Sstevel@tonic-gate 	*split_timeout_hi = csr_handle->csr_split_timeout_hi;
278*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
279*7c478bd9Sstevel@tonic-gate }
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 
282*7c478bd9Sstevel@tonic-gate /*
283*7c478bd9Sstevel@tonic-gate  * hci1394_csr_split_timeout_lo_get()
284*7c478bd9Sstevel@tonic-gate  *    Read the CSR split_timeout_lo register.
285*7c478bd9Sstevel@tonic-gate  */
286*7c478bd9Sstevel@tonic-gate void
hci1394_csr_split_timeout_lo_get(hci1394_csr_handle_t csr_handle,uint32_t * split_timeout_lo)287*7c478bd9Sstevel@tonic-gate hci1394_csr_split_timeout_lo_get(hci1394_csr_handle_t csr_handle,
288*7c478bd9Sstevel@tonic-gate     uint32_t *split_timeout_lo)
289*7c478bd9Sstevel@tonic-gate {
290*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
291*7c478bd9Sstevel@tonic-gate 	ASSERT(split_timeout_lo != NULL);
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate 	/*
296*7c478bd9Sstevel@tonic-gate 	 * Read the split_timeout_lo CSR register. Convert split_timeout_lo to
297*7c478bd9Sstevel@tonic-gate 	 * use the data in most significant 13 bits on the fly.
298*7c478bd9Sstevel@tonic-gate 	 */
299*7c478bd9Sstevel@tonic-gate 	*split_timeout_lo = csr_handle->csr_split_timeout_lo <<
300*7c478bd9Sstevel@tonic-gate 	    CSR_SPLIT_TIMEOUT_LO_SHIFT;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
303*7c478bd9Sstevel@tonic-gate }
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate /*
307*7c478bd9Sstevel@tonic-gate  * hci1394_csr_split_timeout_hi_set()
308*7c478bd9Sstevel@tonic-gate  *    Write the CSR split_timeout_hi register. This routine will also
309*7c478bd9Sstevel@tonic-gate  *    re-calculate the "split_timeout" which is used internally in the HAL
310*7c478bd9Sstevel@tonic-gate  *    driver. The only accesses to split_timeout_hi and split_timeout_lo
311*7c478bd9Sstevel@tonic-gate  *    should be over the 1394 bus. Only the least significant 3 bits are
312*7c478bd9Sstevel@tonic-gate  *    relevant in the split_timeout_hi register.
313*7c478bd9Sstevel@tonic-gate  */
314*7c478bd9Sstevel@tonic-gate void
hci1394_csr_split_timeout_hi_set(hci1394_csr_handle_t csr_handle,uint32_t split_timeout_hi)315*7c478bd9Sstevel@tonic-gate hci1394_csr_split_timeout_hi_set(hci1394_csr_handle_t csr_handle,
316*7c478bd9Sstevel@tonic-gate     uint32_t split_timeout_hi)
317*7c478bd9Sstevel@tonic-gate {
318*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
319*7c478bd9Sstevel@tonic-gate 
320*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 	/*
323*7c478bd9Sstevel@tonic-gate 	 * update the split_timeout_hi CSR register. Only look at the 3 LSBits.
324*7c478bd9Sstevel@tonic-gate 	 * Update our internal split_timeout value.
325*7c478bd9Sstevel@tonic-gate 	 */
326*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_split_timeout_hi = split_timeout_hi &
327*7c478bd9Sstevel@tonic-gate 	    CSR_MAX_SPLIT_TIMEOUT_HI;
328*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT(
329*7c478bd9Sstevel@tonic-gate 	    csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo);
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
332*7c478bd9Sstevel@tonic-gate }
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate /*
336*7c478bd9Sstevel@tonic-gate  * hci1394_csr_split_timeout_lo_set()
337*7c478bd9Sstevel@tonic-gate  *    Write the CSR split_timeout_lo register. This routine will also
338*7c478bd9Sstevel@tonic-gate  *    re-calculate the "split_timeout" which is used internally in the HAL
339*7c478bd9Sstevel@tonic-gate  *    driver. The only accesses to split_timeout_hi and split_timeout_lo
340*7c478bd9Sstevel@tonic-gate  *    should be over the 1394 bus. Only the most significant 13 bits are
341*7c478bd9Sstevel@tonic-gate  *    relevant in the split_timeout_lo register.
342*7c478bd9Sstevel@tonic-gate  */
343*7c478bd9Sstevel@tonic-gate void
hci1394_csr_split_timeout_lo_set(hci1394_csr_handle_t csr_handle,uint32_t split_timeout_lo)344*7c478bd9Sstevel@tonic-gate hci1394_csr_split_timeout_lo_set(hci1394_csr_handle_t csr_handle,
345*7c478bd9Sstevel@tonic-gate     uint32_t split_timeout_lo)
346*7c478bd9Sstevel@tonic-gate {
347*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate 	/*
352*7c478bd9Sstevel@tonic-gate 	 * Update the split_timeout_lo CSR register.  Only look at the 3 LSBits.
353*7c478bd9Sstevel@tonic-gate 	 * Convert the split_timeout_lo to use the data in most significant 13
354*7c478bd9Sstevel@tonic-gate 	 * bits on the fly.
355*7c478bd9Sstevel@tonic-gate 	 */
356*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_split_timeout_lo = split_timeout_lo >>
357*7c478bd9Sstevel@tonic-gate 	    CSR_SPLIT_TIMEOUT_LO_SHIFT;
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 	/* threshold the split_timeout_lo value */
360*7c478bd9Sstevel@tonic-gate 	if (csr_handle->csr_split_timeout_lo < CSR_MIN_SPLIT_TIMEOUT_LO) {
361*7c478bd9Sstevel@tonic-gate 		csr_handle->csr_split_timeout_lo = CSR_MIN_SPLIT_TIMEOUT_LO;
362*7c478bd9Sstevel@tonic-gate 	} else if (csr_handle->csr_split_timeout_lo >
363*7c478bd9Sstevel@tonic-gate 	    CSR_MAX_SPLIT_TIMEOUT_LO) {
364*7c478bd9Sstevel@tonic-gate 		csr_handle->csr_split_timeout_lo = CSR_MAX_SPLIT_TIMEOUT_LO;
365*7c478bd9Sstevel@tonic-gate 	}
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 	/* Update our internal split_timeout value */
368*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_split_timeout = CSR_SPLIT_TIMEOUT(
369*7c478bd9Sstevel@tonic-gate 	    csr_handle->csr_split_timeout_hi, csr_handle->csr_split_timeout_lo);
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
372*7c478bd9Sstevel@tonic-gate }
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate /*
376*7c478bd9Sstevel@tonic-gate  * hci1394_csr_split_timeout_get()
377*7c478bd9Sstevel@tonic-gate  *    Return the current value of split_timeout.  This is the  only routine
378*7c478bd9Sstevel@tonic-gate  *    which should be used to get the split timeout for use in a calculation
379*7c478bd9Sstevel@tonic-gate  *    (e.g. for calculating ACK pending timeout).
380*7c478bd9Sstevel@tonic-gate  */
381*7c478bd9Sstevel@tonic-gate uint_t
hci1394_csr_split_timeout_get(hci1394_csr_handle_t csr_handle)382*7c478bd9Sstevel@tonic-gate hci1394_csr_split_timeout_get(hci1394_csr_handle_t csr_handle)
383*7c478bd9Sstevel@tonic-gate {
384*7c478bd9Sstevel@tonic-gate 	uint_t split_timeout;
385*7c478bd9Sstevel@tonic-gate 
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
390*7c478bd9Sstevel@tonic-gate 
391*7c478bd9Sstevel@tonic-gate 	/* read our internal split_timeout value */
392*7c478bd9Sstevel@tonic-gate 	split_timeout = csr_handle->csr_split_timeout;
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
395*7c478bd9Sstevel@tonic-gate 
396*7c478bd9Sstevel@tonic-gate 	return (split_timeout);
397*7c478bd9Sstevel@tonic-gate }
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate /*
401*7c478bd9Sstevel@tonic-gate  * hci1394_csr_bus_reset()
402*7c478bd9Sstevel@tonic-gate  *    Perform required bus reset processing on CSR registers. This includes
403*7c478bd9Sstevel@tonic-gate  *    clearing the abdicate bit, and setting/clearing the Cycle Master bit.
404*7c478bd9Sstevel@tonic-gate  *    See sections 10.32 and 10.33 in the IEEE P1394A Draft 3.0 spec.  See
405*7c478bd9Sstevel@tonic-gate  *    section 8.3.2.2.1 in the IEEE 1394-1995 spec. This routine should be
406*7c478bd9Sstevel@tonic-gate  *    called every bus reset.
407*7c478bd9Sstevel@tonic-gate  */
408*7c478bd9Sstevel@tonic-gate void
hci1394_csr_bus_reset(hci1394_csr_handle_t csr_handle)409*7c478bd9Sstevel@tonic-gate hci1394_csr_bus_reset(hci1394_csr_handle_t csr_handle)
410*7c478bd9Sstevel@tonic-gate {
411*7c478bd9Sstevel@tonic-gate 	ASSERT(csr_handle != NULL);
412*7c478bd9Sstevel@tonic-gate 
413*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr_handle->csr_mutex);
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 	/* Clear the abdicate bit.  Always do this. */
416*7c478bd9Sstevel@tonic-gate 	csr_handle->csr_state &= ~IEEE1394_CSR_STATE_ABDICATE;
417*7c478bd9Sstevel@tonic-gate 
418*7c478bd9Sstevel@tonic-gate 	/* if we are NOT currently the root node on the bus */
419*7c478bd9Sstevel@tonic-gate 	if (hci1394_ohci_root_check(csr_handle->csr_ohci) == B_FALSE) {
420*7c478bd9Sstevel@tonic-gate 		/*
421*7c478bd9Sstevel@tonic-gate 		 * Set the was_root state.  This is needed for the Cycle Master
422*7c478bd9Sstevel@tonic-gate 		 * state machine below.
423*7c478bd9Sstevel@tonic-gate 		 */
424*7c478bd9Sstevel@tonic-gate 		csr_handle->csr_was_root = B_FALSE;
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate 		/*
427*7c478bd9Sstevel@tonic-gate 		 * Clear the Cycle Master bit.  We do not have to shut off cycle
428*7c478bd9Sstevel@tonic-gate 		 * master in OpenHCI.  The HW will automatically stop generating
429*7c478bd9Sstevel@tonic-gate 		 * Cycle Start packets when it is not the root node.
430*7c478bd9Sstevel@tonic-gate 		 */
431*7c478bd9Sstevel@tonic-gate 		csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR;
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 	/*
434*7c478bd9Sstevel@tonic-gate 	 * if we are currently the root node on the bus and we were NOT
435*7c478bd9Sstevel@tonic-gate 	 * the root before the reset.
436*7c478bd9Sstevel@tonic-gate 	 */
437*7c478bd9Sstevel@tonic-gate 	} else if (csr_handle->csr_was_root == B_FALSE) {
438*7c478bd9Sstevel@tonic-gate 
439*7c478bd9Sstevel@tonic-gate 		/* set the was_root state to TRUE */
440*7c478bd9Sstevel@tonic-gate 		csr_handle->csr_was_root = B_TRUE;
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate 		/*
443*7c478bd9Sstevel@tonic-gate 		 * if we are cycle master capable, set the Cycle Master bit and
444*7c478bd9Sstevel@tonic-gate 		 * start Cycle Start packets. We should always be Cycle Master
445*7c478bd9Sstevel@tonic-gate 		 * capable.
446*7c478bd9Sstevel@tonic-gate 		 */
447*7c478bd9Sstevel@tonic-gate 		if (hci1394_ohci_cmc_check(csr_handle->csr_ohci)) {
448*7c478bd9Sstevel@tonic-gate 			csr_handle->csr_state |= IEEE1394_CSR_STATE_CMSTR;
449*7c478bd9Sstevel@tonic-gate 			hci1394_ohci_cycle_master_enable(csr_handle->csr_ohci);
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 		/*
452*7c478bd9Sstevel@tonic-gate 		 * if we are NOT cycle master capable, clear the Cycle Master
453*7c478bd9Sstevel@tonic-gate 		 * bit and stop Cycle Start packets. We should never see this
454*7c478bd9Sstevel@tonic-gate 		 * in OpenHCI. I think? :-)
455*7c478bd9Sstevel@tonic-gate 		 */
456*7c478bd9Sstevel@tonic-gate 		} else {
457*7c478bd9Sstevel@tonic-gate 			csr_handle->csr_state &= ~IEEE1394_CSR_STATE_CMSTR;
458*7c478bd9Sstevel@tonic-gate 			hci1394_ohci_cycle_master_disable(csr_handle->csr_ohci);
459*7c478bd9Sstevel@tonic-gate 		}
460*7c478bd9Sstevel@tonic-gate 	}
461*7c478bd9Sstevel@tonic-gate 	/*
462*7c478bd9Sstevel@tonic-gate 	 * else {}
463*7c478bd9Sstevel@tonic-gate 	 * else we are root now. We were root before, keep cmstr the same.
464*7c478bd9Sstevel@tonic-gate 	 * Nothing to do.
465*7c478bd9Sstevel@tonic-gate 	 */
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr_handle->csr_mutex);
468*7c478bd9Sstevel@tonic-gate }
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate /*
472*7c478bd9Sstevel@tonic-gate  * hci1394_csr_state_init()
473*7c478bd9Sstevel@tonic-gate  *    set the CSR SW registers and state variables to their initial settings.
474*7c478bd9Sstevel@tonic-gate  */
hci1394_csr_state_init(hci1394_csr_t * csr)475*7c478bd9Sstevel@tonic-gate static void hci1394_csr_state_init(hci1394_csr_t *csr)
476*7c478bd9Sstevel@tonic-gate {
477*7c478bd9Sstevel@tonic-gate 	ASSERT(csr != NULL);
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate 	mutex_enter(&csr->csr_mutex);
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 	/*
482*7c478bd9Sstevel@tonic-gate 	 * Initialize the split timeout to be 0 seconds (split_timeout_hi) and
483*7c478bd9Sstevel@tonic-gate 	 * use a patchable variable for the initial split_timeout_lo. This
484*7c478bd9Sstevel@tonic-gate 	 * variable must be patched before the driver attaches.  It is never
485*7c478bd9Sstevel@tonic-gate 	 * looked at again after this code is run.
486*7c478bd9Sstevel@tonic-gate 	 *
487*7c478bd9Sstevel@tonic-gate 	 * Calculate the split_timeout which we will use in the driver based on
488*7c478bd9Sstevel@tonic-gate 	 * split_timeout_lo and split_timeout_hi.
489*7c478bd9Sstevel@tonic-gate 	 */
490*7c478bd9Sstevel@tonic-gate 	csr->csr_split_timeout_hi = 0;
491*7c478bd9Sstevel@tonic-gate 	csr->csr_split_timeout_lo = hci1394_split_timeout;
492*7c478bd9Sstevel@tonic-gate 	csr->csr_split_timeout = CSR_SPLIT_TIMEOUT(
493*7c478bd9Sstevel@tonic-gate 	    csr->csr_split_timeout_hi, csr->csr_split_timeout_lo);
494*7c478bd9Sstevel@tonic-gate 
495*7c478bd9Sstevel@tonic-gate 	/* Set the initial CSR State register to 0 */
496*7c478bd9Sstevel@tonic-gate 	csr->csr_state = 0;
497*7c478bd9Sstevel@tonic-gate 
498*7c478bd9Sstevel@tonic-gate 	/*
499*7c478bd9Sstevel@tonic-gate 	 * was_root is an internal state variable which tracks if we were root
500*7c478bd9Sstevel@tonic-gate 	 * last bus reset.  This is needed for the required state register bus
501*7c478bd9Sstevel@tonic-gate 	 * reset processing.
502*7c478bd9Sstevel@tonic-gate 	 */
503*7c478bd9Sstevel@tonic-gate 	csr->csr_was_root = B_FALSE;
504*7c478bd9Sstevel@tonic-gate 
505*7c478bd9Sstevel@tonic-gate 	/* setup our initial capabilities setting */
506*7c478bd9Sstevel@tonic-gate 	csr->csr_capabilities = CSR_INITIAL_NODE_CAPABILITIES;
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate 	mutex_exit(&csr->csr_mutex);
509*7c478bd9Sstevel@tonic-gate }
510