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) 2001-2003 Silicon Graphics, Inc. All rights reserved.
9 #include <linux/interrupt.h>
10 #include <asm/sn/sn_cpuid.h>
11 #include <asm/sn/iograph.h>
12 #include <asm/sn/hcl_util.h>
13 #include <asm/sn/pci/pciio.h>
14 #include <asm/sn/pci/pcibr.h>
15 #include <asm/sn/pci/pcibr_private.h>
16 #include <asm/sn/pci/pci_defs.h>
17 #include <asm/sn/pci/pic.h>
18 #include <asm/sn/sn_private.h>
20 extern struct file_operations pcibr_fops;
21 extern pcibr_list_p pcibr_list;
23 static int pic_attach2(vertex_hdl_t, void *, vertex_hdl_t,
26 extern int isIO9(nasid_t);
27 extern char *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen);
28 extern int pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
29 extern pcibr_hints_t pcibr_hints_get(vertex_hdl_t, int);
30 extern unsigned pcibr_intr_bits(pciio_info_t info,
31 pciio_intr_line_t lines, int nslots);
32 extern void pcibr_setwidint(xtalk_intr_t);
33 extern int pcibr_error_handler_wrapper(error_handler_arg_t, int,
34 ioerror_mode_t, ioerror_t *);
35 extern void pcibr_error_intr_handler(intr_arg_t);
36 extern void pcibr_directmap_init(pcibr_soft_t);
37 extern int pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t);
38 extern int pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t);
39 extern int pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t);
40 extern int pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t);
41 extern int pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t);
42 extern int pcibr_slot_call_device_attach(vertex_hdl_t,
44 extern void pcibr_rrb_alloc_init(pcibr_soft_t, int, int, int);
45 extern int pcibr_pcix_rbars_calc(pcibr_soft_t);
46 extern pcibr_info_t pcibr_device_info_new(pcibr_soft_t, pciio_slot_t,
47 pciio_function_t, pciio_vendor_id_t,
49 extern int pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t,
51 extern void xwidget_error_register(vertex_hdl_t, error_handler_f *,
53 extern void pcibr_clearwidint(pcibr_soft_t);
58 * copy xwidget_info_t from conn_v to peer_conn_v
61 pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v,
62 cnodeid_t xbow_peer, char *peer_path)
64 xwidget_info_t widget_info, peer_widget_info;
65 vertex_hdl_t peer_hubv;
66 hubinfo_t peer_hub_info;
68 /* get the peer hub's widgetid */
69 peer_hubv = NODEPDA(xbow_peer)->node_vertex;
71 hubinfo_get(peer_hubv, &peer_hub_info);
72 if (peer_hub_info == NULL)
75 if (hwgraph_info_get_LBL(conn_v, INFO_LBL_XWIDGET,
76 (arbitrary_info_t *)&widget_info) == GRAPH_SUCCESS) {
77 peer_widget_info = kmalloc(sizeof (*(peer_widget_info)), GFP_KERNEL);
78 if ( !peer_widget_info ) {
81 memset(peer_widget_info, 0, sizeof (*(peer_widget_info)));
83 peer_widget_info->w_fingerprint = widget_info_fingerprint;
84 peer_widget_info->w_vertex = peer_conn_v;
85 peer_widget_info->w_id = widget_info->w_id;
86 peer_widget_info->w_master = peer_hubv;
87 peer_widget_info->w_masterid = peer_hub_info->h_widgetid;
89 peer_widget_info->w_hwid = widget_info->w_hwid;
90 peer_widget_info->w_efunc = 0;
91 peer_widget_info->w_einfo = 0;
92 peer_widget_info->w_name = kmalloc(strlen(peer_path) + 1, GFP_KERNEL);
93 if (!peer_widget_info->w_name) {
94 kfree(peer_widget_info);
97 strcpy(peer_widget_info->w_name, peer_path);
99 if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_XWIDGET,
100 (arbitrary_info_t)peer_widget_info) != GRAPH_SUCCESS) {
101 kfree(peer_widget_info->w_name);
102 kfree(peer_widget_info);
106 xwidget_info_set(peer_conn_v, peer_widget_info);
111 printk("pic_bus1_widget_info_dup: "
112 "cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v);
117 * If this PIC is attached to two Cbricks ("dual-ported") then
118 * attach each bus to opposite Cbricks.
120 * If successful, return a new vertex suitable for attaching the PIC bus.
121 * If not successful, return zero and both buses will attach to the
122 * vertex passed into pic_attach().
125 pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v)
127 cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
128 cnodeid_t xbow_peer = -1;
129 char pathname[256], peer_path[256], tmpbuf[256];
132 vertex_hdl_t peer_conn_v, hubv;
136 if (NODEPDA(cnode)->xbow_peer >= 0) { /* if dual-ported */
137 /* create a path for this widget on the peer Cbrick */
138 /* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */
139 /* sprintf(pathname, "%v", conn_v); */
140 xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer);
141 pos = hwgfs_generate_path(conn_v, tmpbuf, 256);
142 strcpy(pathname, &tmpbuf[pos]);
143 p = pathname + strlen("hw/module/001c01/slab/0/");
145 memset(tmpbuf, 0, 16);
146 format_module_id(tmpbuf, geo_module((NODEPDA(xbow_peer))->geoid), MODULE_FORMAT_BRIEF);
147 slab = geo_slab((NODEPDA(xbow_peer))->geoid);
148 sprintf(peer_path, "module/%s/slab/%d/%s", tmpbuf, (int)slab, p);
150 /* Look for vertex for this widget on the peer Cbrick.
151 * Expect GRAPH_NOT_FOUND.
153 rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v);
154 if (GRAPH_SUCCESS == rc)
155 printk("pic_attach: found unexpected vertex: 0x%lx\n",
156 (uint64_t)peer_conn_v);
157 else if (GRAPH_NOT_FOUND != rc) {
158 printk("pic_attach: hwgraph_traverse unexpectedly"
159 " returned 0x%x\n", rc);
161 /* try to add the widget vertex to the peer Cbrick */
162 rc = hwgraph_path_add(hwgraph_root, peer_path, &peer_conn_v);
164 if (GRAPH_SUCCESS != rc)
165 printk("pic_attach: hwgraph_path_add"
166 " failed with 0x%x\n", rc);
168 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
169 "pic_bus1_redist: added vertex %v\n", peer_conn_v));
171 /* Now hang appropiate stuff off of the new
172 * vertex. We bail out if we cannot add something.
173 * In that case, we don't remove the newly added
174 * vertex but that should be safe and we don't
175 * really expect the additions to fail anyway.
177 if (!pic_bus1_widget_info_dup(conn_v, peer_conn_v,
178 xbow_peer, peer_path))
181 hubv = cnodeid_to_vertex(xbow_peer);
182 ASSERT(hubv != GRAPH_VERTEX_NONE);
183 device_master_set(peer_conn_v, hubv);
184 xtalk_provider_register(hubv, &hub_provider);
185 xtalk_provider_startup(hubv);
194 * PIC has two buses under a single widget. pic_attach() calls pic_attach2()
195 * to attach each of those buses.
198 pic_attach(vertex_hdl_t conn_v)
201 void *bridge0, *bridge1 = (void *)0;
202 vertex_hdl_t pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
203 pcibr_soft_t bus0_soft, bus1_soft = (pcibr_soft_t)0;
204 vertex_hdl_t conn_v0, conn_v1, peer_conn_v;
206 int iobrick_type_get_nasid(nasid_t nasid);
208 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));
210 bridge0 = pcibr_bridge_ptr_get(conn_v, 0);
211 bridge1 = pcibr_bridge_ptr_get(conn_v, 1);
213 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
214 "pic_attach: bridge0=0x%lx, bridge1=0x%lx\n",
217 conn_v0 = conn_v1 = conn_v;
219 /* If dual-ported then split the two PIC buses across both Cbricks */
220 peer_conn_v = pic_bus1_redist(NASID_GET(bridge0), conn_v);
222 conn_v1 = peer_conn_v;
225 * Create the vertex for the PCI buses, which we
226 * will also use to hold the pcibr_soft and
227 * which will be the "master" vertex for all the
228 * pciio connection points we will hang off it.
229 * This needs to happen before we call nic_bridge_vertex_info
230 * as we are some of the *_vmc functions need access to the edges.
232 * Opening this vertex will provide access to
233 * the Bridge registers themselves.
235 bricktype = iobrick_type_get_nasid(NASID_GET(bridge0));
236 if ( bricktype == MODULE_CGBRICK ) {
237 rc = hwgraph_path_add(conn_v0, EDGE_LBL_AGP_0, &pcibr_vhdl0);
238 ASSERT(rc == GRAPH_SUCCESS);
239 rc = hwgraph_path_add(conn_v1, EDGE_LBL_AGP_1, &pcibr_vhdl1);
240 ASSERT(rc == GRAPH_SUCCESS);
242 rc = hwgraph_path_add(conn_v0, EDGE_LBL_PCIX_0, &pcibr_vhdl0);
243 ASSERT(rc == GRAPH_SUCCESS);
244 rc = hwgraph_path_add(conn_v1, EDGE_LBL_PCIX_1, &pcibr_vhdl1);
245 ASSERT(rc == GRAPH_SUCCESS);
248 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
249 "pic_attach: pcibr_vhdl0=0x%lx, pcibr_vhdl1=0x%lx\n",
250 pcibr_vhdl0, pcibr_vhdl1));
252 /* register pci provider array */
253 pciio_provider_register(pcibr_vhdl0, &pci_pic_provider);
254 pciio_provider_register(pcibr_vhdl1, &pci_pic_provider);
256 pciio_provider_startup(pcibr_vhdl0);
257 pciio_provider_startup(pcibr_vhdl1);
259 pic_attach2(conn_v0, bridge0, pcibr_vhdl0, 0, &bus0_soft);
260 pic_attach2(conn_v1, bridge1, pcibr_vhdl1, 1, &bus1_soft);
263 /* If we're dual-ported finish duplicating the peer info structure.
264 * The error handler and arg are done in pic_attach2().
266 xwidget_info_t info0, info1;
267 if (conn_v0 != conn_v1) { /* dual ported */
268 info0 = xwidget_info_get(conn_v0);
269 info1 = xwidget_info_get(conn_v1);
270 if (info1->w_efunc == (error_handler_f *)NULL)
271 info1->w_efunc = info0->w_efunc;
272 if (info1->w_einfo == (error_handler_arg_t)0)
273 info1->w_einfo = bus1_soft;
277 /* save a pointer to the PIC's other bus's soft struct */
278 bus0_soft->bs_peers_soft = bus1_soft;
279 bus1_soft->bs_peers_soft = bus0_soft;
281 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
282 "pic_attach: bus0_soft=0x%lx, bus1_soft=0x%lx\n",
283 bus0_soft, bus1_soft));
290 * PIC has two buses under a single widget. pic_attach() calls pic_attach2()
291 * to attach each of those buses.
294 pic_attach2(vertex_hdl_t xconn_vhdl, void *bridge,
295 vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
297 vertex_hdl_t ctlr_vhdl;
298 pcibr_soft_t pcibr_soft;
299 pcibr_info_t pcibr_info;
301 xtalk_intr_t xtalk_intr;
303 int entry, slot, ibit, i;
304 vertex_hdl_t noslot_conn;
305 char devnm[MAXDEVNAME], *s;
306 pcibr_hints_t pcibr_hints;
309 picreg_t pic_ctrl_reg;
311 int iobrick_type_get_nasid(nasid_t nasid);
312 int iomoduleid_get(nasid_t nasid);
316 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
317 "pic_attach2: bridge=0x%lx, busnum=%d\n", bridge, busnum));
320 ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0,
322 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
323 (struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl);
324 ASSERT(ctlr_vhdl != NULL);
326 id = pcireg_bridge_id_get(bridge);
327 hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV,
328 (arbitrary_info_t)XWIDGET_PART_REV_NUM(id));
331 * Get the hint structure; if some NIC callback marked this vertex as
332 * "hands-off" then we just return here, before doing anything else.
334 pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
336 if (pcibr_hints && pcibr_hints->ph_hands_off)
339 /* allocate soft structure to hang off the vertex. Link the new soft
340 * structure to the pcibr_list linked list
342 pcibr_soft = kmalloc(sizeof (*(pcibr_soft)), GFP_KERNEL);
346 self = kmalloc(sizeof (*(self)), GFP_KERNEL);
351 memset(pcibr_soft, 0, sizeof (*(pcibr_soft)));
352 memset(self, 0, sizeof (*(self)));
354 self->bl_soft = pcibr_soft;
355 self->bl_vhdl = pcibr_vhdl;
356 self->bl_next = pcibr_list;
360 *ret_softp = pcibr_soft;
362 memset(pcibr_soft, 0, sizeof *pcibr_soft);
363 pcibr_soft_set(pcibr_vhdl, pcibr_soft);
365 s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
366 pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
367 if (!pcibr_soft->bs_name)
370 strcpy(pcibr_soft->bs_name, s);
372 pcibr_soft->bs_conn = xconn_vhdl;
373 pcibr_soft->bs_vhdl = pcibr_vhdl;
374 pcibr_soft->bs_base = (void *)bridge;
375 pcibr_soft->bs_rev_num = XWIDGET_PART_REV_NUM(id);
376 pcibr_soft->bs_intr_bits = (pcibr_intr_bits_f *)pcibr_intr_bits;
377 pcibr_soft->bsi_err_intr = 0;
378 pcibr_soft->bs_min_slot = 0;
379 pcibr_soft->bs_max_slot = 3;
380 pcibr_soft->bs_busnum = busnum;
381 pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
382 pcibr_soft->bs_int_ate_size = PIC_INTERNAL_ATES;
383 /* Make sure this is called after setting the bs_base and bs_bridge_type */
384 pcibr_soft->bs_bridge_mode = (pcireg_speed_get(pcibr_soft) << 1) |
385 pcireg_mode_get(pcibr_soft);
387 info = xwidget_info_get(xconn_vhdl);
388 pcibr_soft->bs_xid = xwidget_info_id_get(info);
389 pcibr_soft->bs_master = xwidget_info_master_get(info);
390 pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
392 strcpy(pcibr_soft->bs_asic_name, "PIC");
394 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
395 "pic_attach2: pcibr_soft=0x%lx, mode=0x%x\n",
396 pcibr_soft, pcibr_soft->bs_bridge_mode));
398 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
399 "pic_attach2: %s ASIC: rev %s (code=0x%x)\n",
400 pcibr_soft->bs_asic_name,
401 (IS_PIC_PART_REV_A(pcibr_soft->bs_rev_num)) ? "A" :
402 (IS_PIC_PART_REV_B(pcibr_soft->bs_rev_num)) ? "B" :
403 (IS_PIC_PART_REV_C(pcibr_soft->bs_rev_num)) ? "C" :
404 "unknown", pcibr_soft->bs_rev_num));
406 /* PV854845: Must clear write request buffer to avoid parity errors */
407 for (i=0; i < PIC_WR_REQ_BUFSIZE; i++) {
408 ((pic_t *)bridge)->p_wr_req_lower[i] = 0;
409 ((pic_t *)bridge)->p_wr_req_upper[i] = 0;
410 ((pic_t *)bridge)->p_wr_req_parity[i] = 0;
413 pcibr_soft->bs_nasid = NASID_GET(bridge);
415 pcibr_soft->bs_bricktype = iobrick_type_get_nasid(pcibr_soft->bs_nasid);
416 if (pcibr_soft->bs_bricktype < 0)
417 printk(KERN_WARNING "%s: bricktype was unknown by L1 (ret val = 0x%x)\n",
418 pcibr_soft->bs_name, pcibr_soft->bs_bricktype);
420 pcibr_soft->bs_moduleid = iomoduleid_get(pcibr_soft->bs_nasid);
422 if (pcibr_soft->bs_bricktype > 0) {
423 switch (pcibr_soft->bs_bricktype) {
426 case MODULE_OPUSBRICK:
427 pcibr_soft->bs_first_slot = 0;
428 pcibr_soft->bs_last_slot = 1;
429 pcibr_soft->bs_last_reset = 1;
431 /* Bus 1 of IXBrick has a IO9, so there are 4 devices, not 2 */
432 if ((pcibr_widget_to_bus(pcibr_vhdl) == 1)
433 && isIO9(pcibr_soft->bs_nasid)) {
434 pcibr_soft->bs_last_slot = 3;
435 pcibr_soft->bs_last_reset = 3;
440 pcibr_soft->bs_first_slot = 0;
441 pcibr_soft->bs_last_slot = 0;
442 pcibr_soft->bs_last_reset = 0;
446 printk(KERN_WARNING "%s: Unknown bricktype: 0x%x\n",
447 pcibr_soft->bs_name, pcibr_soft->bs_bricktype);
451 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
452 "pic_attach2: bricktype=%d, brickbus=%d, "
453 "slots %d-%d\n", pcibr_soft->bs_bricktype,
454 pcibr_widget_to_bus(pcibr_vhdl),
455 pcibr_soft->bs_first_slot, pcibr_soft->bs_last_slot));
459 * Initialize bridge and bus locks
461 spin_lock_init(&pcibr_soft->bs_lock);
464 * If we have one, process the hints structure.
468 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, pcibr_vhdl,
469 "pic_attach2: pcibr_hints=0x%lx\n", pcibr_hints));
471 rrb_fixed = pcibr_hints->ph_rrb_fixed;
473 pcibr_soft->bs_rrb_fixed = rrb_fixed;
475 if (pcibr_hints->ph_intr_bits)
476 pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
479 for (slot = pcibr_soft->bs_min_slot;
480 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
481 int hslot = pcibr_hints->ph_host_slot[slot] - 1;
484 pcibr_soft->bs_slot[slot].host_slot = slot;
486 pcibr_soft->bs_slot[slot].has_host = 1;
487 pcibr_soft->bs_slot[slot].host_slot = hslot;
493 * Set-up initial values for state fields
495 for (slot = pcibr_soft->bs_min_slot;
496 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
497 pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
498 pcibr_soft->bs_slot[slot].bss_devio.bssd_ref_cnt = 0;
499 pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
500 pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
501 pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN0] = -1;
504 for (ibit = 0; ibit < 8; ++ibit) {
505 pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
506 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
507 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
508 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_ibit = ibit;
509 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
510 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
511 pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
516 * connect up our error handler. PIC has 2 busses (thus resulting in 2
517 * pcibr_soft structs under 1 widget), so only register a xwidget error
518 * handler for PIC's bus0. NOTE: for PIC pcibr_error_handler_wrapper()
519 * is a wrapper routine we register that will call the real error handler
520 * pcibr_error_handler() with the correct pcibr_soft struct.
523 xwidget_error_register(xconn_vhdl,
524 pcibr_error_handler_wrapper, pcibr_soft);
528 * Clear all pending interrupts. Assume all interrupts are from slot 3
529 * until otherise setup.
531 pcireg_intr_reset_set(pcibr_soft, PIC_IRR_ALL_CLR);
532 pcireg_intr_device_set(pcibr_soft, 0x006db6db);
534 /* Setup the mapping register used for direct mapping */
535 pcibr_directmap_init(pcibr_soft);
538 * Initialize the PICs control register.
540 pic_ctrl_reg = pcireg_control_get(pcibr_soft);
542 /* Bridges Requester ID: bus = busnum, dev = 0, func = 0 */
543 pic_ctrl_reg &= ~PIC_CTRL_BUS_NUM_MASK;
544 pic_ctrl_reg |= PIC_CTRL_BUS_NUM(busnum);
545 pic_ctrl_reg &= ~PIC_CTRL_DEV_NUM_MASK;
546 pic_ctrl_reg &= ~PIC_CTRL_FUN_NUM_MASK;
548 pic_ctrl_reg &= ~PIC_CTRL_NO_SNOOP;
549 pic_ctrl_reg &= ~PIC_CTRL_RELAX_ORDER;
551 /* enable parity checking on PICs internal RAM */
552 pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP;
553 pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE;
555 /* PIC BRINGUP WAR (PV# 862253): dont enable write request parity */
556 if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) {
557 pic_ctrl_reg |= PIC_CTRL_PAR_EN_REQ;
560 pic_ctrl_reg |= PIC_CTRL_PAGE_SIZE;
562 pcireg_control_set(pcibr_soft, pic_ctrl_reg);
564 /* Initialize internal mapping entries (ie. the ATEs) */
565 for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
566 pcireg_int_ate_set(pcibr_soft, entry, 0);
568 pcibr_soft->bs_int_ate_resource.start = 0;
569 pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1;
571 /* Setup the PICs error interrupt handler. */
572 xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl);
574 ASSERT(xtalk_intr != NULL);
576 irq = ((hub_intr_t)xtalk_intr)->i_bit;
577 cpu = ((hub_intr_t)xtalk_intr)->i_cpuid;
579 intr_unreserve_level(cpu, irq);
580 ((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR;
581 xtalk_intr->xi_vector = SGI_PCIBR_ERROR;
583 pcibr_soft->bsi_err_intr = xtalk_intr;
586 * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
587 * in order to work around some addressing limitations. In order
588 * for that fire wall to work properly, we need to make sure we
589 * start from a known clean state.
591 pcibr_clearwidint(pcibr_soft);
593 xtalk_intr_connect(xtalk_intr,
594 (intr_func_t) pcibr_error_intr_handler,
595 (intr_arg_t) pcibr_soft,
596 (xtalk_intr_setfunc_t) pcibr_setwidint,
597 (void *) pcibr_soft);
599 request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ,
600 "PCIBR error", (intr_arg_t) pcibr_soft);
602 PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl,
603 "pcibr_setwidint: target_id=0x%lx, int_addr=0x%lx\n",
604 pcireg_intr_dst_target_id_get(pcibr_soft),
605 pcireg_intr_dst_addr_get(pcibr_soft)));
607 /* now we can start handling error interrupts */
608 int_enable = pcireg_intr_enable_get(pcibr_soft);
609 int_enable |= PIC_ISR_ERRORS;
611 /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are
612 * locked out to be freed up sooner (by timing out) so that the
613 * read tnums are never completely used up.
615 if (PCIBR_WAR_ENABLED(PV856864, pcibr_soft)) {
616 int_enable &= ~PIC_ISR_PCIX_REQ_TOUT;
617 int_enable &= ~PIC_ISR_XREAD_REQ_TIMEOUT;
619 pcireg_req_timeout_set(pcibr_soft, 0x750);
622 pcireg_intr_enable_set(pcibr_soft, int_enable);
623 pcireg_intr_mode_set(pcibr_soft, 0); /* dont send 'clear interrupt' pkts */
624 pcireg_tflush_get(pcibr_soft); /* wait until Bridge PIO complete */
627 * PIC BRINGUP WAR (PV# 856866, 859504, 861476, 861478): Don't use
628 * RRB0, RRB8, RRB1, and RRB9. Assign them to DEVICE[2|3]--VCHAN3
629 * so they are not used. This works since there is currently no
630 * API to penable VCHAN3.
632 if (PCIBR_WAR_ENABLED(PV856866, pcibr_soft)) {
633 pcireg_rrb_bit_set(pcibr_soft, 0, 0x000f000f); /* even rrb reg */
634 pcireg_rrb_bit_set(pcibr_soft, 1, 0x000f000f); /* odd rrb reg */
637 /* PIC only supports 64-bit direct mapping in PCI-X mode. Since
638 * all PCI-X devices that initiate memory transactions must be
639 * capable of generating 64-bit addressed, we force 64-bit DMAs.
641 pcibr_soft->bs_dma_flags = 0;
642 if (IS_PCIX(pcibr_soft)) {
643 pcibr_soft->bs_dma_flags |= PCIIO_DMA_A64;
648 iopaddr_t prom_base_addr = pcibr_soft->bs_xid << 24;
649 int prom_base_size = 0x1000000;
651 struct resource *res;
653 /* Allocate resource maps based on bus page size; for I/O and memory
654 * space, free all pages except those in the base area and in the
655 * range set by the PROM.
657 * PROM creates BAR addresses in this format: 0x0ws00000 where w is
658 * the widget number and s is the device register offset for the slot.
661 /* Setup the Bus's PCI IO Root Resource. */
662 pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE;
663 pcibr_soft->bs_io_win_root_resource.end = 0xffffffff;
664 res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);
666 panic("PCIBR:Unable to allocate resource structure\n");
668 /* Block off the range used by PROM. */
669 res->start = prom_base_addr;
670 res->end = prom_base_addr + (prom_base_size - 1);
671 status = request_resource(&pcibr_soft->bs_io_win_root_resource, res);
673 panic("PCIBR:Unable to request_resource()\n");
675 /* Setup the Small Window Root Resource */
676 pcibr_soft->bs_swin_root_resource.start = PAGE_SIZE;
677 pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF;
679 /* Setup the Bus's PCI Memory Root Resource */
680 pcibr_soft->bs_mem_win_root_resource.start = 0x200000;
681 pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff;
682 res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);
684 panic("PCIBR:Unable to allocate resource structure\n");
686 /* Block off the range used by PROM. */
687 res->start = prom_base_addr;
688 res->end = prom_base_addr + (prom_base_size - 1);
689 status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res);
691 panic("PCIBR:Unable to request_resource()\n");
696 /* build "no-slot" connection point */
697 pcibr_info = pcibr_device_info_new(pcibr_soft, PCIIO_SLOT_NONE,
698 PCIIO_FUNC_NONE, PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
699 noslot_conn = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
701 /* Store no slot connection point info for tearing it down during detach. */
702 pcibr_soft->bs_noslot_conn = noslot_conn;
703 pcibr_soft->bs_noslot_info = pcibr_info;
705 for (slot = pcibr_soft->bs_min_slot;
706 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
707 /* Find out what is out there */
708 (void)pcibr_slot_info_init(pcibr_vhdl, slot);
711 for (slot = pcibr_soft->bs_min_slot;
712 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
713 /* Set up the address space for this slot in the PCI land */
714 (void)pcibr_slot_addr_space_init(pcibr_vhdl, slot);
717 for (slot = pcibr_soft->bs_min_slot;
718 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
719 /* Setup the device register */
720 (void)pcibr_slot_device_init(pcibr_vhdl, slot);
723 if (IS_PCIX(pcibr_soft)) {
724 pcibr_soft->bs_pcix_rbar_inuse = 0;
725 pcibr_soft->bs_pcix_rbar_avail = NUM_RBAR;
726 pcibr_soft->bs_pcix_rbar_percent_allowed =
727 pcibr_pcix_rbars_calc(pcibr_soft);
729 for (slot = pcibr_soft->bs_min_slot;
730 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
731 /* Setup the PCI-X Read Buffer Attribute Registers (RBARs) */
732 (void)pcibr_slot_pcix_rbar_init(pcibr_soft, slot);
736 for (slot = pcibr_soft->bs_min_slot;
737 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
738 /* Setup host/guest relations */
739 (void)pcibr_slot_guest_info_init(pcibr_vhdl, slot);
742 /* Handle initial RRB management */
743 pcibr_initial_rrb(pcibr_vhdl,
744 pcibr_soft->bs_first_slot, pcibr_soft->bs_last_slot);
746 /* Before any drivers get called that may want to re-allocate RRB's,
747 * let's get some special cases pre-allocated. Drivers may override
748 * these pre-allocations, but by doing pre-allocations now we're
749 * assured not to step all over what the driver intended.
751 if (pcibr_soft->bs_bricktype > 0) {
752 switch (pcibr_soft->bs_bricktype) {
755 case MODULE_OPUSBRICK:
757 * If IO9 in bus 1, allocate RRBs to all the IO9 devices
759 if ((pcibr_widget_to_bus(pcibr_vhdl) == 1) &&
760 (pcibr_soft->bs_slot[0].bss_vendor_id == 0x10A9) &&
761 (pcibr_soft->bs_slot[0].bss_device_id == 0x100A)) {
762 pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 4);
763 pcibr_rrb_alloc_init(pcibr_soft, 1, VCHAN0, 4);
764 pcibr_rrb_alloc_init(pcibr_soft, 2, VCHAN0, 4);
765 pcibr_rrb_alloc_init(pcibr_soft, 3, VCHAN0, 4);
767 pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 4);
768 pcibr_rrb_alloc_init(pcibr_soft, 1, VCHAN0, 4);
773 pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 8);
779 for (slot = pcibr_soft->bs_min_slot;
780 slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
781 /* Call the device attach */
782 (void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
785 pciio_device_attach(noslot_conn, 0);
792 * pci provider functions
794 * mostly in pcibr.c but if any are needed here then
795 * this might be a way to get them here.
797 pciio_provider_t pci_pic_provider =
801 (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
802 (pciio_piomap_free_f *) pcibr_piomap_free,
803 (pciio_piomap_addr_f *) pcibr_piomap_addr,
804 (pciio_piomap_done_f *) pcibr_piomap_done,
805 (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
806 (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
807 (pciio_piospace_free_f *) pcibr_piospace_free,
809 (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
810 (pciio_dmamap_free_f *) pcibr_dmamap_free,
811 (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
812 (pciio_dmamap_done_f *) pcibr_dmamap_done,
813 (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
814 (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
815 (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
817 (pciio_intr_alloc_f *) pcibr_intr_alloc,
818 (pciio_intr_free_f *) pcibr_intr_free,
819 (pciio_intr_connect_f *) pcibr_intr_connect,
820 (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
821 (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
823 (pciio_provider_startup_f *) pcibr_provider_startup,
824 (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
825 (pciio_reset_f *) pcibr_reset,
826 (pciio_endian_set_f *) pcibr_endian_set,
827 (pciio_config_get_f *) pcibr_config_get,
828 (pciio_config_set_f *) pcibr_config_set,
830 (pciio_error_extract_f *) pcibr_error_extract,
832 (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
833 (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
834 (pciio_device_unregister_f *) pcibr_device_unregister,