bcm2835_intr.c revision 1.4.2.1 1 1.4.2.1 skrll /* $NetBSD: bcm2835_intr.c,v 1.4.2.1 2015/04/06 15:17:52 skrll Exp $ */
2 1.1 skrll
3 1.1 skrll /*-
4 1.1 skrll * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 1.1 skrll * All rights reserved.
6 1.1 skrll *
7 1.1 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.1 skrll * by Nick Hudson
9 1.1 skrll *
10 1.1 skrll * Redistribution and use in source and binary forms, with or without
11 1.1 skrll * modification, are permitted provided that the following conditions
12 1.1 skrll * are met:
13 1.1 skrll * 1. Redistributions of source code must retain the above copyright
14 1.1 skrll * notice, this list of conditions and the following disclaimer.
15 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 skrll * notice, this list of conditions and the following disclaimer in the
17 1.1 skrll * documentation and/or other materials provided with the distribution.
18 1.1 skrll *
19 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 skrll * POSSIBILITY OF SUCH DAMAGE.
30 1.1 skrll */
31 1.1 skrll
32 1.1 skrll #include <sys/cdefs.h>
33 1.4.2.1 skrll __KERNEL_RCSID(0, "$NetBSD: bcm2835_intr.c,v 1.4.2.1 2015/04/06 15:17:52 skrll Exp $");
34 1.1 skrll
35 1.1 skrll #define _INTR_PRIVATE
36 1.1 skrll
37 1.4.2.1 skrll #include "opt_bcm283x.h"
38 1.4.2.1 skrll
39 1.1 skrll #include <sys/param.h>
40 1.4.2.1 skrll #include <sys/bus.h>
41 1.4.2.1 skrll #include <sys/cpu.h>
42 1.1 skrll #include <sys/device.h>
43 1.4.2.1 skrll #include <sys/proc.h>
44 1.1 skrll
45 1.1 skrll #include <machine/intr.h>
46 1.4.2.1 skrll
47 1.4.2.1 skrll #include <arm/locore.h>
48 1.1 skrll
49 1.1 skrll #include <arm/pic/picvar.h>
50 1.4.2.1 skrll #include <arm/cortex/gtmr_var.h>
51 1.1 skrll
52 1.1 skrll #include <arm/broadcom/bcm_amba.h>
53 1.1 skrll #include <arm/broadcom/bcm2835reg.h>
54 1.4.2.1 skrll #include <arm/broadcom/bcm2835var.h>
55 1.1 skrll
56 1.1 skrll static void bcm2835_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
57 1.1 skrll static void bcm2835_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
58 1.1 skrll static int bcm2835_pic_find_pending_irqs(struct pic_softc *);
59 1.1 skrll static void bcm2835_pic_establish_irq(struct pic_softc *, struct intrsource *);
60 1.1 skrll static void bcm2835_pic_source_name(struct pic_softc *, int, char *,
61 1.1 skrll size_t);
62 1.1 skrll
63 1.4.2.1 skrll #if defined(BCM2836)
64 1.4.2.1 skrll static void bcm2836mp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
65 1.4.2.1 skrll static void bcm2836mp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
66 1.4.2.1 skrll static int bcm2836mp_pic_find_pending_irqs(struct pic_softc *);
67 1.4.2.1 skrll static void bcm2836mp_pic_establish_irq(struct pic_softc *, struct intrsource *);
68 1.4.2.1 skrll static void bcm2836mp_pic_source_name(struct pic_softc *, int, char *,
69 1.4.2.1 skrll size_t);
70 1.4.2.1 skrll #if 0
71 1.4.2.1 skrll #ifdef MULTIPROCESSOR
72 1.4.2.1 skrll int bcm2836mp_ipi_handler(void *);
73 1.4.2.1 skrll static void bcm2836mp_cpu_init(struct pic_softc *, struct cpu_info *);
74 1.4.2.1 skrll static void bcm2836mp_send_ipi(struct pic_softc *, const kcpuset_t *, u_long);
75 1.4.2.1 skrll #endif
76 1.4.2.1 skrll #endif
77 1.4.2.1 skrll #endif
78 1.4.2.1 skrll
79 1.4.2.1 skrll #ifdef MULTIPROCESSOR
80 1.4.2.1 skrll static void
81 1.4.2.1 skrll bcm2835_dummy(struct pic_softc *pic, const kcpuset_t *kcp, u_long ipi)
82 1.4.2.1 skrll {
83 1.4.2.1 skrll }
84 1.4.2.1 skrll #endif
85 1.4.2.1 skrll
86 1.1 skrll static int bcm2835_icu_match(device_t, cfdata_t, void *);
87 1.1 skrll static void bcm2835_icu_attach(device_t, device_t, void *);
88 1.1 skrll
89 1.1 skrll static struct pic_ops bcm2835_picops = {
90 1.1 skrll .pic_unblock_irqs = bcm2835_pic_unblock_irqs,
91 1.1 skrll .pic_block_irqs = bcm2835_pic_block_irqs,
92 1.1 skrll .pic_find_pending_irqs = bcm2835_pic_find_pending_irqs,
93 1.1 skrll .pic_establish_irq = bcm2835_pic_establish_irq,
94 1.1 skrll .pic_source_name = bcm2835_pic_source_name,
95 1.4.2.1 skrll #if defined(MULTIPROCESSOR)
96 1.4.2.1 skrll .pic_ipi_send = bcm2835_dummy,
97 1.4.2.1 skrll #endif
98 1.1 skrll };
99 1.1 skrll
100 1.1 skrll struct pic_softc bcm2835_pic = {
101 1.1 skrll .pic_ops = &bcm2835_picops,
102 1.1 skrll .pic_maxsources = BCM2835_NIRQ,
103 1.1 skrll .pic_name = "bcm2835 pic",
104 1.1 skrll };
105 1.1 skrll
106 1.4.2.1 skrll #if defined(BCM2836)
107 1.4.2.1 skrll static struct pic_ops bcm2836mp_picops = {
108 1.4.2.1 skrll .pic_unblock_irqs = bcm2836mp_pic_unblock_irqs,
109 1.4.2.1 skrll .pic_block_irqs = bcm2836mp_pic_block_irqs,
110 1.4.2.1 skrll .pic_find_pending_irqs = bcm2836mp_pic_find_pending_irqs,
111 1.4.2.1 skrll .pic_establish_irq = bcm2836mp_pic_establish_irq,
112 1.4.2.1 skrll .pic_source_name = bcm2836mp_pic_source_name,
113 1.4.2.1 skrll #if 0 && defined(MULTIPROCESSOR)
114 1.4.2.1 skrll .pic_cpu_init = bcm2836mp_cpu_init,
115 1.4.2.1 skrll .pic_ipi_send = bcm2836mp_send_ipi,
116 1.4.2.1 skrll #endif
117 1.4.2.1 skrll };
118 1.4.2.1 skrll
119 1.4.2.1 skrll struct pic_softc bcm2836mp_pic = {
120 1.4.2.1 skrll .pic_ops = &bcm2836mp_picops,
121 1.4.2.1 skrll .pic_maxsources = BCM2836MP_NIRQ,
122 1.4.2.1 skrll .pic_name = "bcm2836 mp pic",
123 1.4.2.1 skrll };
124 1.4.2.1 skrll #endif
125 1.4.2.1 skrll
126 1.1 skrll struct bcm2835icu_softc {
127 1.1 skrll device_t sc_dev;
128 1.1 skrll bus_space_tag_t sc_iot;
129 1.1 skrll bus_space_handle_t sc_ioh;
130 1.1 skrll struct pic_softc *sc_pic;
131 1.1 skrll };
132 1.1 skrll
133 1.1 skrll struct bcm2835icu_softc *bcmicu_sc;
134 1.3 skrll
135 1.1 skrll #define read_bcm2835reg(o) \
136 1.1 skrll bus_space_read_4(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, (o))
137 1.3 skrll
138 1.1 skrll #define write_bcm2835reg(o, v) \
139 1.1 skrll bus_space_write_4(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, (o), (v))
140 1.1 skrll
141 1.1 skrll
142 1.1 skrll #define bcm2835_barrier() \
143 1.1 skrll bus_space_barrier(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, 0, \
144 1.1 skrll BCM2835_ARMICU_SIZE, BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
145 1.3 skrll
146 1.1 skrll static const char * const bcm2835_sources[BCM2835_NIRQ] = {
147 1.1 skrll "(unused 0)", "(unused 1)", "(unused 2)", "timer3",
148 1.1 skrll "(unused 4)", "(unused 5)", "(unused 6)", "jpeg",
149 1.2 jakllsch "(unused 8)", "usb", "(unused 10)", "(unused 11)",
150 1.2 jakllsch "(unused 12)", "(unused 13)", "(unused 14)", "(unused 15)",
151 1.4 skrll "dma0", "dma1", "dma2", "dma3",
152 1.4 skrll "dma4", "dma5", "dma6", "dma7",
153 1.4 skrll "dma8", "dma9", "dma10", "dma11",
154 1.4 skrll "dma12", "aux", "(unused 30)", "(unused 31)",
155 1.1 skrll "(unused 32)", "(unused 33)", "(unused 34)", "(unused 35)",
156 1.1 skrll "(unused 36)", "(unused 37)", "(unused 38)", "(unused 39)",
157 1.1 skrll "(unused 40)", "(unused 41)", "(unused 42)", "i2c spl slv",
158 1.1 skrll "(unused 44)", "pwa0", "pwa1", "(unused 47)",
159 1.1 skrll "smi", "gpio[0]", "gpio[1]", "gpio[2]",
160 1.1 skrll "gpio[3]", "i2c", "spi", "pcm",
161 1.1 skrll "sdio", "uart", "(unused 58)", "(unused 59)",
162 1.1 skrll "(unused 60)", "(unused 61)", "emmc", "(unused 63)",
163 1.1 skrll "Timer", "Mailbox", "Doorbell0", "Doorbell1",
164 1.1 skrll "GPU0 Halted", "GPU1 Halted", "Illegal #1", "Illegal #0"
165 1.1 skrll };
166 1.1 skrll
167 1.4.2.1 skrll #if defined(BCM2836)
168 1.4.2.1 skrll static const char * const bcm2836mp_sources[BCM2836MP_NIRQ] = {
169 1.4.2.1 skrll "cntpsirq", "cntpnsirq", "cnthpirq", "cntvirq",
170 1.4.2.1 skrll "mailbox0", "mailbox1", "mailbox2", "mailbox3",
171 1.4.2.1 skrll };
172 1.4.2.1 skrll #endif
173 1.4.2.1 skrll
174 1.4.2.1 skrll #define BCM2836_INTBIT_GPUPENDING __BIT(8)
175 1.4.2.1 skrll
176 1.1 skrll #define BCM2835_INTBIT_PENDING1 __BIT(8)
177 1.1 skrll #define BCM2835_INTBIT_PENDING2 __BIT(9)
178 1.1 skrll #define BCM2835_INTBIT_ARM __BITS(0,7)
179 1.1 skrll #define BCM2835_INTBIT_GPU0 __BITS(10,14)
180 1.1 skrll #define BCM2835_INTBIT_GPU1 __BITS(15,20)
181 1.1 skrll
182 1.1 skrll CFATTACH_DECL_NEW(bcmicu, sizeof(struct bcm2835icu_softc),
183 1.1 skrll bcm2835_icu_match, bcm2835_icu_attach, NULL, NULL);
184 1.1 skrll
185 1.1 skrll static int
186 1.1 skrll bcm2835_icu_match(device_t parent, cfdata_t cf, void *aux)
187 1.1 skrll {
188 1.1 skrll struct amba_attach_args *aaa = aux;
189 1.1 skrll
190 1.1 skrll if (strcmp(aaa->aaa_name, "icu") != 0)
191 1.1 skrll return 0;
192 1.1 skrll
193 1.1 skrll return 1;
194 1.1 skrll }
195 1.1 skrll
196 1.1 skrll static void
197 1.1 skrll bcm2835_icu_attach(device_t parent, device_t self, void *aux)
198 1.1 skrll {
199 1.1 skrll struct bcm2835icu_softc *sc = device_private(self);
200 1.1 skrll struct amba_attach_args *aaa = aux;
201 1.1 skrll
202 1.1 skrll sc->sc_dev = self;
203 1.1 skrll sc->sc_iot = aaa->aaa_iot;
204 1.1 skrll sc->sc_pic = &bcm2835_pic;
205 1.1 skrll
206 1.1 skrll if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, aaa->aaa_size, 0,
207 1.1 skrll &sc->sc_ioh)) {
208 1.1 skrll aprint_error_dev(self, "unable to map device\n");
209 1.1 skrll return;
210 1.1 skrll }
211 1.1 skrll
212 1.1 skrll bcmicu_sc = sc;
213 1.4.2.1 skrll
214 1.1 skrll pic_add(sc->sc_pic, 0);
215 1.4.2.1 skrll
216 1.4.2.1 skrll #if defined(BCM2836)
217 1.4.2.1 skrll #if 0 && defined(MULTIPROCESSOR)
218 1.4.2.1 skrll aprint_normal(": Multiprocessor");
219 1.4.2.1 skrll #endif
220 1.4.2.1 skrll pic_add(&bcm2836mp_pic, BCM2836_INT_LOCALBASE);
221 1.4.2.1 skrll #endif
222 1.4.2.1 skrll
223 1.1 skrll aprint_normal("\n");
224 1.1 skrll }
225 1.1 skrll
226 1.1 skrll void
227 1.1 skrll bcm2835_irq_handler(void *frame)
228 1.1 skrll {
229 1.1 skrll struct cpu_info * const ci = curcpu();
230 1.1 skrll const int oldipl = ci->ci_cpl;
231 1.1 skrll const uint32_t oldipl_mask = __BIT(oldipl);
232 1.1 skrll int ipl_mask = 0;
233 1.1 skrll
234 1.1 skrll ci->ci_data.cpu_nintr++;
235 1.1 skrll
236 1.1 skrll bcm2835_barrier();
237 1.1 skrll ipl_mask = bcm2835_pic_find_pending_irqs(&bcm2835_pic);
238 1.4.2.1 skrll #if defined(BCM2836)
239 1.4.2.1 skrll ipl_mask |= bcm2836mp_pic_find_pending_irqs(&bcm2836mp_pic);
240 1.4.2.1 skrll #endif
241 1.1 skrll
242 1.1 skrll /*
243 1.1 skrll * Record the pending_ipls and deliver them if we can.
244 1.1 skrll */
245 1.1 skrll if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
246 1.1 skrll pic_do_pending_ints(I32_bit, oldipl, frame);
247 1.1 skrll }
248 1.1 skrll
249 1.1 skrll static void
250 1.1 skrll bcm2835_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
251 1.1 skrll uint32_t irq_mask)
252 1.1 skrll {
253 1.1 skrll
254 1.1 skrll write_bcm2835reg(BCM2835_INTC_ENABLEBASE + (irqbase >> 3), irq_mask);
255 1.1 skrll bcm2835_barrier();
256 1.1 skrll }
257 1.1 skrll
258 1.1 skrll static void
259 1.1 skrll bcm2835_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
260 1.1 skrll uint32_t irq_mask)
261 1.1 skrll {
262 1.1 skrll
263 1.1 skrll write_bcm2835reg(BCM2835_INTC_DISABLEBASE + (irqbase >> 3), irq_mask);
264 1.1 skrll bcm2835_barrier();
265 1.1 skrll }
266 1.1 skrll
267 1.1 skrll /*
268 1.1 skrll * Called with interrupts disabled
269 1.1 skrll */
270 1.1 skrll static int
271 1.1 skrll bcm2835_pic_find_pending_irqs(struct pic_softc *pic)
272 1.1 skrll {
273 1.1 skrll int ipl = 0;
274 1.1 skrll uint32_t bpending, gpu0irq, gpu1irq, armirq;
275 1.1 skrll
276 1.1 skrll bcm2835_barrier();
277 1.1 skrll bpending = read_bcm2835reg(BCM2835_INTC_IRQBPENDING);
278 1.1 skrll if (bpending == 0)
279 1.1 skrll return 0;
280 1.1 skrll
281 1.1 skrll armirq = bpending & BCM2835_INTBIT_ARM;
282 1.1 skrll gpu0irq = bpending & BCM2835_INTBIT_GPU0;
283 1.1 skrll gpu1irq = bpending & BCM2835_INTBIT_GPU1;
284 1.1 skrll
285 1.1 skrll if (armirq) {
286 1.1 skrll ipl |= pic_mark_pending_sources(pic, BCM2835_INT_BASICBASE,
287 1.1 skrll armirq);
288 1.3 skrll
289 1.1 skrll }
290 1.1 skrll
291 1.1 skrll if (gpu0irq || (bpending & BCM2835_INTBIT_PENDING1)) {
292 1.1 skrll uint32_t pending1;
293 1.3 skrll
294 1.1 skrll pending1 = read_bcm2835reg(BCM2835_INTC_IRQ1PENDING);
295 1.1 skrll ipl |= pic_mark_pending_sources(pic, BCM2835_INT_GPU0BASE,
296 1.1 skrll pending1);
297 1.1 skrll }
298 1.1 skrll if (gpu1irq || (bpending & BCM2835_INTBIT_PENDING2)) {
299 1.1 skrll uint32_t pending2;
300 1.3 skrll
301 1.1 skrll pending2 = read_bcm2835reg(BCM2835_INTC_IRQ2PENDING);
302 1.1 skrll ipl |= pic_mark_pending_sources(pic, BCM2835_INT_GPU1BASE,
303 1.1 skrll pending2);
304 1.1 skrll }
305 1.3 skrll
306 1.1 skrll return ipl;
307 1.1 skrll }
308 1.1 skrll
309 1.1 skrll static void
310 1.1 skrll bcm2835_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
311 1.1 skrll {
312 1.1 skrll
313 1.1 skrll /* Nothing really*/
314 1.1 skrll KASSERT(is->is_irq < BCM2835_NIRQ);
315 1.1 skrll KASSERT(is->is_type == IST_LEVEL);
316 1.1 skrll }
317 1.1 skrll
318 1.1 skrll static void
319 1.1 skrll bcm2835_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
320 1.1 skrll {
321 1.1 skrll
322 1.1 skrll strlcpy(buf, bcm2835_sources[irq], len);
323 1.1 skrll }
324 1.4.2.1 skrll
325 1.4.2.1 skrll
326 1.4.2.1 skrll #if defined(BCM2836)
327 1.4.2.1 skrll
328 1.4.2.1 skrll #define BCM2836MP_TIMER_IRQS __BITS(3,0)
329 1.4.2.1 skrll #define BCM2836MP_MAILBOX_IRQS __BITS(4,4)
330 1.4.2.1 skrll
331 1.4.2.1 skrll #define BCM2836MP_ALL_IRQS \
332 1.4.2.1 skrll (BCM2836MP_TIMER_IRQS | BCM2836MP_MAILBOX_IRQS)
333 1.4.2.1 skrll
334 1.4.2.1 skrll static void
335 1.4.2.1 skrll bcm2836mp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
336 1.4.2.1 skrll uint32_t irq_mask)
337 1.4.2.1 skrll {
338 1.4.2.1 skrll const int cpuid = 0;
339 1.4.2.1 skrll
340 1.4.2.1 skrll //printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask);
341 1.4.2.1 skrll
342 1.4.2.1 skrll if (irq_mask & BCM2836MP_TIMER_IRQS) {
343 1.4.2.1 skrll uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
344 1.4.2.1 skrll uint32_t val = bus_space_read_4(al_iot, al_ioh,
345 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
346 1.4.2.1 skrll val |= mask;
347 1.4.2.1 skrll bus_space_write_4(al_iot, al_ioh,
348 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
349 1.4.2.1 skrll val);
350 1.4.2.1 skrll bus_space_barrier(al_iot, al_ioh,
351 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROL_BASE,
352 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROL_SIZE,
353 1.4.2.1 skrll BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
354 1.4.2.1 skrll //printf("%s: val %08x\n", __func__, val);
355 1.4.2.1 skrll } else if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
356 1.4.2.1 skrll uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
357 1.4.2.1 skrll uint32_t val = bus_space_read_4(al_iot, al_ioh,
358 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
359 1.4.2.1 skrll val |= mask;
360 1.4.2.1 skrll bus_space_write_4(al_iot, al_ioh,
361 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
362 1.4.2.1 skrll val);
363 1.4.2.1 skrll bus_space_barrier(al_iot, al_ioh,
364 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_BASE,
365 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROL_SIZE,
366 1.4.2.1 skrll BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
367 1.4.2.1 skrll }
368 1.4.2.1 skrll
369 1.4.2.1 skrll return;
370 1.4.2.1 skrll }
371 1.4.2.1 skrll
372 1.4.2.1 skrll static void
373 1.4.2.1 skrll bcm2836mp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
374 1.4.2.1 skrll uint32_t irq_mask)
375 1.4.2.1 skrll {
376 1.4.2.1 skrll const int cpuid = 0;
377 1.4.2.1 skrll
378 1.4.2.1 skrll //printf("%s: irqbase %zu irq_mask %08x\n", __func__, irqbase, irq_mask);
379 1.4.2.1 skrll if (irq_mask & BCM2836MP_TIMER_IRQS) {
380 1.4.2.1 skrll uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_TIMER_IRQS);
381 1.4.2.1 skrll uint32_t val = bus_space_read_4(al_iot, al_ioh,
382 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid));
383 1.4.2.1 skrll val &= ~mask;
384 1.4.2.1 skrll bus_space_write_4(al_iot, al_ioh,
385 1.4.2.1 skrll BCM2836_LOCAL_TIMER_IRQ_CONTROLN(cpuid),
386 1.4.2.1 skrll val);
387 1.4.2.1 skrll //printf("%s: val %08x\n", __func__, val);
388 1.4.2.1 skrll } else if (irq_mask & BCM2836MP_MAILBOX_IRQS) {
389 1.4.2.1 skrll uint32_t mask = __SHIFTOUT(irq_mask, BCM2836MP_MAILBOX_IRQS);
390 1.4.2.1 skrll uint32_t val = bus_space_read_4(al_iot, al_ioh,
391 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid));
392 1.4.2.1 skrll val &= ~mask;
393 1.4.2.1 skrll bus_space_write_4(al_iot, al_ioh,
394 1.4.2.1 skrll BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid),
395 1.4.2.1 skrll val);
396 1.4.2.1 skrll }
397 1.4.2.1 skrll
398 1.4.2.1 skrll bcm2835_barrier();
399 1.4.2.1 skrll return;
400 1.4.2.1 skrll }
401 1.4.2.1 skrll
402 1.4.2.1 skrll
403 1.4.2.1 skrll static int
404 1.4.2.1 skrll bcm2836mp_pic_find_pending_irqs(struct pic_softc *pic)
405 1.4.2.1 skrll {
406 1.4.2.1 skrll const int cpuid = 0;
407 1.4.2.1 skrll uint32_t lpending;
408 1.4.2.1 skrll int ipl = 0;
409 1.4.2.1 skrll
410 1.4.2.1 skrll bcm2835_barrier();
411 1.4.2.1 skrll
412 1.4.2.1 skrll lpending = bus_space_read_4(al_iot, al_ioh,
413 1.4.2.1 skrll BCM2836_LOCAL_INTC_IRQPENDINGN(cpuid));
414 1.4.2.1 skrll
415 1.4.2.1 skrll lpending &= ~BCM2836_INTBIT_GPUPENDING;
416 1.4.2.1 skrll if (lpending & BCM2836MP_ALL_IRQS) {
417 1.4.2.1 skrll ipl |= pic_mark_pending_sources(pic, 0 /* BCM2836_INT_LOCALBASE */,
418 1.4.2.1 skrll lpending & BCM2836MP_ALL_IRQS);
419 1.4.2.1 skrll }
420 1.4.2.1 skrll
421 1.4.2.1 skrll return ipl;
422 1.4.2.1 skrll }
423 1.4.2.1 skrll
424 1.4.2.1 skrll static void
425 1.4.2.1 skrll bcm2836mp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
426 1.4.2.1 skrll {
427 1.4.2.1 skrll
428 1.4.2.1 skrll /* Nothing really*/
429 1.4.2.1 skrll KASSERT(is->is_irq >= 0);
430 1.4.2.1 skrll KASSERT(is->is_irq < BCM2836MP_NIRQ);
431 1.4.2.1 skrll // KASSERT(is->is_type == IST_LEVEL);
432 1.4.2.1 skrll
433 1.4.2.1 skrll
434 1.4.2.1 skrll }
435 1.4.2.1 skrll
436 1.4.2.1 skrll static void
437 1.4.2.1 skrll bcm2836mp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
438 1.4.2.1 skrll {
439 1.4.2.1 skrll irq %= 32;
440 1.4.2.1 skrll strlcpy(buf, bcm2836mp_sources[irq], len);
441 1.4.2.1 skrll }
442 1.4.2.1 skrll #endif
443