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 /*
28 * hci1394_vendor.c
29 * These routines provide initialization, cleanup, and general access to
30 * vendor specific features on the OpenHCI adapter.
31 */
32
33 #include <sys/conf.h>
34 #include <sys/ddi.h>
35 #include <sys/modctl.h>
36 #include <sys/stat.h>
37 #include <sys/sunddi.h>
38 #include <sys/cmn_err.h>
39 #include <sys/kmem.h>
40
41 #include <sys/1394/adapters/hci1394.h>
42
43
44 /*
45 * Macro which makes sure vendor register offset is not greater that 0x7FC and
46 * that it is quadlet aligned.
47 */
48 #define VENDOR_ALIGN_ADDR(addr) (addr & 0x7FC)
49
50
51 /*
52 * Patchable variable to have the driver set the GUID on a Sun RIO chip.
53 * Normally this will be done by the firmware, but for PPX cards and OBP images
54 * without 1394 support, we need to fo this. This is only used for RIO. Other
55 * vendor cards are not effected.
56 * 0 - don't set GUID (default)
57 * non zero - set GUID on RIO
58 */
59 int hci1394_set_rio_guid = 0;
60
61
62 static int hci1394_rio_init(hci1394_vendor_t *vendor);
63 static void hci1394_rio_guid_init(hci1394_vendor_t *vendor);
64 static int hci1394_rio_resume(hci1394_vendor_t *vendor);
65
66
67 /*
68 * hci1394_vendor_init()
69 * Initialize the Vendor Specific portions of the OpenHCI chipset. This is
70 * not required according to the OpenHCI spec, but may be needed for
71 * performance optimizations, etc. dip, accattrp, and vendor_info are inputs.
72 * num_reg_sets and vendor_handle are outputs. num_reg_sets is the number of
73 * registers sets (or mappings) that are present for this device. This will
74 * usually be 0 or 1. vendor_handle is an opaque handle used in rest of
75 * vendor routines.
76 */
77 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)78 hci1394_vendor_init(hci1394_drvinfo_t *drvinfo, hci1394_ohci_handle_t ohci,
79 hci1394_vendor_info_t *vendor_info, hci1394_vendor_handle_t *vendor_handle)
80 {
81 int status;
82 hci1394_vendor_t *vendor;
83
84
85 ASSERT(drvinfo != NULL);
86 ASSERT(vendor_info != NULL);
87 ASSERT(vendor_handle != NULL);
88
89 /*
90 * alloc the space to keep track of the vendor registers.
91 */
92 vendor = kmem_alloc(sizeof (hci1394_vendor_t), KM_SLEEP);
93 vendor->ve_info = *vendor_info;
94 vendor->ve_drvinfo = drvinfo;
95 vendor->ve_ohci = ohci;
96
97 /* setup the vendor_handle return parameter */
98 *vendor_handle = vendor;
99
100 /* call vendor specific initialization routine */
101 switch (vendor_info->vendor_id) {
102
103 /* Sun Microsystems 1394 Device */
104 case VENDOR_VID_SUN_MICROSYSTEMS:
105 switch (vendor_info->device_id) {
106
107 /* RIO base chip. Call the RIO specific init routine */
108 case VENDOR_DID_RIO_1394:
109 status = hci1394_rio_init(vendor);
110 if (status != DDI_SUCCESS) {
111 kmem_free(vendor,
112 sizeof (hci1394_vendor_t));
113 *vendor_handle = NULL;
114 return (DDI_FAILURE);
115 }
116 break;
117 /* VENDOR_DID_RIO_1394 */
118
119 /* unrecognized device - don't map any registers */
120 default:
121 vendor->ve_reg_count = 0;
122 break;
123 }
124 break;
125 /* VENDOR_VID_SUN_MICROSYSTEMS */
126
127 /* unrecognized vendor - don't map any registers */
128 default:
129 vendor->ve_reg_count = 0;
130 break;
131 }
132
133 vendor_info->vendor_reg_count = vendor->ve_reg_count;
134
135 return (DDI_SUCCESS);
136 }
137
138
139 /*
140 * hci1394_vendor_fini()
141 * Cleanup after Vendor Specific init. This includes freeing any allocated
142 * kernel memory and freeing any mapped registers.
143 *
144 * NOTE: This routine must be called after a successful vendor_init even if the
145 * num_reg_sets = 0 during init. This routine is normally called during
146 * the detach process.
147 *
148 * NOTE: A pointer to the handle is used for the parameter. fini() will set
149 * your handle to NULL before returning.
150 */
151 void
hci1394_vendor_fini(hci1394_vendor_handle_t * vendor_handle)152 hci1394_vendor_fini(hci1394_vendor_handle_t *vendor_handle)
153 {
154 uint_t index;
155
156
157 ASSERT(vendor_handle != NULL);
158
159 for (index = 0; index < (*vendor_handle)->ve_reg_count; index++) {
160 ddi_regs_map_free(&(*vendor_handle)->
161 ve_reg_array[index]->vr_reg_handle);
162 }
163 kmem_free(*vendor_handle, sizeof (hci1394_vendor_t));
164
165 /* Set the vendor_handle to NULL to help catch bugs */
166 *vendor_handle = NULL;
167 }
168
169
170 /*
171 * hci1394_vendor_resume()
172 * Vendor Specific init for a power resume (DDI_RESUME). This includes
173 * re-setting up any vendor specific registers.
174 */
175 int
hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)176 hci1394_vendor_resume(hci1394_vendor_handle_t vendor_handle)
177 {
178 int status;
179 hci1394_vendor_info_t *vendor_info;
180
181
182 ASSERT(vendor_handle != NULL);
183
184 vendor_info = &vendor_handle->ve_info;
185
186 /* call vendor specific initialization routine */
187 switch (vendor_info->vendor_id) {
188
189 /* Sun Microsystems 1394 Device */
190 case VENDOR_VID_SUN_MICROSYSTEMS:
191 switch (vendor_info->device_id) {
192
193 /* RIO base chip. Call the RIO specific resume routine */
194 case VENDOR_DID_RIO_1394:
195 status = hci1394_rio_resume(vendor_handle);
196 if (status != DDI_SUCCESS) {
197 return (DDI_FAILURE);
198 }
199 break;
200 /* VENDOR_DID_RIO_1394 */
201
202 /* unrecognized device - don't map any registers */
203 default:
204 break;
205 }
206 break;
207 /* VENDOR_VID_SUN_MICROSYSTEMS */
208
209 /* unrecognized vendor - don't map any registers */
210 default:
211 break;
212 }
213
214 return (DDI_SUCCESS);
215 }
216
217
218 /*
219 * hci1394_vendor_reg_write()
220 * Write vendor specific register. reg_set is the register set to write. The
221 * first register set would be reg_set = 0, the second reg_set = 1, etc.
222 * offset is the offset into the vendor specific register space. An offset of
223 * 0 would be the first vendor register for that register set. data is the
224 * data to write to the vendor register.
225 */
226 int
hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t data)227 hci1394_vendor_reg_write(hci1394_vendor_handle_t vendor_handle,
228 uint_t reg_set, uint_t offset, uint32_t data)
229 {
230 hci1394_vendor_reg_t *venreg;
231 uint32_t *regaddr;
232
233
234 ASSERT(vendor_handle != NULL);
235
236 if (vendor_handle->ve_reg_count < (reg_set + 1)) {
237 return (DDI_FAILURE);
238 }
239
240 venreg = vendor_handle->ve_reg_array[reg_set];
241 regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
242 (uintptr_t)VENDOR_ALIGN_ADDR(offset));
243
244 ddi_put32(venreg->vr_reg_handle, regaddr, data);
245
246 return (DDI_SUCCESS);
247 }
248
249
250 /*
251 * hci1394_vendor_reg_read()
252 * Read vendor specific register. reg_set is the register set to write. The
253 * first register set would be reg_set = 0, the second reg_set = 1, etc.
254 * offset is the offset into the vendor specific register space. An offset
255 * of 0 would be the first vendor register for that register set. data is
256 * the address to put the data read.
257 */
258 int
hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle,uint_t reg_set,uint_t offset,uint32_t * data)259 hci1394_vendor_reg_read(hci1394_vendor_handle_t vendor_handle, uint_t reg_set,
260 uint_t offset, uint32_t *data)
261 {
262 hci1394_vendor_reg_t *venreg;
263 uint32_t *regaddr;
264
265
266 ASSERT(vendor_handle != NULL);
267 ASSERT(data != NULL);
268
269 if (vendor_handle->ve_reg_count < (reg_set + 1)) {
270 return (DDI_FAILURE);
271 }
272
273 venreg = vendor_handle->ve_reg_array[reg_set];
274 regaddr = (uint32_t *)((uintptr_t)venreg->vr_reg_addr +
275 (uintptr_t)VENDOR_ALIGN_ADDR(offset));
276
277 *data = ddi_get32(venreg->vr_reg_handle, regaddr);
278
279 return (DDI_SUCCESS);
280 }
281
282 /*
283 * hci1394_rio_init()
284 * Initialize SUNW RIO vendor specific registers.
285 */
286 static int
hci1394_rio_init(hci1394_vendor_t * vendor)287 hci1394_rio_init(hci1394_vendor_t *vendor)
288 {
289 int status;
290
291
292 ASSERT(vendor != NULL);
293
294 vendor->ve_reg_count = 1;
295 vendor->ve_reg_array[0] = kmem_alloc(sizeof (hci1394_vendor_reg_t),
296 KM_SLEEP);
297
298 status = ddi_regs_map_setup(vendor->ve_drvinfo->di_dip, RIOREG_REG_BASE,
299 &vendor->ve_reg_array[0]->vr_reg_addr, RIOREG_OFFSET, RIOREG_LENGTH,
300 &vendor->ve_drvinfo->di_reg_attr,
301 &vendor->ve_reg_array[0]->vr_reg_handle);
302 if (status != DDI_SUCCESS) {
303 vendor->ve_reg_count = 0;
304 kmem_free(vendor->ve_reg_array[0],
305 sizeof (hci1394_vendor_reg_t));
306 return (DDI_FAILURE);
307 }
308
309 /* Setup RIO Host Control Register */
310 status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
311 RIOREG_HOST_CONTROL_SETTING);
312 if (status != DDI_SUCCESS) {
313 ddi_regs_map_free(&vendor->ve_reg_array[0]->vr_reg_handle);
314 vendor->ve_reg_count = 0;
315 kmem_free(vendor->ve_reg_array[0],
316 sizeof (hci1394_vendor_reg_t));
317 vendor->ve_reg_array[0] = NULL;
318 return (DDI_FAILURE);
319 }
320
321 /* Setup GUID on RIO without firmware support */
322 hci1394_rio_guid_init(vendor);
323
324 return (DDI_SUCCESS);
325 }
326
327
328 /*
329 * hci1394_rio_resume()
330 * Re-initialize RIO. This routine should be called during a resume.
331 */
332 static int
hci1394_rio_resume(hci1394_vendor_t * vendor)333 hci1394_rio_resume(hci1394_vendor_t *vendor)
334 {
335 int status;
336
337
338 ASSERT(vendor != NULL);
339
340 /* Setup RIO Host Control Register */
341 status = hci1394_vendor_reg_write(vendor, 0, RIOREG_HOST_CONTROL,
342 RIOREG_HOST_CONTROL_SETTING);
343 if (status != DDI_SUCCESS) {
344 return (DDI_FAILURE);
345 }
346
347 /* Setup GUID on RIO PPX */
348 hci1394_rio_guid_init(vendor);
349
350 return (DDI_SUCCESS);
351 }
352
353
354 /*
355 * hci1394_rio_guid_init()
356 * Setup a GUID in the RIO. Normally firmware would do this for the
357 * motherboard version. This will not hurt a RIO on the motherboard since we
358 * won't be able to write the GUID. We should not get to this code anyway in
359 * production systems. Use a timestamp for the lower 40 bits of the GUID.
360 */
361 static void
hci1394_rio_guid_init(hci1394_vendor_t * vendor)362 hci1394_rio_guid_init(hci1394_vendor_t *vendor)
363 {
364 hrtime_t guid_timestamp;
365
366 ASSERT(vendor != NULL);
367
368 if (hci1394_set_rio_guid != 0) {
369 guid_timestamp = gethrtime();
370
371 /* mask out the vendor field of the GUID */
372 guid_timestamp = guid_timestamp & RIOREG_GUID_MASK;
373
374 /* fill in Sun Microsystems */
375 guid_timestamp = guid_timestamp | RIOREG_GUID_SUN_MICROSYSTEMS;
376
377 /* write this to the GUID registers */
378 ddi_put32(vendor->ve_ohci->ohci_reg_handle,
379 &vendor->ve_ohci->ohci_regs->guid_hi,
380 (uint32_t)(guid_timestamp >> 32));
381 ddi_put32(vendor->ve_ohci->ohci_reg_handle,
382 &vendor->ve_ohci->ohci_regs->guid_lo,
383 (uint32_t)(guid_timestamp & 0xFFFFFFFF));
384 }
385 }
386