• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
7  */
8 
9 #include <linux/bootmem.h>
10 #include <asm/sn/types.h>
11 #include <asm/sn/addrs.h>
12 #include <asm/sn/sn_feature_sets.h>
13 #include <asm/sn/geo.h>
14 #include <asm/sn/io.h>
15 #include <asm/sn/l1.h>
16 #include <asm/sn/module.h>
17 #include <asm/sn/pcibr_provider.h>
18 #include <asm/sn/pcibus_provider_defs.h>
19 #include <asm/sn/pcidev.h>
20 #include <asm/sn/simulator.h>
21 #include <asm/sn/sn_sal.h>
22 #include <asm/sn/tioca_provider.h>
23 #include <asm/sn/tioce_provider.h>
24 #include "xtalk/hubdev.h"
25 #include "xtalk/xwidgetdev.h"
26 #include <linux/acpi.h>
27 #include <asm/sn/sn2/sn_hwperf.h>
28 #include <asm/sn/acpi.h>
29 
30 extern void sn_init_cpei_timer(void);
31 extern void register_sn_procfs(void);
32 extern void sn_io_acpi_init(void);
33 extern void sn_io_init(void);
34 
35 
36 static struct list_head sn_sysdata_list;
37 
38 /* sysdata list struct */
39 struct sysdata_el {
40 	struct list_head entry;
41 	void *sysdata;
42 };
43 
44 int sn_ioif_inited;		/* SN I/O infrastructure initialized? */
45 
46 int sn_acpi_rev;		/* SN ACPI revision */
47 EXPORT_SYMBOL_GPL(sn_acpi_rev);
48 
49 struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES];	/* indexed by asic type */
50 
51 /*
52  * Hooks and struct for unsupported pci providers
53  */
54 
55 static dma_addr_t
sn_default_pci_map(struct pci_dev * pdev,unsigned long paddr,size_t size,int type)56 sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
57 {
58 	return 0;
59 }
60 
61 static void
sn_default_pci_unmap(struct pci_dev * pdev,dma_addr_t addr,int direction)62 sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
63 {
64 	return;
65 }
66 
67 static void *
sn_default_pci_bus_fixup(struct pcibus_bussoft * soft,struct pci_controller * controller)68 sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
69 {
70 	return NULL;
71 }
72 
73 static struct sn_pcibus_provider sn_pci_default_provider = {
74 	.dma_map = sn_default_pci_map,
75 	.dma_map_consistent = sn_default_pci_map,
76 	.dma_unmap = sn_default_pci_unmap,
77 	.bus_fixup = sn_default_pci_bus_fixup,
78 };
79 
80 /*
81  * Retrieve the DMA Flush List given nasid, widget, and device.
82  * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
83  */
84 static inline u64
sal_get_device_dmaflush_list(u64 nasid,u64 widget_num,u64 device_num,u64 address)85 sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
86 			     u64 address)
87 {
88 	struct ia64_sal_retval ret_stuff;
89 	ret_stuff.status = 0;
90 	ret_stuff.v0 = 0;
91 
92 	SAL_CALL_NOLOCK(ret_stuff,
93 			(u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
94 			(u64) nasid, (u64) widget_num,
95 			(u64) device_num, (u64) address, 0, 0, 0);
96 	return ret_stuff.status;
97 }
98 
99 /*
100  * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
101  *			  device.
102  */
103 inline struct pcidev_info *
sn_pcidev_info_get(struct pci_dev * dev)104 sn_pcidev_info_get(struct pci_dev *dev)
105 {
106 	struct pcidev_info *pcidev;
107 
108 	list_for_each_entry(pcidev,
109 			    &(SN_PLATFORM_DATA(dev)->pcidev_info), pdi_list) {
110 		if (pcidev->pdi_linux_pcidev == dev)
111 			return pcidev;
112 	}
113 	return NULL;
114 }
115 
116 /* Older PROM flush WAR
117  *
118  * 01/16/06 -- This war will be in place until a new official PROM is released.
119  * Additionally note that the struct sn_flush_device_war also has to be
120  * removed from arch/ia64/sn/include/xtalk/hubdev.h
121  */
122 static u8 war_implemented = 0;
123 
sn_device_fixup_war(u64 nasid,u64 widget,int device,struct sn_flush_device_common * common)124 static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
125 			       struct sn_flush_device_common *common)
126 {
127 	struct sn_flush_device_war *war_list;
128 	struct sn_flush_device_war *dev_entry;
129 	struct ia64_sal_retval isrv = {0,0,0,0};
130 
131 	if (!war_implemented) {
132 		printk(KERN_WARNING "PROM version < 4.50 -- implementing old "
133 		       "PROM flush WAR\n");
134 		war_implemented = 1;
135 	}
136 
137 	war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL);
138 	if (!war_list)
139 		BUG();
140 
141 	SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
142 			nasid, widget, __pa(war_list), 0, 0, 0 ,0);
143 	if (isrv.status)
144 		panic("sn_device_fixup_war failed: %s\n",
145 		      ia64_sal_strerror(isrv.status));
146 
147 	dev_entry = war_list + device;
148 	memcpy(common,dev_entry, sizeof(*common));
149 	kfree(war_list);
150 
151 	return isrv.status;
152 }
153 
154 /*
155  * sn_common_hubdev_init() - This routine is called to initialize the HUB data
156  *			     structure for each node in the system.
157  */
158 void __init
sn_common_hubdev_init(struct hubdev_info * hubdev)159 sn_common_hubdev_init(struct hubdev_info *hubdev)
160 {
161 
162 	struct sn_flush_device_kernel *sn_flush_device_kernel;
163 	struct sn_flush_device_kernel *dev_entry;
164 	s64 status;
165 	int widget, device, size;
166 
167 	/* Attach the error interrupt handlers */
168 	if (hubdev->hdi_nasid & 1)	/* If TIO */
169 		ice_error_init(hubdev);
170 	else
171 		hub_error_init(hubdev);
172 
173 	for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++)
174 		hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev;
175 
176 	if (!hubdev->hdi_flush_nasid_list.widget_p)
177 		return;
178 
179 	size = (HUB_WIDGET_ID_MAX + 1) *
180 		sizeof(struct sn_flush_device_kernel *);
181 	hubdev->hdi_flush_nasid_list.widget_p =
182 		kzalloc(size, GFP_KERNEL);
183 	if (!hubdev->hdi_flush_nasid_list.widget_p)
184 		BUG();
185 
186 	for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
187 		size = DEV_PER_WIDGET *
188 			sizeof(struct sn_flush_device_kernel);
189 		sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
190 		if (!sn_flush_device_kernel)
191 			BUG();
192 
193 		dev_entry = sn_flush_device_kernel;
194 		for (device = 0; device < DEV_PER_WIDGET;
195 		     device++, dev_entry++) {
196 			size = sizeof(struct sn_flush_device_common);
197 			dev_entry->common = kzalloc(size, GFP_KERNEL);
198 			if (!dev_entry->common)
199 				BUG();
200 			if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST))
201 				status = sal_get_device_dmaflush_list(
202 					     hubdev->hdi_nasid, widget, device,
203 					     (u64)(dev_entry->common));
204 			else
205 				status = sn_device_fixup_war(hubdev->hdi_nasid,
206 							     widget, device,
207 							     dev_entry->common);
208 			if (status != SALRET_OK)
209 				panic("SAL call failed: %s\n",
210 				      ia64_sal_strerror(status));
211 
212 			spin_lock_init(&dev_entry->sfdl_flush_lock);
213 		}
214 
215 		if (sn_flush_device_kernel)
216 			hubdev->hdi_flush_nasid_list.widget_p[widget] =
217 							 sn_flush_device_kernel;
218 	}
219 }
220 
sn_pci_unfixup_slot(struct pci_dev * dev)221 void sn_pci_unfixup_slot(struct pci_dev *dev)
222 {
223 	struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;
224 
225 	sn_irq_unfixup(dev);
226 	pci_dev_put(host_pci_dev);
227 	pci_dev_put(dev);
228 }
229 
230 /*
231  * sn_pci_fixup_slot()
232  */
sn_pci_fixup_slot(struct pci_dev * dev,struct pcidev_info * pcidev_info,struct sn_irq_info * sn_irq_info)233 void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
234 		       struct sn_irq_info *sn_irq_info)
235 {
236 	int segment = pci_domain_nr(dev->bus);
237 	struct pcibus_bussoft *bs;
238 	struct pci_bus *host_pci_bus;
239 	struct pci_dev *host_pci_dev;
240 	unsigned int bus_no, devfn;
241 
242 	pci_dev_get(dev); /* for the sysdata pointer */
243 
244 	/* Add pcidev_info to list in pci_controller.platform_data */
245 	list_add_tail(&pcidev_info->pdi_list,
246 		      &(SN_PLATFORM_DATA(dev->bus)->pcidev_info));
247 	/*
248 	 * Using the PROMs values for the PCI host bus, get the Linux
249 	 * PCI host_pci_dev struct and set up host bus linkages
250  	 */
251 
252 	bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
253 	devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
254  	host_pci_bus = pci_find_bus(segment, bus_no);
255  	host_pci_dev = pci_get_slot(host_pci_bus, devfn);
256 
257 	pcidev_info->host_pci_dev = host_pci_dev;
258 	pcidev_info->pdi_linux_pcidev = dev;
259 	pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev);
260 	bs = SN_PCIBUS_BUSSOFT(dev->bus);
261 	pcidev_info->pdi_pcibus_info = bs;
262 
263 	if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
264 		SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
265 	} else {
266 		SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider;
267 	}
268 
269 	/* Only set up IRQ stuff if this device has a host bus context */
270 	if (bs && sn_irq_info->irq_irq) {
271 		pcidev_info->pdi_sn_irq_info = sn_irq_info;
272 		dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq;
273 		sn_irq_fixup(dev, sn_irq_info);
274 	} else {
275 		pcidev_info->pdi_sn_irq_info = NULL;
276 		kfree(sn_irq_info);
277 	}
278 }
279 
280 /*
281  * sn_common_bus_fixup - Perform platform specific bus fixup.
282  *			 Execute the ASIC specific fixup routine
283  *			 for this bus.
284  */
285 void
sn_common_bus_fixup(struct pci_bus * bus,struct pcibus_bussoft * prom_bussoft_ptr)286 sn_common_bus_fixup(struct pci_bus *bus,
287 		    struct pcibus_bussoft *prom_bussoft_ptr)
288 {
289 	int cnode;
290 	struct pci_controller *controller;
291 	struct hubdev_info *hubdev_info;
292 	int nasid;
293 	void *provider_soft;
294 	struct sn_pcibus_provider *provider;
295 	struct sn_platform_data *sn_platform_data;
296 
297 	controller = PCI_CONTROLLER(bus);
298 	/*
299 	 * Per-provider fixup.  Copies the bus soft structure from prom
300 	 * to local area and links SN_PCIBUS_BUSSOFT().
301 	 */
302 
303 	if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
304 		printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d",
305 		       prom_bussoft_ptr->bs_asic_type);
306 		return;
307 	}
308 
309 	if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB)
310 		return;	/* no further fixup necessary */
311 
312 	provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
313 	if (provider == NULL)
314 		panic("sn_common_bus_fixup: No provider registered for this asic type, %d",
315 		      prom_bussoft_ptr->bs_asic_type);
316 
317 	if (provider->bus_fixup)
318 		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr,
319 				 controller);
320 	else
321 		provider_soft = NULL;
322 
323 	/*
324 	 * Generic bus fixup goes here.  Don't reference prom_bussoft_ptr
325 	 * after this point.
326 	 */
327 	controller->platform_data = kzalloc(sizeof(struct sn_platform_data),
328 					    GFP_KERNEL);
329 	if (controller->platform_data == NULL)
330 		BUG();
331 	sn_platform_data =
332 			(struct sn_platform_data *) controller->platform_data;
333 	sn_platform_data->provider_soft = provider_soft;
334 	INIT_LIST_HEAD(&((struct sn_platform_data *)
335 			 controller->platform_data)->pcidev_info);
336 	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
337 	cnode = nasid_to_cnodeid(nasid);
338 	hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
339 	SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
340 	    &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);
341 
342 	/*
343 	 * If the node information we obtained during the fixup phase is
344 	 * invalid then set controller->node to -1 (undetermined)
345 	 */
346 	if (controller->node >= num_online_nodes()) {
347 		struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
348 
349 		printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u "
350 		       "L_IO=%lx L_MEM=%lx BASE=%lx\n",
351 		       b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
352 		       b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
353 		printk(KERN_WARNING "on node %d but only %d nodes online."
354 		       "Association set to undetermined.\n",
355 		       controller->node, num_online_nodes());
356 		controller->node = -1;
357 	}
358 }
359 
sn_bus_store_sysdata(struct pci_dev * dev)360 void sn_bus_store_sysdata(struct pci_dev *dev)
361 {
362 	struct sysdata_el *element;
363 
364 	element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
365 	if (!element) {
366 		dev_dbg(&dev->dev, "%s: out of memory!\n", __func__);
367 		return;
368 	}
369 	element->sysdata = SN_PCIDEV_INFO(dev);
370 	list_add(&element->entry, &sn_sysdata_list);
371 }
372 
sn_bus_free_sysdata(void)373 void sn_bus_free_sysdata(void)
374 {
375 	struct sysdata_el *element;
376 	struct list_head *list, *safe;
377 
378 	list_for_each_safe(list, safe, &sn_sysdata_list) {
379 		element = list_entry(list, struct sysdata_el, entry);
380 		list_del(&element->entry);
381 		list_del(&(((struct pcidev_info *)
382 			     (element->sysdata))->pdi_list));
383 		kfree(element->sysdata);
384 		kfree(element);
385 	}
386 	return;
387 }
388 
389 /*
390  * hubdev_init_node() - Creates the HUB data structure and link them to it's
391  *			own NODE specific data area.
392  */
hubdev_init_node(nodepda_t * npda,cnodeid_t node)393 void __init hubdev_init_node(nodepda_t * npda, cnodeid_t node)
394 {
395 	struct hubdev_info *hubdev_info;
396 	int size;
397 	pg_data_t *pg;
398 
399 	size = sizeof(struct hubdev_info);
400 
401 	if (node >= num_online_nodes())	/* Headless/memless IO nodes */
402 		pg = NODE_DATA(0);
403 	else
404 		pg = NODE_DATA(node);
405 
406 	hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size);
407 
408 	npda->pdinfo = (void *)hubdev_info;
409 }
410 
411 geoid_t
cnodeid_get_geoid(cnodeid_t cnode)412 cnodeid_get_geoid(cnodeid_t cnode)
413 {
414 	struct hubdev_info *hubdev;
415 
416 	hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
417 	return hubdev->hdi_geoid;
418 }
419 
sn_generate_path(struct pci_bus * pci_bus,char * address)420 void sn_generate_path(struct pci_bus *pci_bus, char *address)
421 {
422 	nasid_t nasid;
423 	cnodeid_t cnode;
424 	geoid_t geoid;
425 	moduleid_t moduleid;
426 	u16 bricktype;
427 
428 	nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
429 	cnode = nasid_to_cnodeid(nasid);
430 	geoid = cnodeid_get_geoid(cnode);
431 	moduleid = geo_module(geoid);
432 
433 	sprintf(address, "module_%c%c%c%c%.2d",
434 		'0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)),
435 		'0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)),
436 		'0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)),
437 		MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid));
438 
439 	/* Tollhouse requires slot id to be displayed */
440 	bricktype = MODULE_GET_BTYPE(moduleid);
441 	if ((bricktype == L1_BRICKTYPE_191010) ||
442 	    (bricktype == L1_BRICKTYPE_1932))
443 			sprintf(address, "%s^%d", address, geo_slot(geoid));
444 }
445 
446 void __devinit
sn_pci_fixup_bus(struct pci_bus * bus)447 sn_pci_fixup_bus(struct pci_bus *bus)
448 {
449 
450 	if (SN_ACPI_BASE_SUPPORT())
451 		sn_acpi_bus_fixup(bus);
452 	else
453 		sn_bus_fixup(bus);
454 }
455 
456 /*
457  * sn_io_early_init - Perform early IO (and some non-IO) initialization.
458  *		      In particular, setup the sn_pci_provider[] array.
459  *		      This needs to be done prior to any bus scanning
460  *		      (acpi_scan_init()) in the ACPI case, as the SN
461  *		      bus fixup code will reference the array.
462  */
463 static int __init
sn_io_early_init(void)464 sn_io_early_init(void)
465 {
466 	int i;
467 
468 	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
469 		return 0;
470 
471 	/* we set the acpi revision to that of the DSDT table OEM rev. */
472 	{
473 		struct acpi_table_header *header = NULL;
474 
475 		acpi_get_table(ACPI_SIG_DSDT, 1, &header);
476 		BUG_ON(header == NULL);
477 		sn_acpi_rev = header->oem_revision;
478 	}
479 
480 	/*
481 	 * prime sn_pci_provider[].  Individual provider init routines will
482 	 * override their respective default entries.
483 	 */
484 
485 	for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++)
486 		sn_pci_provider[i] = &sn_pci_default_provider;
487 
488 	pcibr_init_provider();
489 	tioca_init_provider();
490 	tioce_init_provider();
491 
492 	/*
493 	 * This is needed to avoid bounce limit checks in the blk layer
494 	 */
495 	ia64_max_iommu_merge_mask = ~PAGE_MASK;
496 
497 	sn_irq_lh_init();
498 	INIT_LIST_HEAD(&sn_sysdata_list);
499 	sn_init_cpei_timer();
500 
501 #ifdef CONFIG_PROC_FS
502 	register_sn_procfs();
503 #endif
504 
505 	{
506 		struct acpi_table_header *header;
507 		(void)acpi_get_table(ACPI_SIG_DSDT, 1, &header);
508 		printk(KERN_INFO "ACPI  DSDT OEM Rev 0x%x\n",
509 			header->oem_revision);
510 	}
511 	if (SN_ACPI_BASE_SUPPORT())
512 		sn_io_acpi_init();
513 	else
514 		sn_io_init();
515 	return 0;
516 }
517 
518 arch_initcall(sn_io_early_init);
519 
520 /*
521  * sn_io_late_init() - Perform any final platform specific IO initialization.
522  */
523 
524 int __init
sn_io_late_init(void)525 sn_io_late_init(void)
526 {
527 	struct pci_bus *bus;
528 	struct pcibus_bussoft *bussoft;
529 	cnodeid_t cnode;
530 	nasid_t nasid;
531 	cnodeid_t near_cnode;
532 
533 	if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
534 		return 0;
535 
536 	/*
537 	 * Setup closest node in pci_controller->node for
538 	 * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using
539 	 * info from the PROM).
540 	 */
541 	bus = NULL;
542 	while ((bus = pci_find_next_bus(bus)) != NULL) {
543 		bussoft = SN_PCIBUS_BUSSOFT(bus);
544 		nasid = NASID_GET(bussoft->bs_base);
545 		cnode = nasid_to_cnodeid(nasid);
546 		if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) ||
547 		    (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE) ||
548 		    (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC)) {
549 			/* PCI Bridge: find nearest node with CPUs */
550 			int e = sn_hwperf_get_nearest_node(cnode, NULL,
551 							   &near_cnode);
552 			if (e < 0) {
553 				near_cnode = (cnodeid_t)-1; /* use any node */
554 				printk(KERN_WARNING "sn_io_late_init: failed "
555 				       "to find near node with CPUs for "
556 				       "node %d, err=%d\n", cnode, e);
557 			}
558 			PCI_CONTROLLER(bus)->node = near_cnode;
559 		}
560 	}
561 
562 	sn_ioif_inited = 1;	/* SN I/O infrastructure now initialized */
563 
564 	return 0;
565 }
566 
567 fs_initcall(sn_io_late_init);
568 
569 EXPORT_SYMBOL(sn_pci_unfixup_slot);
570 EXPORT_SYMBOL(sn_bus_store_sysdata);
571 EXPORT_SYMBOL(sn_bus_free_sysdata);
572 EXPORT_SYMBOL(sn_generate_path);
573 
574