1 /*
2  *
3  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
4  *
5  *    Module name: ppc4xx_pic.c
6  *
7  *    Description:
8  *      Interrupt controller driver for PowerPC 4xx-based processors.
9  */
10 
11 /*
12  * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
13  * 32 possible interrupts, a majority of which are not implemented on
14  * all cores. There are six configurable, external interrupt pins and
15  * there are eight internal interrupts for the on-chip serial port
16  * (SPU), DMA controller, and JTAG controller.
17  *
18  * The PowerPC 405/440 cores' Universal Interrupt Controller (UIC) has
19  * 32 possible interrupts as well.  Depending on the core and SoC
20  * implementation, a portion of the interrrupts are used for on-chip
21  * peripherals and a portion of the interrupts are available to be
22  * configured for external devices generating interrupts.
23  *
24  * The PowerNP and 440GP (and most likely future implementations) have
25  * cascaded UICs.
26  *
27  */
28 
29 #include <linux/init.h>
30 #include <linux/sched.h>
31 #include <linux/signal.h>
32 #include <linux/stddef.h>
33 
34 #include <asm/processor.h>
35 #include <asm/system.h>
36 #include <asm/irq.h>
37 #include <asm/ppc4xx_pic.h>
38 
39 /* Global Variables */
40 struct hw_interrupt_type *ppc4xx_pic;
41 /*
42  * We define 4xxIRQ_InitSenses table thusly:
43  * bit 0x1: sense, 0 for edge and 1 for level.
44  * bit 0x2: polarity, 0 for negative, 1 for positive.
45  */
46 unsigned int ibm4xxPIC_NumInitSenses __initdata = 0;
47 unsigned char *ibm4xxPIC_InitSenses __initdata = NULL;
48 
49 /* Six of one, half dozen of the other....#ifdefs, separate files,
50  * other tricks.....
51  *
52  * There are basically two types of interrupt controllers, the 403 AIC
53  * and the "others" with UIC.  I just kept them both here separated
54  * with #ifdefs, but it seems to change depending upon how supporting
55  * files (like ppc4xx.h) change.		-- Dan.
56  */
57 
58 #ifdef CONFIG_403
59 
60 /* Function Prototypes */
61 
62 static void ppc403_aic_enable(unsigned int irq);
63 static void ppc403_aic_disable(unsigned int irq);
64 static void ppc403_aic_disable_and_ack(unsigned int irq);
65 
66 static struct hw_interrupt_type ppc403_aic = {
67 	"403GC AIC",
68 	NULL,
69 	NULL,
70 	ppc403_aic_enable,
71 	ppc403_aic_disable,
72 	ppc403_aic_disable_and_ack,
73 	0
74 };
75 
76 int
ppc403_pic_get_irq(struct pt_regs * regs)77 ppc403_pic_get_irq(struct pt_regs *regs)
78 {
79 	int irq;
80 	unsigned long bits;
81 
82 	/*
83 	 * Only report the status of those interrupts that are actually
84 	 * enabled.
85 	 */
86 
87 	bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
88 
89 	/*
90 	 * Walk through the interrupts from highest priority to lowest, and
91 	 * report the first pending interrupt found.
92 	 * We want PPC, not C bit numbering, so just subtract the ffs()
93 	 * result from 32.
94 	 */
95 	irq = 32 - ffs(bits);
96 
97 	if (irq == NR_AIC_IRQS)
98 		irq = -1;
99 
100 	return (irq);
101 }
102 
103 static void
ppc403_aic_enable(unsigned int irq)104 ppc403_aic_enable(unsigned int irq)
105 {
106 	int bit, word;
107 
108 	bit = irq & 0x1f;
109 	word = irq >> 5;
110 
111 	ppc_cached_irq_mask[word] |= (1 << (31 - bit));
112 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
113 }
114 
115 static void
ppc403_aic_disable(unsigned int irq)116 ppc403_aic_disable(unsigned int irq)
117 {
118 	int bit, word;
119 
120 	bit = irq & 0x1f;
121 	word = irq >> 5;
122 
123 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
124 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
125 }
126 
127 static void
ppc403_aic_disable_and_ack(unsigned int irq)128 ppc403_aic_disable_and_ack(unsigned int irq)
129 {
130 	int bit, word;
131 
132 	bit = irq & 0x1f;
133 	word = irq >> 5;
134 
135 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
136 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
137 	mtdcr(DCRN_EXISR, (1 << (31 - bit)));
138 }
139 
140 #else
141 
142 #ifndef UIC1
143 #define UIC1 UIC0
144 #endif
145 
146 static void
ppc405_uic_enable(unsigned int irq)147 ppc405_uic_enable(unsigned int irq)
148 {
149 	int bit, word;
150 	irq_desc_t *desc = irq_desc + irq;
151 
152 	bit = irq & 0x1f;
153 	word = irq >> 5;
154 
155 #ifdef UIC_DEBUG
156 	printk("ppc405_uic_enable - irq %d word %d bit 0x%x\n", irq, word, bit);
157 #endif
158 	ppc_cached_irq_mask[word] |= 1 << (31 - bit);
159 	switch (word) {
160 	case 0:
161 		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
162 		if ((mfdcr(DCRN_UIC_TR(UIC0)) & (1 << (31 - bit))) == 0)
163 			desc->status |= IRQ_LEVEL;
164 		else
165 		/* lets hope this works since in linux/irq.h
166 		 * there is no define for EDGE and it's assumed
167 		 * once you set status to LEVEL you would not
168 		 * want to change it - Armin
169 		 */
170 		desc->status = desc->status & ~IRQ_LEVEL;
171 		break;
172 	case 1:
173 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
174 		if ((mfdcr(DCRN_UIC_TR(UIC1)) & (1 << (31 - bit))) == 0)
175 			desc->status |= IRQ_LEVEL;
176 		else
177 		/* lets hope this works since in linux/irq.h
178 		 * there is no define for EDGE and it's assumed
179 		 * once you set status to LEVEL you would not
180 		 * want to change it - Armin
181 		 */
182 		desc->status = desc->status & ~IRQ_LEVEL;
183 	break;
184 	}
185 
186 }
187 
188 static void
ppc405_uic_disable(unsigned int irq)189 ppc405_uic_disable(unsigned int irq)
190 {
191 	int bit, word;
192 
193 	bit = irq & 0x1f;
194 	word = irq >> 5;
195 #ifdef UIC_DEBUG
196 	printk("ppc405_uic_disable - irq %d word %d bit 0x%x\n", irq, word,
197 	       bit);
198 #endif
199 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
200 	switch (word) {
201 	case 0:
202 		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
203 		break;
204 	case 1:
205 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
206 		break;
207 	}
208 }
209 
210 static void
ppc405_uic_disable_and_ack(unsigned int irq)211 ppc405_uic_disable_and_ack(unsigned int irq)
212 {
213 	int bit, word;
214 
215 	bit = irq & 0x1f;
216 	word = irq >> 5;
217 
218 #ifdef UIC_DEBUG
219 	printk("ppc405_uic_disable_and_ack - irq %d word %d bit 0x%x\n", irq,
220 	       word, bit);
221 #endif
222 	ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
223 	switch (word) {
224 	case 0:
225 		mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
226 		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - bit)));
227 		break;
228 #if NR_UICS > 1
229 	case 1:
230 		mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
231 		mtdcr(DCRN_UIC_SR(UIC1), (1 << (31 - bit)));
232 		/* ACK cascaded interrupt in UIC0 */
233 		mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
234 		break;
235 #endif
236 	}
237 }
238 
239 static void
ppc405_uic_end(unsigned int irq)240 ppc405_uic_end(unsigned int irq)
241 {
242 	int bit, word;
243 	unsigned int tr_bits;
244 
245 	bit = irq & 0x1f;
246 	word = irq >> 5;
247 
248 #ifdef UIC_DEBUG
249 	printk("ppc405_uic_end - irq %d word %d bit 0x%x\n", irq, word, bit);
250 #endif
251 
252 	switch (word) {
253 	case 0:
254 		tr_bits = mfdcr(DCRN_UIC_TR(UIC0));
255 		break;
256 	case 1:
257 		tr_bits = mfdcr(DCRN_UIC_TR(UIC1));
258 		break;
259 	}
260 
261 	if ((tr_bits & (1 << (31 - bit))) == 0) {
262 		/* level trigger */
263 		switch (word) {
264 		case 0:
265 			mtdcr(DCRN_UIC_SR(UIC0), 1 << (31 - bit));
266 			break;
267 #if NR_UICS > 1
268 		case 1:
269 			mtdcr(DCRN_UIC_SR(UIC1), 1 << (31 - bit));
270 			/* ACK cascaded interrupt in UIC0 */
271 			mtdcr(DCRN_UIC_SR(UIC0), (1 << (31 - UIC0_UIC1NC)));
272 			break;
273 #endif
274 		}
275 	}
276 
277 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
278 		ppc_cached_irq_mask[word] |= 1 << (31 - bit);
279 		switch (word) {
280 		case 0:
281 			mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[word]);
282 			break;
283 		case 1:
284 			mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[word]);
285 			break;
286 		}
287 	}
288 }
289 
290 static struct hw_interrupt_type ppc405_uic = {
291 #if (NR_UICS == 1)
292 	"IBM UIC",
293 #else
294 	"IBM UIC Cascade",
295 #endif
296 	NULL,
297 	NULL,
298 	ppc405_uic_enable,
299 	ppc405_uic_disable,
300 	ppc405_uic_disable_and_ack,
301 	ppc405_uic_end,
302 	0
303 };
304 
305 int
ppc405_pic_get_irq(struct pt_regs * regs)306 ppc405_pic_get_irq(struct pt_regs *regs)
307 {
308 	int irq, cas_irq;
309 	unsigned long bits;
310 	cas_irq = 0;
311 	/*
312 	 * Only report the status of those interrupts that are actually
313 	 * enabled.
314 	 */
315 
316 	bits = mfdcr(DCRN_UIC_MSR(UIC0));
317 
318 #if (NR_UICS > 1)
319 	if (bits & UIC_CASCADE_MASK) {
320 		bits = mfdcr(DCRN_UIC_MSR(UIC1));
321 		cas_irq = 32 - ffs(bits);
322 		irq = 32 + cas_irq;
323 	} else {
324 		irq = 32 - ffs(bits);
325 		if (irq == 32)
326 			irq = -1;
327 	}
328 #else
329 	/*
330 	 * Walk through the interrupts from highest priority to lowest, and
331 	 * report the first pending interrupt found.
332 	 * We want PPC, not C bit numbering, so just subtract the ffs()
333 	 * result from 32.
334 	 */
335 	irq = 32 - ffs(bits);
336 #endif
337 	if (irq == (NR_UIC_IRQS * NR_UICS))
338 		irq = -1;
339 
340 #ifdef UIC_DEBUG
341 	printk("ppc405_pic_get_irq - irq %d bit 0x%x\n", irq, bits);
342 #endif
343 
344 	return (irq);
345 }
346 #endif
347 
348 void __init
ppc4xx_extpic_init(void)349 ppc4xx_extpic_init(void)
350 {
351 	unsigned int sense, irq;
352 	int bit, word;
353 	unsigned long ppc_cached_sense_mask[NR_MASK_WORDS];
354 	unsigned long ppc_cached_pol_mask[NR_MASK_WORDS];
355 	ppc_cached_sense_mask[0] = 0;
356 	ppc_cached_sense_mask[1] = 0;
357 	ppc_cached_pol_mask[0] = 0;
358 	ppc_cached_pol_mask[1] = 0;
359 
360 	for (irq = 0; irq < NR_IRQS; irq++) {
361 
362 		bit = irq & 0x1f;
363 		word = irq >> 5;
364 
365 		sense = (irq < ibm4xxPIC_NumInitSenses) ?
366 			ibm4xxPIC_InitSenses[irq] :
367 			IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE;
368 #ifdef PPC4xx_PIC_DEBUG
369 		printk("PPC4xx_picext %d word:%x bit:%x sense:%x", irq, word,
370 		       bit, sense);
371 #endif
372 		ppc_cached_sense_mask[word] |=
373 		    (~sense & IRQ_SENSE_MASK) << (31 - bit);
374 		ppc_cached_pol_mask[word] |=
375 		    ((sense & IRQ_POLARITY_MASK) >> 1) << (31 - bit);
376 		switch (word) {
377 		case 0:
378 #ifdef PPC4xx_PIC_DEBUG
379 			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC0)));
380 			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC0)));
381 #endif
382 			/* polarity  setting */
383 			mtdcr(DCRN_UIC_PR(UIC0), ppc_cached_pol_mask[word]);
384 
385 			/* Level setting */
386 			mtdcr(DCRN_UIC_TR(UIC0), ppc_cached_sense_mask[word]);
387 
388 			break;
389 		case 1:
390 #ifdef PPC4xx_PIC_DEBUG
391 			printk("Pol %x ", mfdcr(DCRN_UIC_PR(UIC1)));
392 			printk("Level %x\n", mfdcr(DCRN_UIC_TR(UIC1)));
393 #endif
394 			/* polarity  setting */
395 			mtdcr(DCRN_UIC_PR(UIC1), ppc_cached_pol_mask[word]);
396 
397 			/* Level setting */
398 			mtdcr(DCRN_UIC_TR(UIC1), ppc_cached_sense_mask[word]);
399 
400 			break;
401 		}
402 	}
403 
404 }
405 void __init
ppc4xx_pic_init(void)406 ppc4xx_pic_init(void)
407 {
408 
409 	/*
410 	 * Disable all external interrupts until they are
411 	 * explicity requested.
412 	 */
413 	ppc_cached_irq_mask[0] = 0;
414 	ppc_cached_irq_mask[1] = 0;
415 
416 #if defined CONFIG_403
417 	mtdcr(DCRN_EXIER, ppc_cached_irq_mask[0]);
418 
419 	ppc4xx_pic = &ppc403_aic;
420 	ppc_md.get_irq = ppc403_pic_get_irq;
421 #else
422 #if  (NR_UICS > 1)
423 	ppc_cached_irq_mask[0] |= 1 << (31 - UIC0_UIC1NC);	/* enable cascading interrupt */
424 	mtdcr(DCRN_UIC_ER(UIC1), ppc_cached_irq_mask[1]);
425 	mtdcr(DCRN_UIC_CR(UIC1), 0);
426 
427 #endif
428 	mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
429 	mtdcr(DCRN_UIC_CR(UIC0), 0);
430 
431 	if (ibm4xxPIC_InitSenses != NULL)
432 		ppc4xx_extpic_init();
433 
434 	/* Clear any pending interrupts */
435 #if (NR_UICS > 1)
436 	mtdcr(DCRN_UIC_SR(UIC1), 0xffffffff);
437 #endif
438 	mtdcr(DCRN_UIC_SR(UIC0), 0xffffffff);
439 
440 	ppc4xx_pic = &ppc405_uic;
441 	ppc_md.get_irq = ppc405_pic_get_irq;
442 #endif
443 
444 }
445