xref: /netbsd-src/sys/arch/evbarm/npwr_fc/npwr_fc_pci.c (revision df756a7782da06ad88fafbf32cf45b9f6d38610f)
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