Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) | |
3 | * Copyright (C) 1999, 2000 Silcon Graphics, Inc. | |
4 | * Copyright (C) 2004 Christoph Hellwig. | |
5 | * Released under GPL v2. | |
6 | * | |
7 | * Generic XTALK initialization code | |
8 | */ | |
9 | ||
1da177e4 | 10 | #include <linux/kernel.h> |
631330f5 | 11 | #include <linux/smp.h> |
1da177e4 LT |
12 | #include <asm/sn/types.h> |
13 | #include <asm/sn/klconfig.h> | |
14 | #include <asm/sn/hub.h> | |
15 | #include <asm/pci/bridge.h> | |
16 | #include <asm/xtalk/xtalk.h> | |
17 | ||
18 | ||
70342287 RB |
19 | #define XBOW_WIDGET_PART_NUM 0x0 |
20 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */ | |
21 | #define BASE_XBOW_PORT 8 /* Lowest external port */ | |
1da177e4 LT |
22 | |
23 | extern int bridge_probe(nasid_t nasid, int widget, int masterwid); | |
24 | ||
078a55fc | 25 | static int probe_one_port(nasid_t nasid, int widget, int masterwid) |
1da177e4 | 26 | { |
70342287 | 27 | widgetreg_t widget_id; |
1da177e4 LT |
28 | xwidget_part_num_t partnum; |
29 | ||
30 | widget_id = *(volatile widgetreg_t *) | |
31 | (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID); | |
32 | partnum = XWIDGET_PART_NUM(widget_id); | |
33 | ||
34 | printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ", | |
35 | smp_processor_id(), nasid, widget, partnum); | |
36 | ||
37 | switch (partnum) { | |
38 | case BRIDGE_WIDGET_PART_NUM: | |
39 | case XBRIDGE_WIDGET_PART_NUM: | |
40 | bridge_probe(nasid, widget, masterwid); | |
41 | break; | |
42 | default: | |
43 | break; | |
44 | } | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
078a55fc | 49 | static int xbow_probe(nasid_t nasid) |
1da177e4 LT |
50 | { |
51 | lboard_t *brd; | |
52 | klxbow_t *xbow_p; | |
53 | unsigned masterwid, i; | |
54 | ||
55 | printk("is xbow\n"); | |
56 | ||
57 | /* | |
58 | * found xbow, so may have multiple bridges | |
59 | * need to probe xbow | |
60 | */ | |
61 | brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8); | |
62 | if (!brd) | |
63 | return -ENODEV; | |
64 | ||
65 | xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW); | |
66 | if (!xbow_p) | |
67 | return -ENODEV; | |
68 | ||
69 | /* | |
70 | * Okay, here's a xbow. Lets arbitrate and find | |
71 | * out if we should initialize it. Set enabled | |
72 | * hub connected at highest or lowest widget as | |
73 | * master. | |
74 | */ | |
75 | #ifdef WIDGET_A | |
76 | i = HUB_WIDGET_ID_MAX + 1; | |
77 | do { | |
78 | i--; | |
79 | } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || | |
80 | (!XBOW_PORT_IS_ENABLED(xbow_p, i))); | |
81 | #else | |
82 | i = HUB_WIDGET_ID_MIN - 1; | |
83 | do { | |
84 | i++; | |
85 | } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) || | |
86 | (!XBOW_PORT_IS_ENABLED(xbow_p, i))); | |
87 | #endif | |
88 | ||
89 | masterwid = i; | |
90 | if (nasid != XBOW_PORT_NASID(xbow_p, i)) | |
91 | return 1; | |
92 | ||
93 | for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) { | |
94 | if (XBOW_PORT_IS_ENABLED(xbow_p, i) && | |
95 | XBOW_PORT_TYPE_IO(xbow_p, i)) | |
96 | probe_one_port(nasid, i, masterwid); | |
97 | } | |
98 | ||
99 | return 0; | |
100 | } | |
101 | ||
078a55fc | 102 | void xtalk_probe_node(cnodeid_t nid) |
1da177e4 | 103 | { |
70342287 RB |
104 | volatile u64 hubreg; |
105 | nasid_t nasid; | |
1da177e4 | 106 | xwidget_part_num_t partnum; |
70342287 | 107 | widgetreg_t widget_id; |
1da177e4 LT |
108 | |
109 | nasid = COMPACT_TO_NASID_NODEID(nid); | |
110 | hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); | |
111 | ||
112 | /* check whether the link is up */ | |
113 | if (!(hubreg & IIO_LLP_CSR_IS_UP)) | |
114 | return; | |
115 | ||
116 | widget_id = *(volatile widgetreg_t *) | |
70342287 | 117 | (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); |
1da177e4 LT |
118 | partnum = XWIDGET_PART_NUM(widget_id); |
119 | ||
120 | printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ", | |
121 | smp_processor_id(), nasid, partnum); | |
122 | ||
123 | switch (partnum) { | |
124 | case BRIDGE_WIDGET_PART_NUM: | |
125 | bridge_probe(nasid, 0x8, 0xa); | |
126 | break; | |
127 | case XBOW_WIDGET_PART_NUM: | |
128 | case XXBOW_WIDGET_PART_NUM: | |
129 | xbow_probe(nasid); | |
130 | break; | |
131 | default: | |
132 | printk(" unknown widget??\n"); | |
133 | break; | |
134 | } | |
135 | } |