1 /*
2  *
3  * Programmable Interrupt Controller functions for the Freescale MPC52xx.
4  *
5  * Copyright (C) 2006 bplan GmbH
6  *
7  * Based on the code from the 2.4 kernel by
8  * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
9  *
10  * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11  * Copyright (C) 2003 Montavista Software, Inc
12  *
13  * This file is licensed under the terms of the GNU General Public License
14  * version 2. This program is licensed "as is" without any warranty of any
15  * kind, whether express or implied.
16  *
17  */
18 
19 #undef DEBUG
20 
21 #include <linux/interrupt.h>
22 #include <linux/irq.h>
23 #include <linux/of.h>
24 #include <asm/io.h>
25 #include <asm/prom.h>
26 #include <asm/mpc52xx.h>
27 #include "mpc52xx_pic.h"
28 
29 /*
30  *
31 */
32 
33 /* MPC5200 device tree match tables */
34 static struct of_device_id mpc52xx_pic_ids[] __initdata = {
35 	{ .compatible = "fsl,mpc5200-pic", },
36 	{ .compatible = "mpc5200-pic", },
37 	{}
38 };
39 static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
40 	{ .compatible = "fsl,mpc5200-bestcomm", },
41 	{ .compatible = "mpc5200-bestcomm", },
42 	{}
43 };
44 
45 static struct mpc52xx_intr __iomem *intr;
46 static struct mpc52xx_sdma __iomem *sdma;
47 static struct irq_host *mpc52xx_irqhost = NULL;
48 
49 static unsigned char mpc52xx_map_senses[4] = {
50 	IRQ_TYPE_LEVEL_HIGH,
51 	IRQ_TYPE_EDGE_RISING,
52 	IRQ_TYPE_EDGE_FALLING,
53 	IRQ_TYPE_LEVEL_LOW,
54 };
55 
56 /*
57  *
58 */
59 
60 static inline void io_be_setbit(u32 __iomem *addr, int bitno)
61 {
62 	out_be32(addr, in_be32(addr) | (1 << bitno));
63 }
64 
65 static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
66 {
67 	out_be32(addr, in_be32(addr) & ~(1 << bitno));
68 }
69 
70 /*
71  * IRQ[0-3] interrupt irq_chip
72 */
73 
74 static void mpc52xx_extirq_mask(unsigned int virq)
75 {
76 	int irq;
77 	int l2irq;
78 
79 	irq = irq_map[virq].hwirq;
80 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
81 
82 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
83 
84 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
85 }
86 
87 static void mpc52xx_extirq_unmask(unsigned int virq)
88 {
89 	int irq;
90 	int l2irq;
91 
92 	irq = irq_map[virq].hwirq;
93 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
94 
95 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
96 
97 	io_be_setbit(&intr->ctrl, 11 - l2irq);
98 }
99 
100 static void mpc52xx_extirq_ack(unsigned int virq)
101 {
102 	int irq;
103 	int l2irq;
104 
105 	irq = irq_map[virq].hwirq;
106 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
107 
108 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
109 
110 	io_be_setbit(&intr->ctrl, 27-l2irq);
111 }
112 
113 static int mpc52xx_extirq_set_type(unsigned int virq, unsigned int flow_type)
114 {
115 	u32 ctrl_reg, type;
116 	int irq;
117 	int l2irq;
118 
119 	irq = irq_map[virq].hwirq;
120 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
121 
122 	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
123 
124 	switch (flow_type) {
125 	case IRQF_TRIGGER_HIGH:
126 		type = 0;
127 		break;
128 	case IRQF_TRIGGER_RISING:
129 		type = 1;
130 		break;
131 	case IRQF_TRIGGER_FALLING:
132 		type = 2;
133 		break;
134 	case IRQF_TRIGGER_LOW:
135 		type = 3;
136 		break;
137 	default:
138 		type = 0;
139 	}
140 
141 	ctrl_reg = in_be32(&intr->ctrl);
142 	ctrl_reg &= ~(0x3 << (22 - (l2irq * 2)));
143 	ctrl_reg |= (type << (22 - (l2irq * 2)));
144 	out_be32(&intr->ctrl, ctrl_reg);
145 
146 	return 0;
147 }
148 
149 static struct irq_chip mpc52xx_extirq_irqchip = {
150 	.typename = " MPC52xx IRQ[0-3] ",
151 	.mask = mpc52xx_extirq_mask,
152 	.unmask = mpc52xx_extirq_unmask,
153 	.ack = mpc52xx_extirq_ack,
154 	.set_type = mpc52xx_extirq_set_type,
155 };
156 
157 /*
158  * Main interrupt irq_chip
159 */
160 
161 static void mpc52xx_main_mask(unsigned int virq)
162 {
163 	int irq;
164 	int l2irq;
165 
166 	irq = irq_map[virq].hwirq;
167 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
168 
169 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
170 
171 	io_be_setbit(&intr->main_mask, 16 - l2irq);
172 }
173 
174 static void mpc52xx_main_unmask(unsigned int virq)
175 {
176 	int irq;
177 	int l2irq;
178 
179 	irq = irq_map[virq].hwirq;
180 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
181 
182 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
183 
184 	io_be_clrbit(&intr->main_mask, 16 - l2irq);
185 }
186 
187 static struct irq_chip mpc52xx_main_irqchip = {
188 	.typename = "MPC52xx Main",
189 	.mask = mpc52xx_main_mask,
190 	.mask_ack = mpc52xx_main_mask,
191 	.unmask = mpc52xx_main_unmask,
192 };
193 
194 /*
195  * Peripherals interrupt irq_chip
196 */
197 
198 static void mpc52xx_periph_mask(unsigned int virq)
199 {
200 	int irq;
201 	int l2irq;
202 
203 	irq = irq_map[virq].hwirq;
204 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
205 
206 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
207 
208 	io_be_setbit(&intr->per_mask, 31 - l2irq);
209 }
210 
211 static void mpc52xx_periph_unmask(unsigned int virq)
212 {
213 	int irq;
214 	int l2irq;
215 
216 	irq = irq_map[virq].hwirq;
217 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
218 
219 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
220 
221 	io_be_clrbit(&intr->per_mask, 31 - l2irq);
222 }
223 
224 static struct irq_chip mpc52xx_periph_irqchip = {
225 	.typename = "MPC52xx Peripherals",
226 	.mask = mpc52xx_periph_mask,
227 	.mask_ack = mpc52xx_periph_mask,
228 	.unmask = mpc52xx_periph_unmask,
229 };
230 
231 /*
232  * SDMA interrupt irq_chip
233 */
234 
235 static void mpc52xx_sdma_mask(unsigned int virq)
236 {
237 	int irq;
238 	int l2irq;
239 
240 	irq = irq_map[virq].hwirq;
241 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
242 
243 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
244 
245 	io_be_setbit(&sdma->IntMask, l2irq);
246 }
247 
248 static void mpc52xx_sdma_unmask(unsigned int virq)
249 {
250 	int irq;
251 	int l2irq;
252 
253 	irq = irq_map[virq].hwirq;
254 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
255 
256 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
257 
258 	io_be_clrbit(&sdma->IntMask, l2irq);
259 }
260 
261 static void mpc52xx_sdma_ack(unsigned int virq)
262 {
263 	int irq;
264 	int l2irq;
265 
266 	irq = irq_map[virq].hwirq;
267 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
268 
269 	pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
270 
271 	out_be32(&sdma->IntPend, 1 << l2irq);
272 }
273 
274 static struct irq_chip mpc52xx_sdma_irqchip = {
275 	.typename = "MPC52xx SDMA",
276 	.mask = mpc52xx_sdma_mask,
277 	.unmask = mpc52xx_sdma_unmask,
278 	.ack = mpc52xx_sdma_ack,
279 };
280 
281 /*
282  * irq_host
283 */
284 
285 static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
286 				 u32 * intspec, unsigned int intsize,
287 				 irq_hw_number_t * out_hwirq,
288 				 unsigned int *out_flags)
289 {
290 	int intrvect_l1;
291 	int intrvect_l2;
292 	int intrvect_type;
293 	int intrvect_linux;
294 
295 	if (intsize != 3)
296 		return -1;
297 
298 	intrvect_l1 = (int)intspec[0];
299 	intrvect_l2 = (int)intspec[1];
300 	intrvect_type = (int)intspec[2];
301 
302 	intrvect_linux =
303 	    (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK;
304 	intrvect_linux |=
305 	    (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK;
306 
307 	pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
308 		 intrvect_l2);
309 
310 	*out_hwirq = intrvect_linux;
311 	*out_flags = mpc52xx_map_senses[intrvect_type];
312 
313 	return 0;
314 }
315 
316 /*
317  * this function retrieves the correct IRQ type out
318  * of the MPC regs
319  * Only externals IRQs needs this
320 */
321 static int mpc52xx_irqx_gettype(int irq)
322 {
323 	int type;
324 	u32 ctrl_reg;
325 
326 	ctrl_reg = in_be32(&intr->ctrl);
327 	type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
328 
329 	return mpc52xx_map_senses[type];
330 }
331 
332 static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
333 			       irq_hw_number_t irq)
334 {
335 	int l1irq;
336 	int l2irq;
337 	struct irq_chip *good_irqchip;
338 	void *good_handle;
339 	int type;
340 
341 	l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
342 	l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
343 
344 	/*
345 	 * Most of ours IRQs will be level low
346 	 * Only external IRQs on some platform may be others
347 	 */
348 	type = IRQ_TYPE_LEVEL_LOW;
349 
350 	switch (l1irq) {
351 	case MPC52xx_IRQ_L1_CRIT:
352 		pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
353 
354 		BUG_ON(l2irq != 0);
355 
356 		type = mpc52xx_irqx_gettype(l2irq);
357 		good_irqchip = &mpc52xx_extirq_irqchip;
358 		break;
359 
360 	case MPC52xx_IRQ_L1_MAIN:
361 		pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
362 
363 		if ((l2irq >= 1) && (l2irq <= 3)) {
364 			type = mpc52xx_irqx_gettype(l2irq);
365 			good_irqchip = &mpc52xx_extirq_irqchip;
366 		} else {
367 			good_irqchip = &mpc52xx_main_irqchip;
368 		}
369 		break;
370 
371 	case MPC52xx_IRQ_L1_PERP:
372 		pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
373 		good_irqchip = &mpc52xx_periph_irqchip;
374 		break;
375 
376 	case MPC52xx_IRQ_L1_SDMA:
377 		pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
378 		good_irqchip = &mpc52xx_sdma_irqchip;
379 		break;
380 
381 	default:
382 		pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq);
383 		printk(KERN_ERR "Unknow IRQ!\n");
384 		return -EINVAL;
385 	}
386 
387 	switch (type) {
388 	case IRQ_TYPE_EDGE_FALLING:
389 	case IRQ_TYPE_EDGE_RISING:
390 		good_handle = handle_edge_irq;
391 		break;
392 	default:
393 		good_handle = handle_level_irq;
394 	}
395 
396 	set_irq_chip_and_handler(virq, good_irqchip, good_handle);
397 
398 	pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
399 		 (int)irq, type);
400 
401 	return 0;
402 }
403 
404 static struct irq_host_ops mpc52xx_irqhost_ops = {
405 	.xlate = mpc52xx_irqhost_xlate,
406 	.map = mpc52xx_irqhost_map,
407 };
408 
409 /*
410  * init (public)
411 */
412 
413 void __init mpc52xx_init_irq(void)
414 {
415 	u32 intr_ctrl;
416 	struct device_node *picnode;
417 	struct device_node *np;
418 
419 	/* Remap the necessary zones */
420 	picnode = of_find_matching_node(NULL, mpc52xx_pic_ids);
421 	intr = of_iomap(picnode, 0);
422 	if (!intr)
423 		panic(__FILE__	": find_and_map failed on 'mpc5200-pic'. "
424 				"Check node !");
425 
426 	np = of_find_matching_node(NULL, mpc52xx_sdma_ids);
427 	sdma = of_iomap(np, 0);
428 	of_node_put(np);
429 	if (!sdma)
430 		panic(__FILE__	": find_and_map failed on 'mpc5200-bestcomm'. "
431 				"Check node !");
432 
433 	/* Disable all interrupt sources. */
434 	out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
435 	out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
436 	out_be32(&intr->per_mask, 0x7ffffc00);	/* 1 means disabled */
437 	out_be32(&intr->main_mask, 0x00010fff);	/* 1 means disabled */
438 	intr_ctrl = in_be32(&intr->ctrl);
439 	intr_ctrl &= 0x00ff0000;	/* Keeps IRQ[0-3] config */
440 	intr_ctrl |=	0x0f000000 |	/* clear IRQ 0-3 */
441 			0x00001000 |	/* MEE master external enable */
442 			0x00000000 |	/* 0 means disable IRQ 0-3 */
443 			0x00000001;	/* CEb route critical normally */
444 	out_be32(&intr->ctrl, intr_ctrl);
445 
446 	/* Zero a bunch of the priority settings. */
447 	out_be32(&intr->per_pri1, 0);
448 	out_be32(&intr->per_pri2, 0);
449 	out_be32(&intr->per_pri3, 0);
450 	out_be32(&intr->main_pri1, 0);
451 	out_be32(&intr->main_pri2, 0);
452 
453 	/*
454 	 * As last step, add an irq host to translate the real
455 	 * hw irq information provided by the ofw to linux virq
456 	 */
457 
458 	mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
459 	                                 MPC52xx_IRQ_HIGHTESTHWIRQ,
460 	                                 &mpc52xx_irqhost_ops, -1);
461 
462 	if (!mpc52xx_irqhost)
463 		panic(__FILE__ ": Cannot allocate the IRQ host\n");
464 
465 	printk(KERN_INFO "MPC52xx PIC is up and running!\n");
466 }
467 
468 /*
469  * get_irq (public)
470 */
471 unsigned int mpc52xx_get_irq(void)
472 {
473 	u32 status;
474 	int irq = NO_IRQ_IGNORE;
475 
476 	status = in_be32(&intr->enc_status);
477 	if (status & 0x00000400) {	/* critical */
478 		irq = (status >> 8) & 0x3;
479 		if (irq == 2)	/* high priority peripheral */
480 			goto peripheral;
481 		irq |=	(MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) &
482 			MPC52xx_IRQ_L1_MASK;
483 	} else if (status & 0x00200000) {	/* main */
484 		irq = (status >> 16) & 0x1f;
485 		if (irq == 4)	/* low priority peripheral */
486 			goto peripheral;
487 		irq |=	(MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) &
488 			MPC52xx_IRQ_L1_MASK;
489 	} else if (status & 0x20000000) {	/* peripheral */
490 	      peripheral:
491 		irq = (status >> 24) & 0x1f;
492 		if (irq == 0) {	/* bestcomm */
493 			status = in_be32(&sdma->IntPend);
494 			irq = ffs(status) - 1;
495 			irq |=	(MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) &
496 				MPC52xx_IRQ_L1_MASK;
497 		} else {
498 			irq |=	(MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) &
499 				MPC52xx_IRQ_L1_MASK;
500 		}
501 	}
502 
503 	pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
504 		 irq_linear_revmap(mpc52xx_irqhost, irq));
505 
506 	return irq_linear_revmap(mpc52xx_irqhost, irq);
507 }
508