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