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
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 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
hci1394_vendor_fini(hci1394_vendor_handle_t * vendor_handle)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
hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)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
hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t data)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
hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t * data)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
hci1394_rio_init(hci1394_vendor_t * vendor)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
hci1394_rio_resume(hci1394_vendor_t * vendor)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
hci1394_rio_guid_init(hci1394_vendor_t * vendor)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