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