1 /* $Id: io.c,v 1.2 2001/06/26 14:02:43 pfg Exp $
2  *
3  * This file is subject to the terms and conditions of the GNU General Public
4  * License.  See the file "COPYING" in the main directory of this archive
5  * for more details.
6  *
7  * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
8  */
9 
10 #include <linux/config.h>
11 #include <linux/types.h>
12 #include <linux/slab.h>
13 #include <asm/sn/types.h>
14 #include <asm/sn/sgi.h>
15 #include <asm/sn/driver.h>
16 #include <asm/sn/iograph.h>
17 #include <asm/param.h>
18 #include <asm/sn/pio.h>
19 #include <asm/sn/xtalk/xwidget.h>
20 #include <asm/sn/io.h>
21 #include <asm/sn/sn_private.h>
22 #include <asm/sn/addrs.h>
23 #include <asm/sn/invent.h>
24 #include <asm/sn/hcl.h>
25 #include <asm/sn/hcl_util.h>
26 #include <asm/sn/intr.h>
27 #include <asm/sn/xtalk/xtalkaddrs.h>
28 #include <asm/sn/klconfig.h>
29 #include <asm/sn/sn_cpuid.h>
30 
31 extern xtalk_provider_t hub_provider;
32 extern void hub_intr_init(vertex_hdl_t hubv);
33 
34 static int force_fire_and_forget = 1;
35 static int ignore_conveyor_override;
36 
37 
38 /*
39  * Implementation of hub iobus operations.
40  *
41  * Hub provides a crosstalk "iobus" on IP27 systems.  These routines
42  * provide a platform-specific implementation of xtalk used by all xtalk
43  * cards on IP27 systems.
44  *
45  * Called from corresponding xtalk_* routines.
46  */
47 
48 
49 /* PIO MANAGEMENT */
50 /* For mapping system virtual address space to xtalk space on a specified widget */
51 
52 /*
53  * Setup pio structures needed for a particular hub.
54  */
55 static void
hub_pio_init(vertex_hdl_t hubv)56 hub_pio_init(vertex_hdl_t hubv)
57 {
58 	xwidgetnum_t widget;
59 	hubinfo_t hubinfo;
60 	nasid_t nasid;
61 	int bigwin;
62 	hub_piomap_t hub_piomap;
63 
64 	hubinfo_get(hubv, &hubinfo);
65 	nasid = hubinfo->h_nasid;
66 
67 	/* Initialize small window piomaps for this hub */
68 	for (widget=0; widget <= HUB_WIDGET_ID_MAX; widget++) {
69 		hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
70 		hub_piomap->hpio_xtalk_info.xp_target = widget;
71 		hub_piomap->hpio_xtalk_info.xp_xtalk_addr = 0;
72 		hub_piomap->hpio_xtalk_info.xp_mapsz = SWIN_SIZE;
73 		hub_piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)NODE_SWIN_BASE(nasid, widget);
74 		hub_piomap->hpio_hub = hubv;
75 		hub_piomap->hpio_flags = HUB_PIOMAP_IS_VALID;
76 	}
77 
78 	/* Initialize big window piomaps for this hub */
79 	for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) {
80 		hub_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin);
81 		hub_piomap->hpio_xtalk_info.xp_mapsz = BWIN_SIZE;
82 		hub_piomap->hpio_hub = hubv;
83 		hub_piomap->hpio_holdcnt = 0;
84 		hub_piomap->hpio_flags = HUB_PIOMAP_IS_BIGWINDOW;
85 		IIO_ITTE_DISABLE(nasid, bigwin);
86 	}
87 	hub_set_piomode(nasid, HUB_PIO_CONVEYOR);
88 
89 	spin_lock_init(&hubinfo->h_bwlock);
90 /*
91  * If this lock can be acquired from interrupts or bh's, add SV_INTS or SV_BHS,
92  * respectively, to the flags here.
93  */
94 	sv_init(&hubinfo->h_bwwait, &hubinfo->h_bwlock, SV_ORDER_FIFO | SV_MON_SPIN);
95 }
96 
97 /*
98  * Create a caddr_t-to-xtalk_addr mapping.
99  *
100  * Use a small window if possible (that's the usual case), but
101  * manage big windows if needed.  Big window mappings can be
102  * either FIXED or UNFIXED -- we keep at least 1 big window available
103  * for UNFIXED mappings.
104  *
105  * Returns an opaque pointer-sized type which can be passed to
106  * other hub_pio_* routines on success, or NULL if the request
107  * cannot be satisfied.
108  */
109 /* ARGSUSED */
110 hub_piomap_t
hub_piomap_alloc(vertex_hdl_t dev,device_desc_t dev_desc,iopaddr_t xtalk_addr,size_t byte_count,size_t byte_count_max,unsigned flags)111 hub_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
112 		device_desc_t dev_desc,	/* device descriptor */
113 		iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
114 		size_t byte_count,
115 		size_t byte_count_max, 	/* maximum size of a mapping */
116 		unsigned flags)		/* defined in sys/pio.h */
117 {
118 	xwidget_info_t widget_info = xwidget_info_get(dev);
119 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
120 	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
121 	hubinfo_t hubinfo;
122 	hub_piomap_t bw_piomap;
123 	int bigwin, free_bw_index;
124 	nasid_t nasid;
125 	volatile hubreg_t junk;
126 	caddr_t kvaddr;
127 #ifdef PIOMAP_UNC_ACC_SPACE
128 	uint64_t addr;
129 #endif
130 
131 	/* sanity check */
132 	if (byte_count_max > byte_count)
133 		return(NULL);
134 
135 	hubinfo_get(hubv, &hubinfo);
136 
137 	/* If xtalk_addr range is mapped by a small window, we don't have
138 	 * to do much
139 	 */
140 	if (xtalk_addr + byte_count <= SWIN_SIZE) {
141 		hub_piomap_t piomap;
142 
143 		piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
144 #ifdef PIOMAP_UNC_ACC_SPACE
145 		if (flags & PIOMAP_UNC_ACC) {
146 			addr = (uint64_t)piomap->hpio_xtalk_info.xp_kvaddr;
147 			addr |= PIOMAP_UNC_ACC_SPACE;
148 			piomap->hpio_xtalk_info.xp_kvaddr = (caddr_t)addr;
149 		}
150 #endif
151 		return piomap;
152 	}
153 
154 	/* We need to use a big window mapping.  */
155 
156 	/*
157 	 * TBD: Allow requests that would consume multiple big windows --
158 	 * split the request up and use multiple mapping entries.
159 	 * For now, reject requests that span big windows.
160 	 */
161 	if ((xtalk_addr % BWIN_SIZE) + byte_count > BWIN_SIZE)
162 		return(NULL);
163 
164 
165 	/* Round xtalk address down for big window alignement */
166 	xtalk_addr = xtalk_addr & ~(BWIN_SIZE-1);
167 
168 	/*
169 	 * Check to see if an existing big window mapping will suffice.
170 	 */
171 tryagain:
172 	free_bw_index = -1;
173 	spin_lock(&hubinfo->h_bwlock);
174 	for (bigwin=0; bigwin < HUB_NUM_BIG_WINDOW; bigwin++) {
175 		bw_piomap = hubinfo_bwin_piomap_get(hubinfo, bigwin);
176 
177 		/* If mapping is not valid, skip it */
178 		if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_VALID)) {
179 			free_bw_index = bigwin;
180 			continue;
181 		}
182 
183 		/*
184 		 * If mapping is UNFIXED, skip it.  We don't allow sharing
185 		 * of UNFIXED mappings, because this would allow starvation.
186 		 */
187 		if (!(bw_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED))
188 			continue;
189 
190 		if ( xtalk_addr == bw_piomap->hpio_xtalk_info.xp_xtalk_addr &&
191 		     widget == bw_piomap->hpio_xtalk_info.xp_target) {
192 			bw_piomap->hpio_holdcnt++;
193 			spin_unlock(&hubinfo->h_bwlock);
194 			return(bw_piomap);
195 		}
196 	}
197 
198 	/*
199 	 * None of the existing big window mappings will work for us --
200 	 * we need to establish a new mapping.
201 	 */
202 
203 	/* Insure that we don't consume all big windows with FIXED mappings */
204 	if (flags & PIOMAP_FIXED) {
205 		if (hubinfo->h_num_big_window_fixed < HUB_NUM_BIG_WINDOW-1) {
206 			ASSERT(free_bw_index >= 0);
207 			hubinfo->h_num_big_window_fixed++;
208 		} else {
209 			bw_piomap = NULL;
210 			goto done;
211 		}
212 	} else /* PIOMAP_UNFIXED */ {
213 		if (free_bw_index < 0) {
214 			if (flags & PIOMAP_NOSLEEP) {
215 				bw_piomap = NULL;
216 				goto done;
217 			}
218 
219 			sv_wait(&hubinfo->h_bwwait, 0, 0);
220 			goto tryagain;
221 		}
222 	}
223 
224 
225 	/* OK!  Allocate big window free_bw_index for this mapping. */
226  	/*
227 	 * The code below does a PIO write to setup an ITTE entry.
228 	 * We need to prevent other CPUs from seeing our updated memory
229 	 * shadow of the ITTE (in the piomap) until the ITTE entry is
230 	 * actually set up; otherwise, another CPU might attempt a PIO
231 	 * prematurely.
232 	 *
233 	 * Also, the only way we can know that an entry has been received
234 	 * by the hub and can be used by future PIO reads/writes is by
235 	 * reading back the ITTE entry after writing it.
236 	 *
237 	 * For these two reasons, we PIO read back the ITTE entry after
238 	 * we write it.
239 	 */
240 
241 	nasid = hubinfo->h_nasid;
242 	IIO_ITTE_PUT(nasid, free_bw_index, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr);
243 	junk = HUB_L(IIO_ITTE_GET(nasid, free_bw_index));
244 
245 	bw_piomap = hubinfo_bwin_piomap_get(hubinfo, free_bw_index);
246 	bw_piomap->hpio_xtalk_info.xp_dev = dev;
247 	bw_piomap->hpio_xtalk_info.xp_target = widget;
248 	bw_piomap->hpio_xtalk_info.xp_xtalk_addr = xtalk_addr;
249 	kvaddr = (caddr_t)NODE_BWIN_BASE(nasid, free_bw_index);
250 #ifdef PIOMAP_UNC_ACC_SPACE
251 	if (flags & PIOMAP_UNC_ACC) {
252 		addr = (uint64_t)kvaddr;
253 		addr |= PIOMAP_UNC_ACC_SPACE;
254 		kvaddr = (caddr_t)addr;
255 	}
256 #endif
257 	bw_piomap->hpio_xtalk_info.xp_kvaddr = kvaddr;
258 	bw_piomap->hpio_holdcnt++;
259 	bw_piomap->hpio_bigwin_num = free_bw_index;
260 
261 	if (flags & PIOMAP_FIXED)
262 		bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED;
263 	else
264 		bw_piomap->hpio_flags |= HUB_PIOMAP_IS_VALID;
265 
266 done:
267 	spin_unlock(&hubinfo->h_bwlock);
268 	return(bw_piomap);
269 }
270 
271 /*
272  * hub_piomap_free destroys a caddr_t-to-xtalk pio mapping and frees
273  * any associated mapping resources.
274  *
275  * If this * piomap was handled with a small window, or if it was handled
276  * in a big window that's still in use by someone else, then there's
277  * nothing to do.  On the other hand, if this mapping was handled
278  * with a big window, AND if we were the final user of that mapping,
279  * then destroy the mapping.
280  */
281 void
hub_piomap_free(hub_piomap_t hub_piomap)282 hub_piomap_free(hub_piomap_t hub_piomap)
283 {
284 	vertex_hdl_t hubv;
285 	hubinfo_t hubinfo;
286 	nasid_t nasid;
287 
288 	/*
289 	 * Small windows are permanently mapped to corresponding widgets,
290 	 * so there're no resources to free.
291 	 */
292 	if (!(hub_piomap->hpio_flags & HUB_PIOMAP_IS_BIGWINDOW))
293 		return;
294 
295 	ASSERT(hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID);
296 	ASSERT(hub_piomap->hpio_holdcnt > 0);
297 
298 	hubv = hub_piomap->hpio_hub;
299 	hubinfo_get(hubv, &hubinfo);
300 	nasid = hubinfo->h_nasid;
301 
302 	spin_lock(&hubinfo->h_bwlock);
303 
304 	/*
305 	 * If this is the last hold on this mapping, free it.
306 	 */
307 	if (--hub_piomap->hpio_holdcnt == 0) {
308 		IIO_ITTE_DISABLE(nasid, hub_piomap->hpio_bigwin_num );
309 
310 		if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_FIXED) {
311 			hub_piomap->hpio_flags &= ~(HUB_PIOMAP_IS_VALID | HUB_PIOMAP_IS_FIXED);
312 			hubinfo->h_num_big_window_fixed--;
313 			ASSERT(hubinfo->h_num_big_window_fixed >= 0);
314 		} else
315 			hub_piomap->hpio_flags &= ~HUB_PIOMAP_IS_VALID;
316 
317 		(void)sv_signal(&hubinfo->h_bwwait);
318 	}
319 
320 	spin_unlock(&hubinfo->h_bwlock);
321 }
322 
323 /*
324  * Establish a mapping to a given xtalk address range using the resources
325  * allocated earlier.
326  */
327 caddr_t
hub_piomap_addr(hub_piomap_t hub_piomap,iopaddr_t xtalk_addr,size_t byte_count)328 hub_piomap_addr(hub_piomap_t hub_piomap,	/* mapping resources */
329 		iopaddr_t xtalk_addr,		/* map for this xtalk address */
330 		size_t byte_count)		/* map this many bytes */
331 {
332 	/* Verify that range can be mapped using the specified piomap */
333 	if (xtalk_addr < hub_piomap->hpio_xtalk_info.xp_xtalk_addr)
334 		return(0);
335 
336 	if (xtalk_addr + byte_count >
337 		( hub_piomap->hpio_xtalk_info.xp_xtalk_addr +
338 			hub_piomap->hpio_xtalk_info.xp_mapsz))
339 		return(0);
340 
341 	if (hub_piomap->hpio_flags & HUB_PIOMAP_IS_VALID)
342 		return(hub_piomap->hpio_xtalk_info.xp_kvaddr +
343 			(xtalk_addr % hub_piomap->hpio_xtalk_info.xp_mapsz));
344 	else
345 		return(0);
346 }
347 
348 
349 /*
350  * Driver indicates that it's done with PIO's from an earlier piomap_addr.
351  */
352 /* ARGSUSED */
353 void
hub_piomap_done(hub_piomap_t hub_piomap)354 hub_piomap_done(hub_piomap_t hub_piomap)	/* done with these mapping resources */
355 {
356 	/* Nothing to do */
357 }
358 
359 
360 /*
361  * For translations that require no mapping resources, supply a kernel virtual
362  * address that maps to the specified xtalk address range.
363  */
364 /* ARGSUSED */
365 caddr_t
hub_piotrans_addr(vertex_hdl_t dev,device_desc_t dev_desc,iopaddr_t xtalk_addr,size_t byte_count,unsigned flags)366 hub_piotrans_addr(	vertex_hdl_t dev,	/* translate to this device */
367 			device_desc_t dev_desc,	/* device descriptor */
368 			iopaddr_t xtalk_addr,	/* Crosstalk address */
369 			size_t byte_count,	/* map this many bytes */
370 			unsigned flags)		/* (currently unused) */
371 {
372 	xwidget_info_t widget_info = xwidget_info_get(dev);
373 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
374 	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
375 	hub_piomap_t hub_piomap;
376 	hubinfo_t hubinfo;
377 	caddr_t addr;
378 
379 	hubinfo_get(hubv, &hubinfo);
380 
381 	if (xtalk_addr + byte_count <= SWIN_SIZE) {
382 		hub_piomap = hubinfo_swin_piomap_get(hubinfo, (int)widget);
383 		addr = hub_piomap_addr(hub_piomap, xtalk_addr, byte_count);
384 #ifdef PIOMAP_UNC_ACC_SPACE
385 		if (flags & PIOMAP_UNC_ACC) {
386 			uint64_t iaddr;
387 			iaddr = (uint64_t)addr;
388 			iaddr |= PIOMAP_UNC_ACC_SPACE;
389 			addr = (caddr_t)iaddr;
390 		}
391 #endif
392 		return(addr);
393 	} else
394 		return(0);
395 }
396 
397 
398 /* DMA MANAGEMENT */
399 /* Mapping from crosstalk space to system physical space */
400 
401 
402 /*
403  * Allocate resources needed to set up DMA mappings up to a specified size
404  * on a specified adapter.
405  *
406  * We don't actually use the adapter ID for anything.  It's just the adapter
407  * that the lower level driver plans to use for DMA.
408  */
409 /* ARGSUSED */
410 hub_dmamap_t
hub_dmamap_alloc(vertex_hdl_t dev,device_desc_t dev_desc,size_t byte_count_max,unsigned flags)411 hub_dmamap_alloc(	vertex_hdl_t dev,	/* set up mappings for this device */
412 			device_desc_t dev_desc,	/* device descriptor */
413 			size_t byte_count_max, 	/* max size of a mapping */
414 			unsigned flags)		/* defined in dma.h */
415 {
416 	hub_dmamap_t dmamap;
417 	xwidget_info_t widget_info = xwidget_info_get(dev);
418 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
419 	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
420 
421 	dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
422 	dmamap->hdma_xtalk_info.xd_dev = dev;
423 	dmamap->hdma_xtalk_info.xd_target = widget;
424 	dmamap->hdma_hub = hubv;
425 	dmamap->hdma_flags = HUB_DMAMAP_IS_VALID;
426  	if (flags & XTALK_FIXED)
427 		dmamap->hdma_flags |= HUB_DMAMAP_IS_FIXED;
428 
429 	return(dmamap);
430 }
431 
432 /*
433  * Destroy a DMA mapping from crosstalk space to system address space.
434  * There is no actual mapping hardware to destroy, but we at least mark
435  * the dmamap INVALID and free the space that it took.
436  */
437 void
hub_dmamap_free(hub_dmamap_t hub_dmamap)438 hub_dmamap_free(hub_dmamap_t hub_dmamap)
439 {
440 	hub_dmamap->hdma_flags &= ~HUB_DMAMAP_IS_VALID;
441 	kfree(hub_dmamap);
442 }
443 
444 /*
445  * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
446  * Return an appropriate crosstalk address range that maps to the specified physical
447  * address range.
448  */
449 /* ARGSUSED */
450 extern iopaddr_t
hub_dmamap_addr(hub_dmamap_t dmamap,paddr_t paddr,size_t byte_count)451 hub_dmamap_addr(	hub_dmamap_t dmamap,	/* use these mapping resources */
452 			paddr_t paddr,		/* map for this address */
453 			size_t byte_count)	/* map this many bytes */
454 {
455 	vertex_hdl_t vhdl;
456 
457 	ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
458 
459 	if (dmamap->hdma_flags & HUB_DMAMAP_USED) {
460 	    /* If the map is FIXED, re-use is OK. */
461 	    if (!(dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
462 		char name[MAXDEVNAME];
463 		vhdl = dmamap->hdma_xtalk_info.xd_dev;
464 		printk(KERN_WARNING  "%s: hub_dmamap_addr re-uses dmamap.\n", vertex_to_name(vhdl, name, MAXDEVNAME));
465 	    }
466 	} else {
467 		dmamap->hdma_flags |= HUB_DMAMAP_USED;
468 	}
469 
470 	/* There isn't actually any DMA mapping hardware on the hub. */
471         return( (PHYS_TO_DMA(paddr)) );
472 }
473 
474 /*
475  * Establish a DMA mapping using the resources allocated in a previous dmamap_alloc.
476  * Return an appropriate crosstalk address list that maps to the specified physical
477  * address list.
478  */
479 /* ARGSUSED */
480 alenlist_t
hub_dmamap_list(hub_dmamap_t hub_dmamap,alenlist_t palenlist,unsigned flags)481 hub_dmamap_list(hub_dmamap_t hub_dmamap,	/* use these mapping resources */
482 		alenlist_t palenlist,		/* map this area of memory */
483 		unsigned flags)
484 {
485 	vertex_hdl_t vhdl;
486 
487 	ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
488 
489 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
490 	    /* If the map is FIXED, re-use is OK. */
491 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
492 		char name[MAXDEVNAME];
493 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
494 		printk(KERN_WARNING  "%s: hub_dmamap_list re-uses dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME));
495 	    }
496 	} else {
497 		hub_dmamap->hdma_flags |= HUB_DMAMAP_USED;
498 	}
499 
500 	/* There isn't actually any DMA mapping hardware on the hub.  */
501 	return(palenlist);
502 }
503 
504 /*
505  * Driver indicates that it has completed whatever DMA it may have started
506  * after an earlier dmamap_addr or dmamap_list call.
507  */
508 void
hub_dmamap_done(hub_dmamap_t hub_dmamap)509 hub_dmamap_done(hub_dmamap_t hub_dmamap)	/* done with these mapping resources */
510 {
511 	vertex_hdl_t vhdl;
512 
513 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
514 		hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
515 	} else {
516 	    /* If the map is FIXED, re-done is OK. */
517 	    if (!(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_FIXED)) {
518 		char name[MAXDEVNAME];
519 		vhdl = hub_dmamap->hdma_xtalk_info.xd_dev;
520 		printk(KERN_WARNING  "%s: hub_dmamap_done already done with dmamap\n", vertex_to_name(vhdl, name, MAXDEVNAME));
521 	    }
522 	}
523 }
524 
525 /*
526  * Translate a single system physical address into a crosstalk address.
527  */
528 /* ARGSUSED */
529 iopaddr_t
hub_dmatrans_addr(vertex_hdl_t dev,device_desc_t dev_desc,paddr_t paddr,size_t byte_count,unsigned flags)530 hub_dmatrans_addr(	vertex_hdl_t dev,	/* translate for this device */
531 			device_desc_t dev_desc,	/* device descriptor */
532 			paddr_t paddr,		/* system physical address */
533 			size_t byte_count,	/* length */
534 			unsigned flags)		/* defined in dma.h */
535 {
536 	return( (PHYS_TO_DMA(paddr)) );
537 }
538 
539 /*
540  * Translate a list of IP27 addresses and lengths into a list of crosstalk
541  * addresses and lengths.  No actual hardware mapping takes place; the hub
542  * has no DMA mapping registers -- crosstalk addresses map directly.
543  */
544 /* ARGSUSED */
545 alenlist_t
hub_dmatrans_list(vertex_hdl_t dev,device_desc_t dev_desc,alenlist_t palenlist,unsigned flags)546 hub_dmatrans_list(	vertex_hdl_t dev,	/* translate for this device */
547 			device_desc_t dev_desc,	/* device descriptor */
548 			alenlist_t palenlist,	/* system address/length list */
549 			unsigned flags)		/* defined in dma.h */
550 {
551 	BUG();
552 	/* no translation needed */
553 	return(palenlist);
554 }
555 
556 /*ARGSUSED*/
557 void
hub_dmamap_drain(hub_dmamap_t map)558 hub_dmamap_drain(	hub_dmamap_t map)
559 {
560     /* XXX- flush caches, if cache coherency WAR is needed */
561 }
562 
563 /*ARGSUSED*/
564 void
hub_dmaaddr_drain(vertex_hdl_t vhdl,paddr_t addr,size_t bytes)565 hub_dmaaddr_drain(	vertex_hdl_t vhdl,
566 			paddr_t addr,
567 			size_t bytes)
568 {
569     /* XXX- flush caches, if cache coherency WAR is needed */
570 }
571 
572 /*ARGSUSED*/
573 void
hub_dmalist_drain(vertex_hdl_t vhdl,alenlist_t list)574 hub_dmalist_drain(	vertex_hdl_t vhdl,
575 			alenlist_t list)
576 {
577     /* XXX- flush caches, if cache coherency WAR is needed */
578 }
579 
580 
581 int
hub_dma_enabled(vertex_hdl_t xconn_vhdl)582 hub_dma_enabled(vertex_hdl_t xconn_vhdl)
583 {
584 	return(0);
585 }
586 
587 int
hub_error_devenable(vertex_hdl_t xconn_vhdl,int devnum,int error_code)588 hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
589 {
590 	return(0);
591 }
592 
593 
594 /* CONFIGURATION MANAGEMENT */
595 
596 /*
597  * Perform initializations that allow this hub to start crosstalk support.
598  */
599 void
hub_provider_startup(vertex_hdl_t hubv)600 hub_provider_startup(vertex_hdl_t hubv)
601 {
602 	hub_pio_init(hubv);
603 	hub_intr_init(hubv);
604 }
605 
606 /*
607  * Shutdown crosstalk support from a hub.
608  */
609 void
hub_provider_shutdown(vertex_hdl_t hub)610 hub_provider_shutdown(vertex_hdl_t hub)
611 {
612 	/* TBD */
613 	xtalk_provider_unregister(hub);
614 }
615 
616 /*
617  * Check that an address is in the real small window widget 0 space
618  * or else in the big window we're using to emulate small window 0
619  * in the kernel.
620  */
621 int
hub_check_is_widget0(void * addr)622 hub_check_is_widget0(void *addr)
623 {
624 	nasid_t nasid = NASID_GET(addr);
625 
626 	if (((__psunsigned_t)addr >= RAW_NODE_SWIN_BASE(nasid, 0)) &&
627 	    ((__psunsigned_t)addr < RAW_NODE_SWIN_BASE(nasid, 1)))
628 		return 1;
629 	return 0;
630 }
631 
632 
633 /*
634  * Check that two addresses use the same widget
635  */
636 int
hub_check_window_equiv(void * addra,void * addrb)637 hub_check_window_equiv(void *addra, void *addrb)
638 {
639 	if (hub_check_is_widget0(addra) && hub_check_is_widget0(addrb))
640 		return 1;
641 
642 	/* XXX - Assume this is really a small window address */
643 	if (WIDGETID_GET((__psunsigned_t)addra) ==
644 	    WIDGETID_GET((__psunsigned_t)addrb))
645 		return 1;
646 
647 	return 0;
648 }
649 
650 
651 /*
652  * hub_setup_prb(nasid, prbnum, credits, conveyor)
653  *
654  * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otherwise,
655  * 	put it into conveyor belt mode with the specified number of credits.
656  */
657 void
hub_setup_prb(nasid_t nasid,int prbnum,int credits,int conveyor)658 hub_setup_prb(nasid_t nasid, int prbnum, int credits, int conveyor)
659 {
660 	iprb_t prb;
661 	int prb_offset;
662 
663 	if (force_fire_and_forget && !ignore_conveyor_override)
664 	    if (conveyor == HUB_PIO_CONVEYOR)
665 		conveyor = HUB_PIO_FIRE_N_FORGET;
666 
667 	/*
668 	 * Get the current register value.
669 	 */
670 	prb_offset = IIO_IOPRB(prbnum);
671 	prb.iprb_regval = REMOTE_HUB_L(nasid, prb_offset);
672 
673 	/*
674 	 * Clear out some fields.
675 	 */
676 	prb.iprb_ovflow = 1;
677 	prb.iprb_bnakctr = 0;
678 	prb.iprb_anakctr = 0;
679 
680 	/*
681 	 * Enable or disable fire-and-forget mode.
682 	 */
683 	prb.iprb_ff = ((conveyor == HUB_PIO_CONVEYOR) ? 0 : 1);
684 
685 	/*
686 	 * Set the appropriate number of PIO cresits for the widget.
687 	 */
688 	prb.iprb_xtalkctr = credits;
689 
690 	/*
691 	 * Store the new value to the register.
692 	 */
693 	REMOTE_HUB_S(nasid, prb_offset, prb.iprb_regval);
694 }
695 
696 /*
697  * hub_set_piomode()
698  *
699  * 	Put the hub into either "PIO conveyor belt" mode or "fire-and-forget"
700  * 	mode.  To do this, we have to make absolutely sure that no PIOs
701  *	are in progress so we turn off access to all widgets for the duration
702  *	of the function.
703  *
704  * XXX - This code should really check what kind of widget we're talking
705  * to.  Bridges can only handle three requests, but XG will do more.
706  * How many can crossbow handle to widget 0?  We're assuming 1.
707  *
708  * XXX - There is a bug in the crossbow that link reset PIOs do not
709  * return write responses.  The easiest solution to this problem is to
710  * leave widget 0 (xbow) in fire-and-forget mode at all times.  This
711  * only affects pio's to xbow registers, which should be rare.
712  */
713 void
hub_set_piomode(nasid_t nasid,int conveyor)714 hub_set_piomode(nasid_t nasid, int conveyor)
715 {
716 	hubreg_t ii_iowa;
717 	int direct_connect;
718 	hubii_wcr_t ii_wcr;
719 	int prbnum;
720 
721 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
722 
723 	ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
724 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
725 
726 	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid, IIO_WCR);
727 	direct_connect = ii_wcr.iwcr_dir_con;
728 
729 	if (direct_connect) {
730 		/*
731 		 * Assume a bridge here.
732 		 */
733 		hub_setup_prb(nasid, 0, 3, conveyor);
734 	} else {
735 		/*
736 		 * Assume a crossbow here.
737 		 */
738 		hub_setup_prb(nasid, 0, 1, conveyor);
739 	}
740 
741 	for (prbnum = HUB_WIDGET_ID_MIN; prbnum <= HUB_WIDGET_ID_MAX; prbnum++) {
742 		/*
743 		 * XXX - Here's where we should take the widget type into
744 		 * when account assigning credits.
745 		 */
746 		/* Always set the PRBs in fire-and-forget mode */
747 		hub_setup_prb(nasid, prbnum, 3, conveyor);
748 	}
749 
750 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
751 }
752 /* Interface to allow special drivers to set hub specific
753  * device flags.
754  * Return 0 on failure , 1 on success
755  */
756 int
hub_widget_flags_set(nasid_t nasid,xwidgetnum_t widget_num,hub_widget_flags_t flags)757 hub_widget_flags_set(nasid_t		nasid,
758 		     xwidgetnum_t	widget_num,
759 		     hub_widget_flags_t	flags)
760 {
761 
762 	ASSERT((flags & HUB_WIDGET_FLAGS) == flags);
763 
764 	if (flags & HUB_PIO_CONVEYOR) {
765 		hub_setup_prb(nasid,widget_num,
766 			      3,HUB_PIO_CONVEYOR); /* set the PRB in conveyor
767 						    * belt mode with 3 credits
768 						    */
769 	} else if (flags & HUB_PIO_FIRE_N_FORGET) {
770 		hub_setup_prb(nasid,widget_num,
771 			      3,HUB_PIO_FIRE_N_FORGET); /* set the PRB in fire
772 							 *  and forget mode
773 							 */
774 	}
775 
776 	return 1;
777 }
778 
779 /*
780  * A pointer to this structure hangs off of every hub hwgraph vertex.
781  * The generic xtalk layer may indirect through it to get to this specific
782  * crosstalk bus provider.
783  */
784 xtalk_provider_t hub_provider = {
785 	(xtalk_piomap_alloc_f *)	hub_piomap_alloc,
786 	(xtalk_piomap_free_f *)		hub_piomap_free,
787 	(xtalk_piomap_addr_f *)		hub_piomap_addr,
788 	(xtalk_piomap_done_f *)		hub_piomap_done,
789 	(xtalk_piotrans_addr_f *)	hub_piotrans_addr,
790 
791 	(xtalk_dmamap_alloc_f *)	hub_dmamap_alloc,
792 	(xtalk_dmamap_free_f *)		hub_dmamap_free,
793 	(xtalk_dmamap_addr_f *)		hub_dmamap_addr,
794 	(xtalk_dmamap_list_f *)		hub_dmamap_list,
795 	(xtalk_dmamap_done_f *)		hub_dmamap_done,
796 	(xtalk_dmatrans_addr_f *)	hub_dmatrans_addr,
797 	(xtalk_dmatrans_list_f *)	hub_dmatrans_list,
798 	(xtalk_dmamap_drain_f *)	hub_dmamap_drain,
799 	(xtalk_dmaaddr_drain_f *)	hub_dmaaddr_drain,
800 	(xtalk_dmalist_drain_f *)	hub_dmalist_drain,
801 
802 	(xtalk_intr_alloc_f *)		hub_intr_alloc,
803 	(xtalk_intr_alloc_f *)		hub_intr_alloc_nothd,
804 	(xtalk_intr_free_f *)		hub_intr_free,
805 	(xtalk_intr_connect_f *)	hub_intr_connect,
806 	(xtalk_intr_disconnect_f *)	hub_intr_disconnect,
807 	(xtalk_provider_startup_f *)	hub_provider_startup,
808 	(xtalk_provider_shutdown_f *)	hub_provider_shutdown,
809 };
810 
811 /*
812  * per_ice_init
813  *
814  *      This code is executed once for each Ice chip.
815  */
816 void
per_ice_init(cnodeid_t cnode)817 per_ice_init(cnodeid_t cnode)
818 {
819 
820         /* Initialize error interrupts for this ice. */
821 	printk("per_ice_init: We need to init ice here ....!\n");
822         /* ice_error_init(cnode); */
823 
824 }
825 /*
826  * per_hub_init
827  *
828  *	This code is executed once for each Hub chip.
829  */
830 void
per_hub_init(cnodeid_t cnode)831 per_hub_init(cnodeid_t cnode)
832 {
833 	nasid_t		nasid;
834 	nodepda_t	*npdap;
835 	ii_icmr_u_t	ii_icmr;
836 	ii_ibcr_u_t	ii_ibcr;
837 	ii_ilcsr_u_t	ii_ilcsr;
838 
839 	nasid = COMPACT_TO_NASID_NODEID(cnode);
840 
841 	ASSERT(nasid != INVALID_NASID);
842 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
843 
844 	npdap = NODEPDA(cnode);
845 
846 	/* Disable the request and reply errors. */
847 	REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000);
848 
849 	/*
850 	 * Set the total number of CRBs that can be used.
851 	 */
852 	ii_icmr.ii_icmr_regval= 0x0;
853 	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
854 	if (enable_shub_wars_1_1() ) {
855 		// Set bit one of ICMR to prevent II from sending interrupt for II bug.
856 		ii_icmr.ii_icmr_regval |= 0x1;
857 	}
858 	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
859 
860 	/*
861 	 * Set the number of CRBs that both of the BTEs combined
862 	 * can use minus 1.
863 	 */
864 	ii_ibcr.ii_ibcr_regval= 0x0;
865 	ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
866 	if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) {
867 	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
868 	} else {
869 	    /*
870 	     * if the LLP is down, there is no attached I/O, so
871 	    * give BTE all the CRBs.
872 	    */
873 	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x14;
874 	}
875 	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
876 
877 	/*
878 	 * Set CRB timeout to be 10ms.
879 	 */
880 	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
881 	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
882 
883 	/* Initialize error interrupts for this hub. */
884 	hub_error_init(cnode);
885 }
886 
887 
888