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 */
61int hci1394_set_rio_guid = 0;
62
63
64static int hci1394_rio_init(hci1394_vendor_t *vendor);
65static void hci1394_rio_guid_init(hci1394_vendor_t *vendor);
66static 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 */
79int
80hci1394_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 */
161void
162hci1394_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 */
188int
189hci1394_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 */
249int
250hci1394_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 */
291int
292hci1394_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 */
329static int
330hci1394_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 */
386static int
387hci1394_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 */
422static void
423hci1394_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