1*df756a77Smsaitoh /* $NetBSD: npwr_fc_pci.c,v 1.5 2019/01/09 07:49:22 msaitoh Exp $ */
223dfb2cdSbriggs
323dfb2cdSbriggs /*
423dfb2cdSbriggs * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
523dfb2cdSbriggs * All rights reserved.
623dfb2cdSbriggs *
723dfb2cdSbriggs * Written by Jason R. Thorpe for Wasabi Systems, Inc.
823dfb2cdSbriggs *
923dfb2cdSbriggs * Redistribution and use in source and binary forms, with or without
1023dfb2cdSbriggs * modification, are permitted provided that the following conditions
1123dfb2cdSbriggs * are met:
1223dfb2cdSbriggs * 1. Redistributions of source code must retain the above copyright
1323dfb2cdSbriggs * notice, this list of conditions and the following disclaimer.
1423dfb2cdSbriggs * 2. Redistributions in binary form must reproduce the above copyright
1523dfb2cdSbriggs * notice, this list of conditions and the following disclaimer in the
1623dfb2cdSbriggs * documentation and/or other materials provided with the distribution.
1723dfb2cdSbriggs * 3. All advertising materials mentioning features or use of this software
1823dfb2cdSbriggs * must display the following acknowledgement:
1923dfb2cdSbriggs * This product includes software developed for the NetBSD Project by
2023dfb2cdSbriggs * Wasabi Systems, Inc.
2123dfb2cdSbriggs * 4. The name of Wasabi Systems, Inc. may not be used to endorse
2223dfb2cdSbriggs * or promote products derived from this software without specific prior
2323dfb2cdSbriggs * written permission.
2423dfb2cdSbriggs *
2523dfb2cdSbriggs * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
2623dfb2cdSbriggs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2723dfb2cdSbriggs * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2823dfb2cdSbriggs * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
2923dfb2cdSbriggs * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3023dfb2cdSbriggs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3123dfb2cdSbriggs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3223dfb2cdSbriggs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3323dfb2cdSbriggs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3423dfb2cdSbriggs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3523dfb2cdSbriggs * POSSIBILITY OF SUCH DAMAGE.
3623dfb2cdSbriggs */
3723dfb2cdSbriggs
3823dfb2cdSbriggs /*
3923dfb2cdSbriggs * IQ80321 PCI interrupt support.
4023dfb2cdSbriggs */
4123dfb2cdSbriggs
4223dfb2cdSbriggs #include <sys/cdefs.h>
43*df756a77Smsaitoh __KERNEL_RCSID(0, "$NetBSD: npwr_fc_pci.c,v 1.5 2019/01/09 07:49:22 msaitoh Exp $");
4423dfb2cdSbriggs
4523dfb2cdSbriggs #include <sys/param.h>
4623dfb2cdSbriggs #include <sys/systm.h>
4723dfb2cdSbriggs #include <sys/device.h>
4823dfb2cdSbriggs
4923dfb2cdSbriggs #include <machine/autoconf.h>
50fea15f47Sdyoung #include <sys/bus.h>
5123dfb2cdSbriggs
5223dfb2cdSbriggs #include <evbarm/iq80321/iq80321reg.h>
5323dfb2cdSbriggs #include <evbarm/iq80321/iq80321var.h>
5423dfb2cdSbriggs
5523dfb2cdSbriggs #include <arm/xscale/i80321reg.h>
5623dfb2cdSbriggs #include <arm/xscale/i80321var.h>
5723dfb2cdSbriggs
5823dfb2cdSbriggs #include <dev/pci/pcidevs.h>
5923dfb2cdSbriggs #include <dev/pci/ppbreg.h>
6023dfb2cdSbriggs
61d3e53912Sdyoung int iq80321_pci_intr_map(const struct pci_attach_args *,
62d3e53912Sdyoung pci_intr_handle_t *);
63e58a356cSchristos const char *iq80321_pci_intr_string(void *, pci_intr_handle_t, char *, size_t);
6423dfb2cdSbriggs const struct evcnt *iq80321_pci_intr_evcnt(void *, pci_intr_handle_t);
6523dfb2cdSbriggs void *iq80321_pci_intr_establish(void *, pci_intr_handle_t,
66*df756a77Smsaitoh int, int (*func)(void *), void *, const char *);
6723dfb2cdSbriggs void iq80321_pci_intr_disestablish(void *, void *);
6823dfb2cdSbriggs
6923dfb2cdSbriggs void
iq80321_pci_init(pci_chipset_tag_t pc,void * cookie)7023dfb2cdSbriggs iq80321_pci_init(pci_chipset_tag_t pc, void *cookie)
7123dfb2cdSbriggs {
7223dfb2cdSbriggs
7323dfb2cdSbriggs pc->pc_intr_v = cookie; /* the i80321 softc */
7423dfb2cdSbriggs pc->pc_intr_map = iq80321_pci_intr_map;
7523dfb2cdSbriggs pc->pc_intr_string = iq80321_pci_intr_string;
7623dfb2cdSbriggs pc->pc_intr_evcnt = iq80321_pci_intr_evcnt;
7723dfb2cdSbriggs pc->pc_intr_establish = iq80321_pci_intr_establish;
7823dfb2cdSbriggs pc->pc_intr_disestablish = iq80321_pci_intr_disestablish;
7923dfb2cdSbriggs }
8023dfb2cdSbriggs
8123dfb2cdSbriggs int
iq80321_pci_intr_map(const struct pci_attach_args * pa,pci_intr_handle_t * ihp)82d3e53912Sdyoung iq80321_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
8323dfb2cdSbriggs {
8423dfb2cdSbriggs struct i80321_softc *sc = pa->pa_pc->pc_intr_v;
8523dfb2cdSbriggs int b, d, f;
8623dfb2cdSbriggs uint32_t busno;
8723dfb2cdSbriggs
8823dfb2cdSbriggs /*
8923dfb2cdSbriggs * The IQ80321's interrupts are routed like so:
9023dfb2cdSbriggs *
9123dfb2cdSbriggs * XINT0 i82544 Gig-E
9223dfb2cdSbriggs *
9323dfb2cdSbriggs * XINT1 UART
9423dfb2cdSbriggs *
9523dfb2cdSbriggs * XINT2 INTA# from S-PCI-X slot
9623dfb2cdSbriggs *
9723dfb2cdSbriggs * XINT3 INTB# from S-PCI-X slot
9823dfb2cdSbriggs */
9923dfb2cdSbriggs
10023dfb2cdSbriggs busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
10123dfb2cdSbriggs busno = PCIXSR_BUSNO(busno);
10223dfb2cdSbriggs if (busno == 0xff)
10323dfb2cdSbriggs busno = 0;
10423dfb2cdSbriggs
10523dfb2cdSbriggs pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &b, &d, &f);
10623dfb2cdSbriggs
10723dfb2cdSbriggs /* No mappings for devices not on our bus. */
10823dfb2cdSbriggs if (b != busno)
10923dfb2cdSbriggs goto no_mapping;
11023dfb2cdSbriggs
11123dfb2cdSbriggs switch (d) {
11223dfb2cdSbriggs case 0: /* i82546 Dual Gig-E */
11323dfb2cdSbriggs if (pa->pa_intrpin == 1) {
11423dfb2cdSbriggs *ihp = ICU_INT_XINT(0);
11523dfb2cdSbriggs return (0);
11623dfb2cdSbriggs }
11723dfb2cdSbriggs if (pa->pa_intrpin == 2) {
11823dfb2cdSbriggs *ihp = ICU_INT_XINT(1);
11923dfb2cdSbriggs return (0);
12023dfb2cdSbriggs }
12123dfb2cdSbriggs goto no_mapping;
12223dfb2cdSbriggs
12323dfb2cdSbriggs case 1: /* i31244 SATA */
12423dfb2cdSbriggs if (pa->pa_intrpin == 1) {
12523dfb2cdSbriggs *ihp = ICU_INT_XINT(2);
12623dfb2cdSbriggs return (0);
12723dfb2cdSbriggs }
12823dfb2cdSbriggs goto no_mapping;
12923dfb2cdSbriggs
13023dfb2cdSbriggs case 2: /* LSI Fibre */
13123dfb2cdSbriggs if (pa->pa_intrpin == 1) {
13223dfb2cdSbriggs *ihp = ICU_INT_XINT(3);
13323dfb2cdSbriggs return (0);
13423dfb2cdSbriggs }
13523dfb2cdSbriggs goto no_mapping;
13623dfb2cdSbriggs
13723dfb2cdSbriggs default:
13823dfb2cdSbriggs no_mapping:
13923dfb2cdSbriggs printf("iq80321_pci_intr_map: no mapping for %d/%d/%d\n",
14023dfb2cdSbriggs pa->pa_bus, pa->pa_device, pa->pa_function);
14123dfb2cdSbriggs return (1);
14223dfb2cdSbriggs }
14323dfb2cdSbriggs
14423dfb2cdSbriggs return (0);
14523dfb2cdSbriggs }
14623dfb2cdSbriggs
14723dfb2cdSbriggs const char *
iq80321_pci_intr_string(void * v,pci_intr_handle_t ih,char * buf,size_t len)148e58a356cSchristos iq80321_pci_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
14923dfb2cdSbriggs {
15023dfb2cdSbriggs
151e58a356cSchristos strlcpy(buf, i80321_irqnames[ih], len);
152e58a356cSchristos return buf;
15323dfb2cdSbriggs }
15423dfb2cdSbriggs
15523dfb2cdSbriggs const struct evcnt *
iq80321_pci_intr_evcnt(void * v,pci_intr_handle_t ih)15623dfb2cdSbriggs iq80321_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
15723dfb2cdSbriggs {
15823dfb2cdSbriggs
15923dfb2cdSbriggs /* XXX For now. */
16023dfb2cdSbriggs return (NULL);
16123dfb2cdSbriggs }
16223dfb2cdSbriggs
16323dfb2cdSbriggs void *
iq80321_pci_intr_establish(void * v,pci_intr_handle_t ih,int ipl,int (* func)(void *),void * arg,const char * xname)16423dfb2cdSbriggs iq80321_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
165*df756a77Smsaitoh int (*func)(void *), void *arg, const char *xname)
16623dfb2cdSbriggs {
16723dfb2cdSbriggs
16823dfb2cdSbriggs return (i80321_intr_establish(ih, ipl, func, arg));
16923dfb2cdSbriggs }
17023dfb2cdSbriggs
17123dfb2cdSbriggs void
iq80321_pci_intr_disestablish(void * v,void * cookie)17223dfb2cdSbriggs iq80321_pci_intr_disestablish(void *v, void *cookie)
17323dfb2cdSbriggs {
17423dfb2cdSbriggs
17523dfb2cdSbriggs i80321_intr_disestablish(cookie);
17623dfb2cdSbriggs }
177