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