xref: /openbmc/linux/arch/sparc/kernel/sun4m_irq.c (revision 384740dc)
1 /*  sun4m_irq.c
2  *  arch/sparc/kernel/sun4m_irq.c:
3  *
4  *  djhr: Hacked out of irq.c into a CPU dependent version.
5  *
6  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
7  *  Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
8  *  Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com)
9  *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
10  */
11 
12 #include <linux/errno.h>
13 #include <linux/linkage.h>
14 #include <linux/kernel_stat.h>
15 #include <linux/signal.h>
16 #include <linux/sched.h>
17 #include <linux/ptrace.h>
18 #include <linux/smp.h>
19 #include <linux/interrupt.h>
20 #include <linux/slab.h>
21 #include <linux/init.h>
22 #include <linux/ioport.h>
23 
24 #include <asm/ptrace.h>
25 #include <asm/processor.h>
26 #include <asm/system.h>
27 #include <asm/psr.h>
28 #include <asm/vaddrs.h>
29 #include <asm/timer.h>
30 #include <asm/openprom.h>
31 #include <asm/oplib.h>
32 #include <asm/traps.h>
33 #include <asm/pgalloc.h>
34 #include <asm/pgtable.h>
35 #include <asm/smp.h>
36 #include <asm/irq.h>
37 #include <asm/io.h>
38 #include <asm/sbus.h>
39 #include <asm/cacheflush.h>
40 
41 #include "irq.h"
42 
43 /* On the sun4m, just like the timers, we have both per-cpu and master
44  * interrupt registers.
45  */
46 
47 /* These registers are used for sending/receiving irqs from/to
48  * different cpu's.
49  */
50 struct sun4m_intreg_percpu {
51 	unsigned int tbt;        /* Interrupts still pending for this cpu. */
52 
53 	/* These next two registers are WRITE-ONLY and are only
54 	 * "on bit" sensitive, "off bits" written have NO affect.
55 	 */
56 	unsigned int clear;  /* Clear this cpus irqs here. */
57 	unsigned int set;    /* Set this cpus irqs here. */
58 	unsigned char space[PAGE_SIZE - 12];
59 };
60 
61 /*
62  * djhr
63  * Actually the clear and set fields in this struct are misleading..
64  * according to the SLAVIO manual (and the same applies for the SEC)
65  * the clear field clears bits in the mask which will ENABLE that IRQ
66  * the set field sets bits in the mask to DISABLE the IRQ.
67  *
68  * Also the undirected_xx address in the SLAVIO is defined as
69  * RESERVED and write only..
70  *
71  * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
72  *             sun4m machines, for MP the layout makes more sense.
73  */
74 struct sun4m_intregs {
75 	struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
76 	unsigned int tbt;                /* IRQ's that are still pending. */
77 	unsigned int irqs;               /* Master IRQ bits. */
78 
79 	/* Again, like the above, two these registers are WRITE-ONLY. */
80 	unsigned int clear;              /* Clear master IRQ's by setting bits here. */
81 	unsigned int set;                /* Set master IRQ's by setting bits here. */
82 
83 	/* This register is both READ and WRITE. */
84 	unsigned int undirected_target;  /* Which cpu gets undirected irqs. */
85 };
86 
87 static unsigned long dummy;
88 
89 struct sun4m_intregs *sun4m_interrupts;
90 unsigned long *irq_rcvreg = &dummy;
91 
92 /* Dave Redman (djhr@tadpole.co.uk)
93  * The sun4m interrupt registers.
94  */
95 #define SUN4M_INT_ENABLE  	0x80000000
96 #define SUN4M_INT_E14     	0x00000080
97 #define SUN4M_INT_E10     	0x00080000
98 
99 #define SUN4M_HARD_INT(x)	(0x000000001 << (x))
100 #define SUN4M_SOFT_INT(x)	(0x000010000 << (x))
101 
102 #define	SUN4M_INT_MASKALL	0x80000000	  /* mask all interrupts */
103 #define	SUN4M_INT_MODULE_ERR	0x40000000	  /* module error */
104 #define	SUN4M_INT_M2S_WRITE	0x20000000	  /* write buffer error */
105 #define	SUN4M_INT_ECC		0x10000000	  /* ecc memory error */
106 #define	SUN4M_INT_FLOPPY	0x00400000	  /* floppy disk */
107 #define	SUN4M_INT_MODULE	0x00200000	  /* module interrupt */
108 #define	SUN4M_INT_VIDEO		0x00100000	  /* onboard video */
109 #define	SUN4M_INT_REALTIME	0x00080000	  /* system timer */
110 #define	SUN4M_INT_SCSI		0x00040000	  /* onboard scsi */
111 #define	SUN4M_INT_AUDIO		0x00020000	  /* audio/isdn */
112 #define	SUN4M_INT_ETHERNET	0x00010000	  /* onboard ethernet */
113 #define	SUN4M_INT_SERIAL	0x00008000	  /* serial ports */
114 #define	SUN4M_INT_KBDMS		0x00004000	  /* keyboard/mouse */
115 #define	SUN4M_INT_SBUSBITS	0x00003F80	  /* sbus int bits */
116 
117 #define SUN4M_INT_SBUS(x)	(1 << (x+7))
118 #define SUN4M_INT_VME(x)	(1 << (x))
119 
120 /* These tables only apply for interrupts greater than 15..
121  *
122  * any intr value below 0x10 is considered to be a soft-int
123  * this may be useful or it may not.. but that's how I've done it.
124  * and it won't clash with what OBP is telling us about devices.
125  *
126  * take an encoded intr value and lookup if it's valid
127  * then get the mask bits that match from irq_mask
128  *
129  * P3: Translation from irq 0x0d to mask 0x2000 is for MrCoffee.
130  */
131 static unsigned char irq_xlate[32] = {
132     /*  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  a,  b,  c,  d,  e,  f */
133 	0,  0,  0,  0,  1,  0,  2,  0,  3,  0,  4,  5,  6, 14,  0,  7,
134 	0,  0,  8,  9,  0, 10,  0, 11,  0, 12,  0, 13,  0, 14,  0,  0
135 };
136 
137 static unsigned long irq_mask[] = {
138 	0,						  /* illegal index */
139 	SUN4M_INT_SCSI,				  	  /*  1 irq 4 */
140 	SUN4M_INT_ETHERNET,				  /*  2 irq 6 */
141 	SUN4M_INT_VIDEO,				  /*  3 irq 8 */
142 	SUN4M_INT_REALTIME,				  /*  4 irq 10 */
143 	SUN4M_INT_FLOPPY,				  /*  5 irq 11 */
144 	(SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),	  	  /*  6 irq 12 */
145 	SUN4M_INT_MODULE_ERR,			  	  /*  7 irq 15 */
146 	SUN4M_INT_SBUS(0),				  /*  8 irq 2 */
147 	SUN4M_INT_SBUS(1),				  /*  9 irq 3 */
148 	SUN4M_INT_SBUS(2),				  /* 10 irq 5 */
149 	SUN4M_INT_SBUS(3),				  /* 11 irq 7 */
150 	SUN4M_INT_SBUS(4),				  /* 12 irq 9 */
151 	SUN4M_INT_SBUS(5),				  /* 13 irq 11 */
152 	SUN4M_INT_SBUS(6)				  /* 14 irq 13 */
153 };
154 
155 static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 };
156 
157 static unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev,
158 				       unsigned int sbint)
159 {
160 	if (sbint >= sizeof(sun4m_pil_map)) {
161 		printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
162 		BUG();
163 	}
164 	return sun4m_pil_map[sbint] | 0x30;
165 }
166 
167 static unsigned long sun4m_get_irqmask(unsigned int irq)
168 {
169 	unsigned long mask;
170 
171 	if (irq > 0x20) {
172 		/* OBIO/SBUS interrupts */
173 		irq &= 0x1f;
174 		mask = irq_mask[irq_xlate[irq]];
175 		if (!mask)
176 			printk("sun4m_get_irqmask: IRQ%d has no valid mask!\n",irq);
177 	} else {
178 		/* Soft Interrupts will come here.
179 		 * Currently there is no way to trigger them but I'm sure
180 		 * something could be cooked up.
181 		 */
182 		irq &= 0xf;
183 		mask = SUN4M_SOFT_INT(irq);
184 	}
185 	return mask;
186 }
187 
188 static void sun4m_disable_irq(unsigned int irq_nr)
189 {
190 	unsigned long mask, flags;
191 	int cpu = smp_processor_id();
192 
193 	mask = sun4m_get_irqmask(irq_nr);
194 	local_irq_save(flags);
195 	if (irq_nr > 15)
196 		sun4m_interrupts->set = mask;
197 	else
198 		sun4m_interrupts->cpu_intregs[cpu].set = mask;
199 	local_irq_restore(flags);
200 }
201 
202 static void sun4m_enable_irq(unsigned int irq_nr)
203 {
204 	unsigned long mask, flags;
205 	int cpu = smp_processor_id();
206 
207 	/* Dreadful floppy hack. When we use 0x2b instead of
208          * 0x0b the system blows (it starts to whistle!).
209          * So we continue to use 0x0b. Fixme ASAP. --P3
210          */
211         if (irq_nr != 0x0b) {
212 		mask = sun4m_get_irqmask(irq_nr);
213 		local_irq_save(flags);
214 		if (irq_nr > 15)
215 			sun4m_interrupts->clear = mask;
216 		else
217 			sun4m_interrupts->cpu_intregs[cpu].clear = mask;
218 		local_irq_restore(flags);
219 	} else {
220 		local_irq_save(flags);
221 		sun4m_interrupts->clear = SUN4M_INT_FLOPPY;
222 		local_irq_restore(flags);
223 	}
224 }
225 
226 static unsigned long cpu_pil_to_imask[16] = {
227 /*0*/	0x00000000,
228 /*1*/	0x00000000,
229 /*2*/	SUN4M_INT_SBUS(0) | SUN4M_INT_VME(0),
230 /*3*/	SUN4M_INT_SBUS(1) | SUN4M_INT_VME(1),
231 /*4*/	SUN4M_INT_SCSI,
232 /*5*/	SUN4M_INT_SBUS(2) | SUN4M_INT_VME(2),
233 /*6*/	SUN4M_INT_ETHERNET,
234 /*7*/	SUN4M_INT_SBUS(3) | SUN4M_INT_VME(3),
235 /*8*/	SUN4M_INT_VIDEO,
236 /*9*/	SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,
237 /*10*/	SUN4M_INT_REALTIME,
238 /*11*/	SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
239 /*12*/	SUN4M_INT_SERIAL | SUN4M_INT_KBDMS,
240 /*13*/	SUN4M_INT_AUDIO,
241 /*14*/	SUN4M_INT_E14,
242 /*15*/	0x00000000
243 };
244 
245 /* We assume the caller has disabled local interrupts when these are called,
246  * or else very bizarre behavior will result.
247  */
248 static void sun4m_disable_pil_irq(unsigned int pil)
249 {
250 	sun4m_interrupts->set = cpu_pil_to_imask[pil];
251 }
252 
253 static void sun4m_enable_pil_irq(unsigned int pil)
254 {
255 	sun4m_interrupts->clear = cpu_pil_to_imask[pil];
256 }
257 
258 #ifdef CONFIG_SMP
259 static void sun4m_send_ipi(int cpu, int level)
260 {
261 	unsigned long mask;
262 
263 	mask = sun4m_get_irqmask(level);
264 	sun4m_interrupts->cpu_intregs[cpu].set = mask;
265 }
266 
267 static void sun4m_clear_ipi(int cpu, int level)
268 {
269 	unsigned long mask;
270 
271 	mask = sun4m_get_irqmask(level);
272 	sun4m_interrupts->cpu_intregs[cpu].clear = mask;
273 }
274 
275 static void sun4m_set_udt(int cpu)
276 {
277 	sun4m_interrupts->undirected_target = cpu;
278 }
279 #endif
280 
281 #define OBIO_INTR	0x20
282 #define TIMER_IRQ  	(OBIO_INTR | 10)
283 #define PROFILE_IRQ	(OBIO_INTR | 14)
284 
285 static struct sun4m_timer_regs *sun4m_timers;
286 unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
287 
288 static void sun4m_clear_clock_irq(void)
289 {
290 	volatile unsigned int clear_intr;
291 	clear_intr = sun4m_timers->l10_timer_limit;
292 }
293 
294 static void sun4m_clear_profile_irq(int cpu)
295 {
296 	volatile unsigned int clear;
297 
298 	clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit;
299 }
300 
301 static void sun4m_load_profile_irq(int cpu, unsigned int limit)
302 {
303 	sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit;
304 }
305 
306 static void __init sun4m_init_timers(irq_handler_t counter_fn)
307 {
308 	int reg_count, irq, cpu;
309 	struct linux_prom_registers cnt_regs[PROMREG_MAX];
310 	int obio_node, cnt_node;
311 	struct resource r;
312 
313 	cnt_node = 0;
314 	if((obio_node =
315 	    prom_searchsiblings (prom_getchild(prom_root_node), "obio")) == 0 ||
316 	   (obio_node = prom_getchild (obio_node)) == 0 ||
317 	   (cnt_node = prom_searchsiblings (obio_node, "counter")) == 0) {
318 		prom_printf("Cannot find /obio/counter node\n");
319 		prom_halt();
320 	}
321 	reg_count = prom_getproperty(cnt_node, "reg",
322 				     (void *) cnt_regs, sizeof(cnt_regs));
323 	reg_count = (reg_count/sizeof(struct linux_prom_registers));
324 
325 	/* Apply the obio ranges to the timer registers. */
326 	prom_apply_obio_ranges(cnt_regs, reg_count);
327 
328 	cnt_regs[4].phys_addr = cnt_regs[reg_count-1].phys_addr;
329 	cnt_regs[4].reg_size = cnt_regs[reg_count-1].reg_size;
330 	cnt_regs[4].which_io = cnt_regs[reg_count-1].which_io;
331 	for(obio_node = 1; obio_node < 4; obio_node++) {
332 		cnt_regs[obio_node].phys_addr =
333 			cnt_regs[obio_node-1].phys_addr + PAGE_SIZE;
334 		cnt_regs[obio_node].reg_size = cnt_regs[obio_node-1].reg_size;
335 		cnt_regs[obio_node].which_io = cnt_regs[obio_node-1].which_io;
336 	}
337 
338 	memset((char*)&r, 0, sizeof(struct resource));
339 	/* Map the per-cpu Counter registers. */
340 	r.flags = cnt_regs[0].which_io;
341 	r.start = cnt_regs[0].phys_addr;
342 	sun4m_timers = (struct sun4m_timer_regs *) sbus_ioremap(&r, 0,
343 	    PAGE_SIZE*SUN4M_NCPUS, "sun4m_cpu_cnt");
344 	/* Map the system Counter register. */
345 	/* XXX Here we expect consequent calls to yeld adjusent maps. */
346 	r.flags = cnt_regs[4].which_io;
347 	r.start = cnt_regs[4].phys_addr;
348 	sbus_ioremap(&r, 0, cnt_regs[4].reg_size, "sun4m_sys_cnt");
349 
350 	sun4m_timers->l10_timer_limit =  (((1000000/HZ) + 1) << 10);
351 	master_l10_counter = &sun4m_timers->l10_cur_count;
352 	master_l10_limit = &sun4m_timers->l10_timer_limit;
353 
354 	irq = request_irq(TIMER_IRQ,
355 			  counter_fn,
356 			  (IRQF_DISABLED | SA_STATIC_ALLOC),
357 			  "timer", NULL);
358 	if (irq) {
359 		prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
360 		prom_halt();
361 	}
362 
363 	if (!cpu_find_by_instance(1, NULL, NULL)) {
364 		for(cpu = 0; cpu < 4; cpu++)
365 			sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0;
366 		sun4m_interrupts->set = SUN4M_INT_E14;
367 	} else {
368 		sun4m_timers->cpu_timers[0].l14_timer_limit = 0;
369 	}
370 #ifdef CONFIG_SMP
371 	{
372 		unsigned long flags;
373 		extern unsigned long lvl14_save[4];
374 		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
375 
376 		/* For SMP we use the level 14 ticker, however the bootup code
377 		 * has copied the firmware's level 14 vector into the boot cpu's
378 		 * trap table, we must fix this now or we get squashed.
379 		 */
380 		local_irq_save(flags);
381 		trap_table->inst_one = lvl14_save[0];
382 		trap_table->inst_two = lvl14_save[1];
383 		trap_table->inst_three = lvl14_save[2];
384 		trap_table->inst_four = lvl14_save[3];
385 		local_flush_cache_all();
386 		local_irq_restore(flags);
387 	}
388 #endif
389 }
390 
391 void __init sun4m_init_IRQ(void)
392 {
393 	int ie_node,i;
394 	struct linux_prom_registers int_regs[PROMREG_MAX];
395 	int num_regs;
396 	struct resource r;
397 	int mid;
398 
399 	local_irq_disable();
400 	if((ie_node = prom_searchsiblings(prom_getchild(prom_root_node), "obio")) == 0 ||
401 	   (ie_node = prom_getchild (ie_node)) == 0 ||
402 	   (ie_node = prom_searchsiblings (ie_node, "interrupt")) == 0) {
403 		prom_printf("Cannot find /obio/interrupt node\n");
404 		prom_halt();
405 	}
406 	num_regs = prom_getproperty(ie_node, "reg", (char *) int_regs,
407 				    sizeof(int_regs));
408 	num_regs = (num_regs/sizeof(struct linux_prom_registers));
409 
410 	/* Apply the obio ranges to these registers. */
411 	prom_apply_obio_ranges(int_regs, num_regs);
412 
413 	int_regs[4].phys_addr = int_regs[num_regs-1].phys_addr;
414 	int_regs[4].reg_size = int_regs[num_regs-1].reg_size;
415 	int_regs[4].which_io = int_regs[num_regs-1].which_io;
416 	for(ie_node = 1; ie_node < 4; ie_node++) {
417 		int_regs[ie_node].phys_addr = int_regs[ie_node-1].phys_addr + PAGE_SIZE;
418 		int_regs[ie_node].reg_size = int_regs[ie_node-1].reg_size;
419 		int_regs[ie_node].which_io = int_regs[ie_node-1].which_io;
420 	}
421 
422 	memset((char *)&r, 0, sizeof(struct resource));
423 	/* Map the interrupt registers for all possible cpus. */
424 	r.flags = int_regs[0].which_io;
425 	r.start = int_regs[0].phys_addr;
426 	sun4m_interrupts = (struct sun4m_intregs *) sbus_ioremap(&r, 0,
427 	    PAGE_SIZE*SUN4M_NCPUS, "interrupts_percpu");
428 
429 	/* Map the system interrupt control registers. */
430 	r.flags = int_regs[4].which_io;
431 	r.start = int_regs[4].phys_addr;
432 	sbus_ioremap(&r, 0, int_regs[4].reg_size, "interrupts_system");
433 
434 	sun4m_interrupts->set = ~SUN4M_INT_MASKALL;
435 	for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
436 		sun4m_interrupts->cpu_intregs[mid].clear = ~0x17fff;
437 
438 	if (!cpu_find_by_instance(1, NULL, NULL)) {
439 		/* system wide interrupts go to cpu 0, this should always
440 		 * be safe because it is guaranteed to be fitted or OBP doesn't
441 		 * come up
442 		 *
443 		 * Not sure, but writing here on SLAVIO systems may puke
444 		 * so I don't do it unless there is more than 1 cpu.
445 		 */
446 		irq_rcvreg = (unsigned long *)
447 				&sun4m_interrupts->undirected_target;
448 		sun4m_interrupts->undirected_target = 0;
449 	}
450 	BTFIXUPSET_CALL(sbint_to_irq, sun4m_sbint_to_irq, BTFIXUPCALL_NORM);
451 	BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
452 	BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
453 	BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
454 	BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
455 	BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
456 	BTFIXUPSET_CALL(clear_profile_irq, sun4m_clear_profile_irq, BTFIXUPCALL_NORM);
457 	BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
458 	sparc_init_timers = sun4m_init_timers;
459 #ifdef CONFIG_SMP
460 	BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
461 	BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);
462 	BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);
463 #endif
464 	/* Cannot enable interrupts until OBP ticker is disabled. */
465 }
466