xref: /onnv-gate/usr/src/uts/common/io/1394/adapters/hci1394_vendor.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1999-2000 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * hci1394_vendor.c
31*0Sstevel@tonic-gate  *   These routines provide initialization, cleanup, and general access to
32*0Sstevel@tonic-gate  *   vendor specific features on the OpenHCI adapter.
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <sys/conf.h>
36*0Sstevel@tonic-gate #include <sys/ddi.h>
37*0Sstevel@tonic-gate #include <sys/modctl.h>
38*0Sstevel@tonic-gate #include <sys/stat.h>
39*0Sstevel@tonic-gate #include <sys/sunddi.h>
40*0Sstevel@tonic-gate #include <sys/cmn_err.h>
41*0Sstevel@tonic-gate #include <sys/kmem.h>
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate #include <sys/1394/adapters/hci1394.h>
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate /*
47*0Sstevel@tonic-gate  * Macro which makes sure vendor register offset is not greater that 0x7FC and
48*0Sstevel@tonic-gate  * that it is quadlet aligned.
49*0Sstevel@tonic-gate  */
50*0Sstevel@tonic-gate #define	VENDOR_ALIGN_ADDR(addr)	(addr & 0x7FC)
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate  * Patchable variable to have the driver set the GUID on a Sun RIO chip.
55*0Sstevel@tonic-gate  * Normally this will be done by the firmware, but for PPX cards and OBP images
56*0Sstevel@tonic-gate  * without 1394 support, we need to fo this. This is only used for RIO.  Other
57*0Sstevel@tonic-gate  * vendor cards are not effected.
58*0Sstevel@tonic-gate  *   0 - don't set GUID (default)
59*0Sstevel@tonic-gate  *   non zero - set GUID on RIO
60*0Sstevel@tonic-gate  */
61*0Sstevel@tonic-gate int hci1394_set_rio_guid = 0;
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate static int hci1394_rio_init(hci1394_vendor_t *vendor);
65*0Sstevel@tonic-gate static void hci1394_rio_guid_init(hci1394_vendor_t *vendor);
66*0Sstevel@tonic-gate static int hci1394_rio_resume(hci1394_vendor_t *vendor);
67*0Sstevel@tonic-gate 
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate /*
70*0Sstevel@tonic-gate  * hci1394_vendor_init()
71*0Sstevel@tonic-gate  *    Initialize the Vendor Specific portions of the OpenHCI chipset. This is
72*0Sstevel@tonic-gate  *    not required according to the OpenHCI spec, but may be needed for
73*0Sstevel@tonic-gate  *    performance optimizations, etc. dip, accattrp, and vendor_info are inputs.
74*0Sstevel@tonic-gate  *    num_reg_sets and vendor_handle are outputs. num_reg_sets is the number of
75*0Sstevel@tonic-gate  *    registers sets (or mappings) that are present for this device. This will
76*0Sstevel@tonic-gate  *    usually be 0 or 1. vendor_handle is an opaque handle used in rest of
77*0Sstevel@tonic-gate  *    vendor routines.
78*0Sstevel@tonic-gate  */
79*0Sstevel@tonic-gate int
hci1394_vendor_init(hci1394_drvinfo_t * drvinfo,hci1394_ohci_handle_t ohci,hci1394_vendor_info_t * vendor_info,hci1394_vendor_handle_t * vendor_handle)80*0Sstevel@tonic-gate hci1394_vendor_init(hci1394_drvinfo_t *drvinfo,  hci1394_ohci_handle_t ohci,
81*0Sstevel@tonic-gate     hci1394_vendor_info_t *vendor_info, hci1394_vendor_handle_t *vendor_handle)
82*0Sstevel@tonic-gate {
83*0Sstevel@tonic-gate 	int status;
84*0Sstevel@tonic-gate 	hci1394_vendor_t *vendor;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate 	ASSERT(drvinfo != NULL);
88*0Sstevel@tonic-gate 	ASSERT(vendor_info != NULL);
89*0Sstevel@tonic-gate 	ASSERT(vendor_handle != NULL);
90*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_init_enter, HCI1394_TNF_HAL_STACK, "");
91*0Sstevel@tonic-gate 
92*0Sstevel@tonic-gate 	/*
93*0Sstevel@tonic-gate 	 * alloc the space to keep track of the vendor registers.
94*0Sstevel@tonic-gate 	 */
95*0Sstevel@tonic-gate 	vendor = kmem_alloc(sizeof (hci1394_vendor_t), KM_SLEEP);
96*0Sstevel@tonic-gate 	vendor->ve_info = *vendor_info;
97*0Sstevel@tonic-gate 	vendor->ve_drvinfo = drvinfo;
98*0Sstevel@tonic-gate 	vendor->ve_ohci = ohci;
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 	/* setup the vendor_handle return parameter */
101*0Sstevel@tonic-gate 	*vendor_handle = vendor;
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	/* call vendor specific initialization routine */
104*0Sstevel@tonic-gate 	switch (vendor_info->vendor_id) {
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate 	/* Sun Microsystems 1394 Device */
107*0Sstevel@tonic-gate 	case VENDOR_VID_SUN_MICROSYSTEMS:
108*0Sstevel@tonic-gate 		switch (vendor_info->device_id) {
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate 		/* RIO base chip. Call the RIO specific init routine */
111*0Sstevel@tonic-gate 		case VENDOR_DID_RIO_1394:
112*0Sstevel@tonic-gate 			status = hci1394_rio_init(vendor);
113*0Sstevel@tonic-gate 			if (status != DDI_SUCCESS) {
114*0Sstevel@tonic-gate 				kmem_free(vendor,
115*0Sstevel@tonic-gate 				    sizeof (hci1394_vendor_t));
116*0Sstevel@tonic-gate 				*vendor_handle = NULL;
117*0Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_vendor_init_rio_fail,
118*0Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR, "", tnf_string,
119*0Sstevel@tonic-gate 				    errmsg, "hci1394_rio_init() failed");
120*0Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(hci1394_vendor_init_exit,
121*0Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK, "");
122*0Sstevel@tonic-gate 				return (DDI_FAILURE);
123*0Sstevel@tonic-gate 			}
124*0Sstevel@tonic-gate 			break;
125*0Sstevel@tonic-gate 			/* VENDOR_DID_RIO_1394 */
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 		/* unrecognized device - don't map any registers */
128*0Sstevel@tonic-gate 		default:
129*0Sstevel@tonic-gate 			vendor->ve_reg_count = 0;
130*0Sstevel@tonic-gate 			break;
131*0Sstevel@tonic-gate 		}
132*0Sstevel@tonic-gate 		break;
133*0Sstevel@tonic-gate 		/* VENDOR_VID_SUN_MICROSYSTEMS */
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 	/* unrecognized vendor - don't map any registers */
136*0Sstevel@tonic-gate 	default:
137*0Sstevel@tonic-gate 		vendor->ve_reg_count = 0;
138*0Sstevel@tonic-gate 		break;
139*0Sstevel@tonic-gate 	}
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	vendor_info->vendor_reg_count = vendor->ve_reg_count;
142*0Sstevel@tonic-gate 
143*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_init_exit, HCI1394_TNF_HAL_STACK, "");
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
146*0Sstevel@tonic-gate }
147*0Sstevel@tonic-gate 
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate /*
150*0Sstevel@tonic-gate  * hci1394_vendor_fini()
151*0Sstevel@tonic-gate  *    Cleanup after Vendor Specific init.  This includes freeing any allocated
152*0Sstevel@tonic-gate  *    kernel memory and freeing any mapped registers.
153*0Sstevel@tonic-gate  *
154*0Sstevel@tonic-gate  * NOTE: This routine must be called after a successful vendor_init even if the
155*0Sstevel@tonic-gate  *	 num_reg_sets = 0 during init.  This routine is normally called during
156*0Sstevel@tonic-gate  *	 the detach process.
157*0Sstevel@tonic-gate  *
158*0Sstevel@tonic-gate  * NOTE: A pointer to the handle is used for the parameter. fini() will set
159*0Sstevel@tonic-gate  *	 your handle to NULL before returning.
160*0Sstevel@tonic-gate  */
161*0Sstevel@tonic-gate void
hci1394_vendor_fini(hci1394_vendor_handle_t * vendor_handle)162*0Sstevel@tonic-gate hci1394_vendor_fini(hci1394_vendor_handle_t *vendor_handle)
163*0Sstevel@tonic-gate {
164*0Sstevel@tonic-gate 	uint_t index;
165*0Sstevel@tonic-gate 
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	ASSERT(vendor_handle != NULL);
168*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_fini_enter, HCI1394_TNF_HAL_STACK, "");
169*0Sstevel@tonic-gate 
170*0Sstevel@tonic-gate 	for (index = 0; index < (*vendor_handle)->ve_reg_count; index++) {
171*0Sstevel@tonic-gate 		ddi_regs_map_free(&(*vendor_handle)->
172*0Sstevel@tonic-gate 		    ve_reg_array[index]->vr_reg_handle);
173*0Sstevel@tonic-gate 	}
174*0Sstevel@tonic-gate 	kmem_free(*vendor_handle, sizeof (hci1394_vendor_t));
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate 	/* Set the vendor_handle to NULL to help catch bugs */
177*0Sstevel@tonic-gate 	*vendor_handle = NULL;
178*0Sstevel@tonic-gate 
179*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_fini_exit, HCI1394_TNF_HAL_STACK, "");
180*0Sstevel@tonic-gate }
181*0Sstevel@tonic-gate 
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate /*
184*0Sstevel@tonic-gate  * hci1394_vendor_resume()
185*0Sstevel@tonic-gate  *    Vendor Specific init for a power resume (DDI_RESUME). This includes
186*0Sstevel@tonic-gate  *    re-setting up any vendor specific registers.
187*0Sstevel@tonic-gate  */
188*0Sstevel@tonic-gate int
hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)189*0Sstevel@tonic-gate hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)
190*0Sstevel@tonic-gate {
191*0Sstevel@tonic-gate 	int status;
192*0Sstevel@tonic-gate 	hci1394_vendor_info_t *vendor_info;
193*0Sstevel@tonic-gate 
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	ASSERT(vendor_handle != NULL);
196*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_resume_enter, HCI1394_TNF_HAL_STACK,
197*0Sstevel@tonic-gate 	    "");
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate 	vendor_info = &vendor_handle->ve_info;
200*0Sstevel@tonic-gate 
201*0Sstevel@tonic-gate 	/* call vendor specific initialization routine */
202*0Sstevel@tonic-gate 	switch (vendor_info->vendor_id) {
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	/* Sun Microsystems 1394 Device */
205*0Sstevel@tonic-gate 	case VENDOR_VID_SUN_MICROSYSTEMS:
206*0Sstevel@tonic-gate 		switch (vendor_info->device_id) {
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate 		/* RIO base chip. Call the RIO specific resume routine */
209*0Sstevel@tonic-gate 		case VENDOR_DID_RIO_1394:
210*0Sstevel@tonic-gate 			status = hci1394_rio_resume(vendor_handle);
211*0Sstevel@tonic-gate 			if (status != DDI_SUCCESS) {
212*0Sstevel@tonic-gate 				TNF_PROBE_1(hci1394_vendor_resume_rio_fail,
213*0Sstevel@tonic-gate 				    HCI1394_TNF_HAL_ERROR, "", tnf_string,
214*0Sstevel@tonic-gate 				    errmsg, "hci1394_rio_resume() failed");
215*0Sstevel@tonic-gate 				TNF_PROBE_0_DEBUG(hci1394_vendor_resume_exit,
216*0Sstevel@tonic-gate 				    HCI1394_TNF_HAL_STACK, "");
217*0Sstevel@tonic-gate 				return (DDI_FAILURE);
218*0Sstevel@tonic-gate 			}
219*0Sstevel@tonic-gate 			break;
220*0Sstevel@tonic-gate 			/* VENDOR_DID_RIO_1394 */
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate 		/* unrecognized device - don't map any registers */
223*0Sstevel@tonic-gate 		default:
224*0Sstevel@tonic-gate 			break;
225*0Sstevel@tonic-gate 		}
226*0Sstevel@tonic-gate 		break;
227*0Sstevel@tonic-gate 		/* VENDOR_VID_SUN_MICROSYSTEMS */
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate 	/* unrecognized vendor - don't map any registers */
230*0Sstevel@tonic-gate 	default:
231*0Sstevel@tonic-gate 		break;
232*0Sstevel@tonic-gate 	}
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_resume_exit, HCI1394_TNF_HAL_STACK,
235*0Sstevel@tonic-gate 	    "");
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
238*0Sstevel@tonic-gate }
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate 
241*0Sstevel@tonic-gate /*
242*0Sstevel@tonic-gate  * hci1394_vendor_reg_write()
243*0Sstevel@tonic-gate  *    Write vendor specific register. reg_set is the register set to write. The
244*0Sstevel@tonic-gate  *    first register set would be reg_set = 0, the second reg_set = 1, etc.
245*0Sstevel@tonic-gate  *    offset is the offset into the vendor specific register space. An offset of
246*0Sstevel@tonic-gate  *    0 would be the first vendor register for that register set. data is the
247*0Sstevel@tonic-gate  *    data to write to the vendor register.
248*0Sstevel@tonic-gate  */
249*0Sstevel@tonic-gate int
hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t data)250*0Sstevel@tonic-gate hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,
251*0Sstevel@tonic-gate     uint_t reg_set, uint_t offset, uint32_t data)
252*0Sstevel@tonic-gate {
253*0Sstevel@tonic-gate 	hci1394_vendor_reg_t *venreg;
254*0Sstevel@tonic-gate 	uint32_t *regaddr;
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 
257*0Sstevel@tonic-gate 	ASSERT(vendor_handle != NULL);
258*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_reg_write_enter,
259*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate 	if (vendor_handle->ve_reg_count < (reg_set + 1)) {
262*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_vendor_reg_write_fail,
263*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
264*0Sstevel@tonic-gate 		    "reg_set not present");
265*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_vendor_reg_read_exit,
266*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
267*0Sstevel@tonic-gate 		return (DDI_FAILURE);
268*0Sstevel@tonic-gate 	}
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 	venreg = vendor_handle->ve_reg_array[reg_set];
271*0Sstevel@tonic-gate 	regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
272*0Sstevel@tonic-gate 	    (uintptr_t)VENDOR_ALIGN_ADDR(offset));
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate 	ddi_put32(venreg->vr_reg_handle, regaddr, data);
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_reg_write_exit,
277*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
278*0Sstevel@tonic-gate 
279*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
280*0Sstevel@tonic-gate }
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate /*
284*0Sstevel@tonic-gate  * hci1394_vendor_reg_read()
285*0Sstevel@tonic-gate  *    Read vendor specific register. reg_set is the register set to write. The
286*0Sstevel@tonic-gate  *    first register set would be reg_set = 0, the second reg_set = 1, etc.
287*0Sstevel@tonic-gate  *    offset is the offset into the vendor specific register space. An offset
288*0Sstevel@tonic-gate  *    of 0 would be the first vendor register for that register set. data is
289*0Sstevel@tonic-gate  *    the address to put the data read.
290*0Sstevel@tonic-gate  */
291*0Sstevel@tonic-gate int
hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t * data)292*0Sstevel@tonic-gate hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle, uint_t reg_set,
293*0Sstevel@tonic-gate     uint_t offset, uint32_t *data)
294*0Sstevel@tonic-gate {
295*0Sstevel@tonic-gate 	hci1394_vendor_reg_t *venreg;
296*0Sstevel@tonic-gate 	uint32_t *regaddr;
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate 	ASSERT(vendor_handle != NULL);
300*0Sstevel@tonic-gate 	ASSERT(data != NULL);
301*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_reg_read_enter,
302*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 	if (vendor_handle->ve_reg_count < (reg_set + 1)) {
305*0Sstevel@tonic-gate 		TNF_PROBE_1(hci1394_vendor_reg_read_fail,
306*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_ERROR, "", tnf_string, errmsg,
307*0Sstevel@tonic-gate 		    "reg_set not present");
308*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_vendor_reg_read_exit,
309*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
310*0Sstevel@tonic-gate 		return (DDI_FAILURE);
311*0Sstevel@tonic-gate 	}
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 	venreg = vendor_handle->ve_reg_array[reg_set];
314*0Sstevel@tonic-gate 	regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
315*0Sstevel@tonic-gate 	    (uintptr_t)VENDOR_ALIGN_ADDR(offset));
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	*data = ddi_get32(venreg->vr_reg_handle, regaddr);
318*0Sstevel@tonic-gate 
319*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_vendor_reg_read_exit,
320*0Sstevel@tonic-gate 	    HCI1394_TNF_HAL_STACK, "");
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
323*0Sstevel@tonic-gate }
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate /*
326*0Sstevel@tonic-gate  * hci1394_rio_init()
327*0Sstevel@tonic-gate  *    Initialize SUNW RIO vendor specific registers.
328*0Sstevel@tonic-gate  */
329*0Sstevel@tonic-gate static int
hci1394_rio_init(hci1394_vendor_t * vendor)330*0Sstevel@tonic-gate hci1394_rio_init(hci1394_vendor_t *vendor)
331*0Sstevel@tonic-gate {
332*0Sstevel@tonic-gate 	int status;
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate 	ASSERT(vendor != NULL);
336*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_init_enter, HCI1394_TNF_HAL_STACK, "");
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 	vendor->ve_reg_count = 1;
339*0Sstevel@tonic-gate 	vendor->ve_reg_array[0] = kmem_alloc(sizeof (hci1394_vendor_reg_t),
340*0Sstevel@tonic-gate 	    KM_SLEEP);
341*0Sstevel@tonic-gate 
342*0Sstevel@tonic-gate 	status = ddi_regs_map_setup(vendor->ve_drvinfo->di_dip, RIOREG_REG_BASE,
343*0Sstevel@tonic-gate 	    &vendor->ve_reg_array[0]->vr_reg_addr, RIOREG_OFFSET, RIOREG_LENGTH,
344*0Sstevel@tonic-gate 	    &vendor->ve_drvinfo->di_reg_attr,
345*0Sstevel@tonic-gate 	    &vendor->ve_reg_array[0]->vr_reg_handle);
346*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
347*0Sstevel@tonic-gate 		vendor->ve_reg_count = 0;
348*0Sstevel@tonic-gate 		kmem_free(vendor->ve_reg_array[0],
349*0Sstevel@tonic-gate 		    sizeof (hci1394_vendor_reg_t));
350*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_rio_init_rms_fail, HCI1394_TNF_HAL_ERROR,
351*0Sstevel@tonic-gate 		    "");
352*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_rio_init_exit, HCI1394_TNF_HAL_STACK,
353*0Sstevel@tonic-gate 		    "");
354*0Sstevel@tonic-gate 		return (DDI_FAILURE);
355*0Sstevel@tonic-gate 	}
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	/* Setup RIO Host Control Register */
358*0Sstevel@tonic-gate 	status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
359*0Sstevel@tonic-gate 	    RIOREG_HOST_CONTROL_SETTING);
360*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
361*0Sstevel@tonic-gate 		ddi_regs_map_free(&vendor->ve_reg_array[0]->vr_reg_handle);
362*0Sstevel@tonic-gate 		vendor->ve_reg_count = 0;
363*0Sstevel@tonic-gate 		kmem_free(vendor->ve_reg_array[0],
364*0Sstevel@tonic-gate 		    sizeof (hci1394_vendor_reg_t));
365*0Sstevel@tonic-gate 		vendor->ve_reg_array[0] = NULL;
366*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_rio_init_vrw_fail, HCI1394_TNF_HAL_ERROR,
367*0Sstevel@tonic-gate 		    "");
368*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_rio_init_exit,
369*0Sstevel@tonic-gate 		    HCI1394_TNF_HAL_STACK, "");
370*0Sstevel@tonic-gate 		return (DDI_FAILURE);
371*0Sstevel@tonic-gate 	}
372*0Sstevel@tonic-gate 
373*0Sstevel@tonic-gate 	/* Setup GUID on RIO without firmware support */
374*0Sstevel@tonic-gate 	hci1394_rio_guid_init(vendor);
375*0Sstevel@tonic-gate 
376*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_init_exit, HCI1394_TNF_HAL_STACK, "");
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate 
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate /*
383*0Sstevel@tonic-gate  * hci1394_rio_resume()
384*0Sstevel@tonic-gate  *    Re-initialize RIO.  This routine should be called during a resume.
385*0Sstevel@tonic-gate  */
386*0Sstevel@tonic-gate static int
hci1394_rio_resume(hci1394_vendor_t * vendor)387*0Sstevel@tonic-gate hci1394_rio_resume(hci1394_vendor_t *vendor)
388*0Sstevel@tonic-gate {
389*0Sstevel@tonic-gate 	int status;
390*0Sstevel@tonic-gate 
391*0Sstevel@tonic-gate 
392*0Sstevel@tonic-gate 	ASSERT(vendor != NULL);
393*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_init_enter, HCI1394_TNF_HAL_STACK, "");
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate 	/* Setup RIO Host Control Register */
396*0Sstevel@tonic-gate 	status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
397*0Sstevel@tonic-gate 	    RIOREG_HOST_CONTROL_SETTING);
398*0Sstevel@tonic-gate 	if (status != DDI_SUCCESS) {
399*0Sstevel@tonic-gate 		TNF_PROBE_0(hci1394_rio_resume_vrw_fail, HCI1394_TNF_HAL_ERROR,
400*0Sstevel@tonic-gate 		    "");
401*0Sstevel@tonic-gate 		TNF_PROBE_0_DEBUG(hci1394_rio_init_exit, HCI1394_TNF_HAL_STACK,
402*0Sstevel@tonic-gate 		    "");
403*0Sstevel@tonic-gate 		return (DDI_FAILURE);
404*0Sstevel@tonic-gate 	}
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate 	/* Setup GUID on RIO PPX */
407*0Sstevel@tonic-gate 	hci1394_rio_guid_init(vendor);
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_init_exit, HCI1394_TNF_HAL_STACK, "");
410*0Sstevel@tonic-gate 
411*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
412*0Sstevel@tonic-gate }
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate /*
416*0Sstevel@tonic-gate  * hci1394_rio_guid_init()
417*0Sstevel@tonic-gate  *    Setup a GUID in the RIO. Normally firmware would do this for the
418*0Sstevel@tonic-gate  *    motherboard version. This will not hurt a RIO  on the motherboard since we
419*0Sstevel@tonic-gate  *    won't be able to write the GUID. We should not get to this code anyway in
420*0Sstevel@tonic-gate  *    production systems.  Use a timestamp for the lower 40 bits of the GUID.
421*0Sstevel@tonic-gate  */
422*0Sstevel@tonic-gate static void
hci1394_rio_guid_init(hci1394_vendor_t * vendor)423*0Sstevel@tonic-gate hci1394_rio_guid_init(hci1394_vendor_t *vendor)
424*0Sstevel@tonic-gate {
425*0Sstevel@tonic-gate 	hrtime_t guid_timestamp;
426*0Sstevel@tonic-gate 
427*0Sstevel@tonic-gate 	ASSERT(vendor != NULL);
428*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_guid_init_enter, HCI1394_TNF_HAL_STACK,
429*0Sstevel@tonic-gate 	    "");
430*0Sstevel@tonic-gate 
431*0Sstevel@tonic-gate 	if (hci1394_set_rio_guid != 0) {
432*0Sstevel@tonic-gate 		guid_timestamp = gethrtime();
433*0Sstevel@tonic-gate 
434*0Sstevel@tonic-gate 		/* mask out the vendor field of the GUID */
435*0Sstevel@tonic-gate 		guid_timestamp = guid_timestamp & RIOREG_GUID_MASK;
436*0Sstevel@tonic-gate 
437*0Sstevel@tonic-gate 		/* fill in Sun Microsystems */
438*0Sstevel@tonic-gate 		guid_timestamp = guid_timestamp | RIOREG_GUID_SUN_MICROSYSTEMS;
439*0Sstevel@tonic-gate 
440*0Sstevel@tonic-gate 		/* write this to the GUID registers */
441*0Sstevel@tonic-gate 		ddi_put32(vendor->ve_ohci->ohci_reg_handle,
442*0Sstevel@tonic-gate 		    &vendor->ve_ohci->ohci_regs->guid_hi,
443*0Sstevel@tonic-gate 		    (uint32_t)(guid_timestamp >> 32));
444*0Sstevel@tonic-gate 		ddi_put32(vendor->ve_ohci->ohci_reg_handle,
445*0Sstevel@tonic-gate 		    &vendor->ve_ohci->ohci_regs->guid_lo,
446*0Sstevel@tonic-gate 		    (uint32_t)(guid_timestamp & 0xFFFFFFFF));
447*0Sstevel@tonic-gate 	}
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 	TNF_PROBE_0_DEBUG(hci1394_rio_guid_init_exit, HCI1394_TNF_HAL_STACK,
450*0Sstevel@tonic-gate 	    "");
451*0Sstevel@tonic-gate }
452