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
6 * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
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>
30 extern void sn_init_cpei_timer(void);
31 extern void register_sn_procfs(void);
32 extern void sn_acpi_bus_fixup(struct pci_bus
*);
33 extern void sn_bus_fixup(struct pci_bus
*);
34 extern void sn_acpi_slot_fixup(struct pci_dev
*, struct pcidev_info
*);
35 extern void sn_more_slot_fixup(struct pci_dev
*, struct pcidev_info
*);
36 extern void sn_legacy_pci_window_fixup(struct pci_controller
*, u64
, u64
);
37 extern void sn_io_acpi_init(void);
38 extern void sn_io_init(void);
41 static struct list_head sn_sysdata_list
;
43 /* sysdata list struct */
45 struct list_head entry
;
49 int sn_ioif_inited
; /* SN I/O infrastructure initialized? */
51 struct sn_pcibus_provider
*sn_pci_provider
[PCIIO_ASIC_MAX_TYPES
]; /* indexed by asic type */
54 * Hooks and struct for unsupported pci providers
58 sn_default_pci_map(struct pci_dev
*pdev
, unsigned long paddr
, size_t size
, int type
)
64 sn_default_pci_unmap(struct pci_dev
*pdev
, dma_addr_t addr
, int direction
)
70 sn_default_pci_bus_fixup(struct pcibus_bussoft
*soft
, struct pci_controller
*controller
)
75 static struct sn_pcibus_provider sn_pci_default_provider
= {
76 .dma_map
= sn_default_pci_map
,
77 .dma_map_consistent
= sn_default_pci_map
,
78 .dma_unmap
= sn_default_pci_unmap
,
79 .bus_fixup
= sn_default_pci_bus_fixup
,
83 * Retrieve the DMA Flush List given nasid, widget, and device.
84 * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
87 sal_get_device_dmaflush_list(u64 nasid
, u64 widget_num
, u64 device_num
,
90 struct ia64_sal_retval ret_stuff
;
94 SAL_CALL_NOLOCK(ret_stuff
,
95 (u64
) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST
,
96 (u64
) nasid
, (u64
) widget_num
,
97 (u64
) device_num
, (u64
) address
, 0, 0, 0);
98 return ret_stuff
.status
;
102 * Retrieve the pci device information given the bus and device|function number.
105 sal_get_pcidev_info(u64 segment
, u64 bus_number
, u64 devfn
, u64 pci_dev
,
108 struct ia64_sal_retval ret_stuff
;
109 ret_stuff
.status
= 0;
112 SAL_CALL_NOLOCK(ret_stuff
,
113 (u64
) SN_SAL_IOIF_GET_PCIDEV_INFO
,
114 (u64
) segment
, (u64
) bus_number
, (u64
) devfn
,
121 * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
124 inline struct pcidev_info
*
125 sn_pcidev_info_get(struct pci_dev
*dev
)
127 struct pcidev_info
*pcidev
;
129 list_for_each_entry(pcidev
,
130 &(SN_PLATFORM_DATA(dev
)->pcidev_info
), pdi_list
) {
131 if (pcidev
->pdi_linux_pcidev
== dev
)
137 /* Older PROM flush WAR
139 * 01/16/06 -- This war will be in place until a new official PROM is released.
140 * Additionally note that the struct sn_flush_device_war also has to be
141 * removed from arch/ia64/sn/include/xtalk/hubdev.h
143 static u8 war_implemented
= 0;
145 static s64
sn_device_fixup_war(u64 nasid
, u64 widget
, int device
,
146 struct sn_flush_device_common
*common
)
148 struct sn_flush_device_war
*war_list
;
149 struct sn_flush_device_war
*dev_entry
;
150 struct ia64_sal_retval isrv
= {0,0,0,0};
152 if (!war_implemented
) {
153 printk(KERN_WARNING
"PROM version < 4.50 -- implementing old "
158 war_list
= kzalloc(DEV_PER_WIDGET
* sizeof(*war_list
), GFP_KERNEL
);
162 SAL_CALL_NOLOCK(isrv
, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST
,
163 nasid
, widget
, __pa(war_list
), 0, 0, 0 ,0);
165 panic("sn_device_fixup_war failed: %s\n",
166 ia64_sal_strerror(isrv
.status
));
168 dev_entry
= war_list
+ device
;
169 memcpy(common
,dev_entry
, sizeof(*common
));
176 * sn_common_hubdev_init() - This routine is called to initialize the HUB data
177 * structure for each node in the system.
180 sn_common_hubdev_init(struct hubdev_info
*hubdev
)
183 struct sn_flush_device_kernel
*sn_flush_device_kernel
;
184 struct sn_flush_device_kernel
*dev_entry
;
186 int widget
, device
, size
;
188 /* Attach the error interrupt handlers */
189 if (hubdev
->hdi_nasid
& 1) /* If TIO */
190 ice_error_init(hubdev
);
192 hub_error_init(hubdev
);
194 for (widget
= 0; widget
<= HUB_WIDGET_ID_MAX
; widget
++)
195 hubdev
->hdi_xwidget_info
[widget
].xwi_hubinfo
= hubdev
;
197 if (!hubdev
->hdi_flush_nasid_list
.widget_p
)
200 size
= (HUB_WIDGET_ID_MAX
+ 1) *
201 sizeof(struct sn_flush_device_kernel
*);
202 hubdev
->hdi_flush_nasid_list
.widget_p
=
203 kzalloc(size
, GFP_KERNEL
);
204 if (!hubdev
->hdi_flush_nasid_list
.widget_p
)
207 for (widget
= 0; widget
<= HUB_WIDGET_ID_MAX
; widget
++) {
208 size
= DEV_PER_WIDGET
*
209 sizeof(struct sn_flush_device_kernel
);
210 sn_flush_device_kernel
= kzalloc(size
, GFP_KERNEL
);
211 if (!sn_flush_device_kernel
)
214 dev_entry
= sn_flush_device_kernel
;
215 for (device
= 0; device
< DEV_PER_WIDGET
;
216 device
++, dev_entry
++) {
217 size
= sizeof(struct sn_flush_device_common
);
218 dev_entry
->common
= kzalloc(size
, GFP_KERNEL
);
219 if (!dev_entry
->common
)
221 if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST
))
222 status
= sal_get_device_dmaflush_list(
223 hubdev
->hdi_nasid
, widget
, device
,
224 (u64
)(dev_entry
->common
));
226 status
= sn_device_fixup_war(hubdev
->hdi_nasid
,
229 if (status
!= SALRET_OK
)
230 panic("SAL call failed: %s\n",
231 ia64_sal_strerror(status
));
233 spin_lock_init(&dev_entry
->sfdl_flush_lock
);
236 if (sn_flush_device_kernel
)
237 hubdev
->hdi_flush_nasid_list
.widget_p
[widget
] =
238 sn_flush_device_kernel
;
242 void sn_pci_unfixup_slot(struct pci_dev
*dev
)
244 struct pci_dev
*host_pci_dev
= SN_PCIDEV_INFO(dev
)->host_pci_dev
;
247 pci_dev_put(host_pci_dev
);
252 * sn_pci_fixup_slot() - This routine sets up a slot's resources consistent
253 * with the Linux PCI abstraction layer. Resources
254 * acquired from our PCI provider include PIO maps
255 * to BAR space and interrupt objects.
257 void sn_pci_fixup_slot(struct pci_dev
*dev
)
259 int segment
= pci_domain_nr(dev
->bus
);
261 struct pcibus_bussoft
*bs
;
262 struct pci_bus
*host_pci_bus
;
263 struct pci_dev
*host_pci_dev
;
264 struct pcidev_info
*pcidev_info
;
265 struct sn_irq_info
*sn_irq_info
;
266 unsigned int bus_no
, devfn
;
268 pci_dev_get(dev
); /* for the sysdata pointer */
269 pcidev_info
= kzalloc(sizeof(struct pcidev_info
), GFP_KERNEL
);
271 BUG(); /* Cannot afford to run out of memory */
273 sn_irq_info
= kzalloc(sizeof(struct sn_irq_info
), GFP_KERNEL
);
275 BUG(); /* Cannot afford to run out of memory */
277 /* Call to retrieve pci device information needed by kernel. */
278 status
= sal_get_pcidev_info((u64
) segment
, (u64
) dev
->bus
->number
,
280 (u64
) __pa(pcidev_info
),
281 (u64
) __pa(sn_irq_info
));
283 BUG(); /* Cannot get platform pci device information */
285 /* Add pcidev_info to list in pci_controller.platform_data */
286 list_add_tail(&pcidev_info
->pdi_list
,
287 &(SN_PLATFORM_DATA(dev
->bus
)->pcidev_info
));
289 if (SN_ACPI_BASE_SUPPORT())
290 sn_acpi_slot_fixup(dev
, pcidev_info
);
292 sn_more_slot_fixup(dev
, pcidev_info
);
294 * Using the PROMs values for the PCI host bus, get the Linux
295 * PCI host_pci_dev struct and set up host bus linkages
298 bus_no
= (pcidev_info
->pdi_slot_host_handle
>> 32) & 0xff;
299 devfn
= pcidev_info
->pdi_slot_host_handle
& 0xffffffff;
300 host_pci_bus
= pci_find_bus(segment
, bus_no
);
301 host_pci_dev
= pci_get_slot(host_pci_bus
, devfn
);
303 pcidev_info
->host_pci_dev
= host_pci_dev
;
304 pcidev_info
->pdi_linux_pcidev
= dev
;
305 pcidev_info
->pdi_host_pcidev_info
= SN_PCIDEV_INFO(host_pci_dev
);
306 bs
= SN_PCIBUS_BUSSOFT(dev
->bus
);
307 pcidev_info
->pdi_pcibus_info
= bs
;
309 if (bs
&& bs
->bs_asic_type
< PCIIO_ASIC_MAX_TYPES
) {
310 SN_PCIDEV_BUSPROVIDER(dev
) = sn_pci_provider
[bs
->bs_asic_type
];
312 SN_PCIDEV_BUSPROVIDER(dev
) = &sn_pci_default_provider
;
315 /* Only set up IRQ stuff if this device has a host bus context */
316 if (bs
&& sn_irq_info
->irq_irq
) {
317 pcidev_info
->pdi_sn_irq_info
= sn_irq_info
;
318 dev
->irq
= pcidev_info
->pdi_sn_irq_info
->irq_irq
;
319 sn_irq_fixup(dev
, sn_irq_info
);
321 pcidev_info
->pdi_sn_irq_info
= NULL
;
327 * sn_common_bus_fixup - Perform platform specific bus fixup.
328 * Execute the ASIC specific fixup routine
332 sn_common_bus_fixup(struct pci_bus
*bus
,
333 struct pcibus_bussoft
*prom_bussoft_ptr
)
336 struct pci_controller
*controller
;
337 struct hubdev_info
*hubdev_info
;
340 struct sn_pcibus_provider
*provider
;
341 struct sn_platform_data
*sn_platform_data
;
343 controller
= PCI_CONTROLLER(bus
);
345 * Per-provider fixup. Copies the bus soft structure from prom
346 * to local area and links SN_PCIBUS_BUSSOFT().
349 if (prom_bussoft_ptr
->bs_asic_type
>= PCIIO_ASIC_MAX_TYPES
) {
350 printk(KERN_WARNING
"sn_common_bus_fixup: Unsupported asic type, %d",
351 prom_bussoft_ptr
->bs_asic_type
);
355 if (prom_bussoft_ptr
->bs_asic_type
== PCIIO_ASIC_TYPE_PPB
)
356 return; /* no further fixup necessary */
358 provider
= sn_pci_provider
[prom_bussoft_ptr
->bs_asic_type
];
359 if (provider
== NULL
)
360 panic("sn_common_bus_fixup: No provider registered for this asic type, %d",
361 prom_bussoft_ptr
->bs_asic_type
);
363 if (provider
->bus_fixup
)
364 provider_soft
= (*provider
->bus_fixup
) (prom_bussoft_ptr
,
367 provider_soft
= NULL
;
370 * Generic bus fixup goes here. Don't reference prom_bussoft_ptr
373 controller
->platform_data
= kzalloc(sizeof(struct sn_platform_data
),
375 if (controller
->platform_data
== NULL
)
378 (struct sn_platform_data
*) controller
->platform_data
;
379 sn_platform_data
->provider_soft
= provider_soft
;
380 INIT_LIST_HEAD(&((struct sn_platform_data
*)
381 controller
->platform_data
)->pcidev_info
);
382 nasid
= NASID_GET(SN_PCIBUS_BUSSOFT(bus
)->bs_base
);
383 cnode
= nasid_to_cnodeid(nasid
);
384 hubdev_info
= (struct hubdev_info
*)(NODEPDA(cnode
)->pdinfo
);
385 SN_PCIBUS_BUSSOFT(bus
)->bs_xwidget_info
=
386 &(hubdev_info
->hdi_xwidget_info
[SN_PCIBUS_BUSSOFT(bus
)->bs_xid
]);
389 * If the node information we obtained during the fixup phase is
390 * invalid then set controller->node to -1 (undetermined)
392 if (controller
->node
>= num_online_nodes()) {
393 struct pcibus_bussoft
*b
= SN_PCIBUS_BUSSOFT(bus
);
395 printk(KERN_WARNING
"Device ASIC=%u XID=%u PBUSNUM=%u"
396 "L_IO=%lx L_MEM=%lx BASE=%lx\n",
397 b
->bs_asic_type
, b
->bs_xid
, b
->bs_persist_busnum
,
398 b
->bs_legacy_io
, b
->bs_legacy_mem
, b
->bs_base
);
399 printk(KERN_WARNING
"on node %d but only %d nodes online."
400 "Association set to undetermined.\n",
401 controller
->node
, num_online_nodes());
402 controller
->node
= -1;
406 void sn_bus_store_sysdata(struct pci_dev
*dev
)
408 struct sysdata_el
*element
;
410 element
= kzalloc(sizeof(struct sysdata_el
), GFP_KERNEL
);
412 dev_dbg(dev
, "%s: out of memory!\n", __FUNCTION__
);
415 element
->sysdata
= SN_PCIDEV_INFO(dev
);
416 list_add(&element
->entry
, &sn_sysdata_list
);
419 void sn_bus_free_sysdata(void)
421 struct sysdata_el
*element
;
422 struct list_head
*list
, *safe
;
424 list_for_each_safe(list
, safe
, &sn_sysdata_list
) {
425 element
= list_entry(list
, struct sysdata_el
, entry
);
426 list_del(&element
->entry
);
427 list_del(&(((struct pcidev_info
*)
428 (element
->sysdata
))->pdi_list
));
429 kfree(element
->sysdata
);
436 * hubdev_init_node() - Creates the HUB data structure and link them to it's
437 * own NODE specific data area.
439 void hubdev_init_node(nodepda_t
* npda
, cnodeid_t node
)
441 struct hubdev_info
*hubdev_info
;
445 size
= sizeof(struct hubdev_info
);
447 if (node
>= num_online_nodes()) /* Headless/memless IO nodes */
450 pg
= NODE_DATA(node
);
452 hubdev_info
= (struct hubdev_info
*)alloc_bootmem_node(pg
, size
);
454 npda
->pdinfo
= (void *)hubdev_info
;
458 cnodeid_get_geoid(cnodeid_t cnode
)
460 struct hubdev_info
*hubdev
;
462 hubdev
= (struct hubdev_info
*)(NODEPDA(cnode
)->pdinfo
);
463 return hubdev
->hdi_geoid
;
466 void sn_generate_path(struct pci_bus
*pci_bus
, char *address
)
474 nasid
= NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus
)->bs_base
);
475 cnode
= nasid_to_cnodeid(nasid
);
476 geoid
= cnodeid_get_geoid(cnode
);
477 moduleid
= geo_module(geoid
);
479 sprintf(address
, "module_%c%c%c%c%.2d",
480 '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid
)),
481 '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid
)),
482 '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid
)),
483 MODULE_GET_BTCHAR(moduleid
), MODULE_GET_BPOS(moduleid
));
485 /* Tollhouse requires slot id to be displayed */
486 bricktype
= MODULE_GET_BTYPE(moduleid
);
487 if ((bricktype
== L1_BRICKTYPE_191010
) ||
488 (bricktype
== L1_BRICKTYPE_1932
))
489 sprintf(address
, "%s^%d", address
, geo_slot(geoid
));
493 * sn_pci_fixup_bus() - Perform SN specific setup of software structs
494 * (pcibus_bussoft, pcidev_info) and hardware
495 * registers, for the specified bus and devices under it.
498 sn_pci_fixup_bus(struct pci_bus
*bus
)
501 if (SN_ACPI_BASE_SUPPORT())
502 sn_acpi_bus_fixup(bus
);
508 * sn_io_early_init - Perform early IO (and some non-IO) initialization.
509 * In particular, setup the sn_pci_provider[] array.
510 * This needs to be done prior to any bus scanning
511 * (acpi_scan_init()) in the ACPI case, as the SN
512 * bus fixup code will reference the array.
515 sn_io_early_init(void)
519 if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
523 * prime sn_pci_provider[]. Individial provider init routines will
524 * override their respective default entries.
527 for (i
= 0; i
< PCIIO_ASIC_MAX_TYPES
; i
++)
528 sn_pci_provider
[i
] = &sn_pci_default_provider
;
530 pcibr_init_provider();
531 tioca_init_provider();
532 tioce_init_provider();
535 * This is needed to avoid bounce limit checks in the blk layer
537 ia64_max_iommu_merge_mask
= ~PAGE_MASK
;
540 INIT_LIST_HEAD(&sn_sysdata_list
);
541 sn_init_cpei_timer();
543 #ifdef CONFIG_PROC_FS
544 register_sn_procfs();
547 printk(KERN_INFO
"ACPI DSDT OEM Rev 0x%x\n",
548 acpi_gbl_DSDT
->oem_revision
);
549 if (SN_ACPI_BASE_SUPPORT())
556 arch_initcall(sn_io_early_init
);
559 * sn_io_late_init() - Perform any final platform specific IO initialization.
563 sn_io_late_init(void)
566 struct pcibus_bussoft
*bussoft
;
569 cnodeid_t near_cnode
;
571 if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
575 * Setup closest node in pci_controller->node for
576 * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using
577 * info from the PROM).
580 while ((bus
= pci_find_next_bus(bus
)) != NULL
) {
581 bussoft
= SN_PCIBUS_BUSSOFT(bus
);
582 nasid
= NASID_GET(bussoft
->bs_base
);
583 cnode
= nasid_to_cnodeid(nasid
);
584 if ((bussoft
->bs_asic_type
== PCIIO_ASIC_TYPE_TIOCP
) ||
585 (bussoft
->bs_asic_type
== PCIIO_ASIC_TYPE_TIOCE
)) {
586 /* TIO PCI Bridge: find nearest node with CPUs */
587 int e
= sn_hwperf_get_nearest_node(cnode
, NULL
,
590 near_cnode
= (cnodeid_t
)-1; /* use any node */
591 printk(KERN_WARNING
"pcibr_bus_fixup: failed "
592 "to find near node with CPUs to TIO "
593 "node %d, err=%d\n", cnode
, e
);
595 PCI_CONTROLLER(bus
)->node
= near_cnode
;
596 } else if (bussoft
->bs_asic_type
== PCIIO_ASIC_TYPE_PIC
) {
597 PCI_CONTROLLER(bus
)->node
= cnode
;
601 sn_ioif_inited
= 1; /* SN I/O infrastructure now initialized */
606 fs_initcall(sn_io_late_init
);
608 EXPORT_SYMBOL(sn_pci_fixup_slot
);
609 EXPORT_SYMBOL(sn_pci_unfixup_slot
);
610 EXPORT_SYMBOL(sn_bus_store_sysdata
);
611 EXPORT_SYMBOL(sn_bus_free_sysdata
);
612 EXPORT_SYMBOL(sn_generate_path
);