Home | History | Annotate | Line # | Download | only in broadcom
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