File: /usr/src/linux/arch/mips64/sgi-ip27/ip27-setup.c
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 * SGI IP27 specific setup.
7 *
8 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
9 * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
10 */
11 #include <linux/config.h>
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/spinlock.h>
15 #include <linux/sched.h>
16 #include <linux/smp.h>
17 #include <asm/io.h>
18 #include <asm/sn/types.h>
19 #include <asm/sn/sn0/addrs.h>
20 #include <asm/sn/sn0/hubni.h>
21 #include <asm/sn/sn0/hubio.h>
22 #include <asm/sn/klconfig.h>
23 #include <asm/sn/ioc3.h>
24 #include <asm/mipsregs.h>
25 #include <asm/sn/arch.h>
26 #include <asm/sn/sn_private.h>
27 #include <asm/pci/bridge.h>
28 #include <asm/paccess.h>
29 #include <asm/sn/sn0/ip27.h>
30
31 /* Check against user dumbness. */
32 #ifdef CONFIG_VT
33 #error CONFIG_VT not allowed for IP27.
34 #endif
35
36 #undef DEBUG_SETUP
37 #ifdef DEBUG_SETUP
38 #define DBG(x...) printk(x)
39 #else
40 #define DBG(x...)
41 #endif
42
43 unsigned long mips_io_port_base = IO_BASE;
44
45 /*
46 * get_nasid() returns the physical node id number of the caller.
47 */
48 nasid_t
49 get_nasid(void)
50 {
51 return (nasid_t)((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_NODEID_MASK)
52 >> NSRI_NODEID_SHFT);
53 }
54
55 /* Extracted from the IOC3 meta driver. FIXME. */
56 static inline void ioc3_sio_init(void)
57 {
58 struct ioc3 *ioc3;
59 nasid_t nid;
60 long loops;
61
62 nid = get_nasid();
63 ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
64
65 ioc3->sscr_a = 0; /* PIO mode for uarta. */
66 ioc3->sscr_b = 0; /* PIO mode for uartb. */
67 ioc3->sio_iec = ~0;
68 ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT);
69
70 loops=1000000; while(loops--);
71 ioc3->sregs.uarta.iu_fcr = 0;
72 ioc3->sregs.uartb.iu_fcr = 0;
73 loops=1000000; while(loops--);
74 }
75
76 static inline void ioc3_eth_init(void)
77 {
78 struct ioc3 *ioc3;
79 nasid_t nid;
80
81 nid = get_nasid();
82 ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base;
83
84 ioc3->eier = 0;
85 }
86
87 /* Try to catch kernel missconfigurations and give user an indication what
88 option to select. */
89 static void __init verify_mode(void)
90 {
91 int n_mode;
92
93 n_mode = LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_MORENODES_MASK;
94 printk("Machine is in %c mode.\n", n_mode ? 'N' : 'M');
95 #ifdef CONFIG_SGI_SN0_N_MODE
96 if (!n_mode)
97 panic("Kernel compiled for M mode.");
98 #else
99 if (n_mode)
100 panic("Kernel compiled for N mode.");
101 #endif
102 }
103
104 #define XBOW_WIDGET_PART_NUM 0x0
105 #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */
106 #define BASE_XBOW_PORT 8 /* Lowest external port */
107
108 unsigned int bus_to_cpu[256];
109 unsigned long bus_to_baddr[256];
110
111 void __init pcibr_setup(cnodeid_t nid)
112 {
113 int i, start, num;
114 unsigned long masterwid;
115 bridge_t *bridge;
116 volatile u64 hubreg;
117 nasid_t nasid, masternasid;
118 xwidget_part_num_t partnum;
119 widgetreg_t widget_id;
120 static spinlock_t pcibr_setup_lock = SPIN_LOCK_UNLOCKED;
121
122 /*
123 * If the master is doing this for headless node, nothing to do.
124 * This is because currently we require at least one of the hubs
125 * (master hub) connected to the xbow to have at least one enabled
126 * cpu to receive intrs. Else we need an array bus_to_intrnasid[]
127 * that bridge_startup() needs to use to target intrs. All dma is
128 * routed thru the widget of the master hub. The master hub wid
129 * is selectable by WIDGET_A below.
130 */
131 if (nid != get_compact_nodeid())
132 return;
133 /*
134 * find what's on our local node
135 */
136 spin_lock(&pcibr_setup_lock);
137 start = num_bridges; /* Remember where we start from */
138 nasid = COMPACT_TO_NASID_NODEID(nid);
139 hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
140 if (hubreg & IIO_LLP_CSR_IS_UP) {
141 /* link is up */
142 widget_id = *(volatile widgetreg_t *)
143 (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
144 partnum = XWIDGET_PART_NUM(widget_id);
145 printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
146 smp_processor_id(), nasid, partnum);
147 if (partnum == BRIDGE_WIDGET_PART_NUM) {
148 /*
149 * found direct connected bridge so must be Origin200
150 */
151 printk("...is bridge\n");
152 num_bridges = 1;
153 bus_to_wid[0] = 0x8;
154 bus_to_nid[0] = 0;
155 masterwid = 0xa;
156 bus_to_baddr[0] = 0xa100000000000000UL;
157 } else if (partnum == XBOW_WIDGET_PART_NUM) {
158 lboard_t *brd;
159 klxbow_t *xbow_p;
160 /*
161 * found xbow, so may have multiple bridges
162 * need to probe xbow
163 */
164 printk("...is xbow\n");
165
166 if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
167 KLTYPE_MIDPLANE8)) == NULL)
168 printk("argh\n");
169 else
170 printk("brd = 0x%lx\n", (unsigned long) brd);
171 if ((xbow_p = (klxbow_t *)
172 find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
173 printk("argh\n");
174 else {
175 /*
176 * Okay, here's a xbow. Lets arbitrate and find
177 * out if we should initialize it. Set enabled
178 * hub connected at highest or lowest widget as
179 * master.
180 */
181 #ifdef WIDGET_A
182 i = HUB_WIDGET_ID_MAX + 1;
183 do {
184 i--;
185 } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
186 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
187 #else
188 i = HUB_WIDGET_ID_MIN - 1;
189 do {
190 i++;
191 } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
192 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
193 #endif
194 masterwid = i;
195 masternasid = XBOW_PORT_NASID(xbow_p, i);
196 if (nasid == masternasid)
197 for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
198 if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
199 continue;
200 if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
201 widget_id = *(volatile widgetreg_t *)
202 (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
203 partnum = XWIDGET_PART_NUM(widget_id);
204 if (partnum == BRIDGE_WIDGET_PART_NUM) {
205 printk("widget 0x%x is a bridge\n", i);
206 bus_to_wid[num_bridges] = i;
207 bus_to_nid[num_bridges] = nasid;
208 bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56)); /* Barrier set */
209 num_bridges++;
210 }
211 }
212 }
213 }
214 } else if (partnum == XXBOW_WIDGET_PART_NUM) {
215 /*
216 * found xbridge, assume ibrick for now
217 */
218 printk("...is xbridge\n");
219 bus_to_wid[0] = 0xb;
220 bus_to_wid[1] = 0xe;
221 bus_to_wid[2] = 0xf;
222
223 bus_to_nid[0] = 0;
224 bus_to_nid[1] = 0;
225 bus_to_nid[2] = 0;
226
227 bus_to_baddr[0] = 0xa100000000000000UL;
228 bus_to_baddr[1] = 0xa100000000000000UL;
229 bus_to_baddr[2] = 0xa100000000000000UL;
230 masterwid = 0xa;
231 num_bridges = 3;
232 }
233 }
234 num = num_bridges - start;
235 spin_unlock(&pcibr_setup_lock);
236 /*
237 * set bridge registers
238 */
239 for (i = start; i < (start + num); i++) {
240
241 DBG("pcibr_setup: bus= %d bus_to_wid[%2d]= %d bus_to_nid[%2d]= %d\n",
242 i, i, bus_to_wid[i], i, bus_to_nid[i]);
243
244 bus_to_cpu[i] = smp_processor_id();
245 /*
246 * point to this bridge
247 */
248 bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
249 /*
250 * Clear all pending interrupts.
251 */
252 bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
253 /*
254 * Until otherwise set up, assume all interrupts are from slot 0
255 */
256 bridge->b_int_device = (u32) 0x0;
257 /*
258 * swap pio's to pci mem and io space (big windows)
259 */
260 bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
261 bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;
262
263 /*
264 * Hmm... IRIX sets additional bits in the address which
265 * are documented as reserved in the bridge docs.
266 */
267 bridge->b_int_mode = 0x0; /* Don't clear ints */
268 bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
269 bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/
270 bridge->b_dir_map = (masterwid << 20); /* DMA */
271 bridge->b_int_enable = 0;
272
273 bridge->b_wid_tflush; /* wait until Bridge PIO complete */
274 }
275 }
276
277 extern void ip27_setup_console(void);
278
279 void __init ip27_setup(void)
280 {
281 nasid_t nid;
282 hubreg_t p, e;
283
284 ip27_setup_console();
285
286 num_bridges = 0;
287 /*
288 * hub_rtc init and cpu clock intr enabled for later calibrate_delay.
289 */
290 DBG("ip27_setup(): Entered.\n");
291 nid = get_nasid();
292 printk("IP27: Running on node %d.\n", nid);
293
294 p = LOCAL_HUB_L(PI_CPU_PRESENT_A) & 1;
295 e = LOCAL_HUB_L(PI_CPU_ENABLE_A) & 1;
296 printk("Node %d has %s primary CPU%s.\n", nid,
297 p ? "a" : "no",
298 e ? ", CPU is running" : "");
299
300 p = LOCAL_HUB_L(PI_CPU_PRESENT_B) & 1;
301 e = LOCAL_HUB_L(PI_CPU_ENABLE_B) & 1;
302 printk("Node %d has %s secondary CPU%s.\n", nid,
303 p ? "a" : "no",
304 e ? ", CPU is running" : "");
305
306 verify_mode();
307 ioc3_sio_init();
308 ioc3_eth_init();
309 per_cpu_init();
310 }
311