xref: /netbsd/sys/arch/evbarm/iq31244/iq31244_pci.c (revision 0f2ccb3a)
1*0f2ccb3aSmsaitoh /*	$NetBSD: iq31244_pci.c,v 1.7 2019/01/09 07:49:22 msaitoh Exp $	*/
25b9c2e62Sthorpej 
35b9c2e62Sthorpej /*
45b9c2e62Sthorpej  * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
55b9c2e62Sthorpej  * All rights reserved.
65b9c2e62Sthorpej  *
75b9c2e62Sthorpej  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
85b9c2e62Sthorpej  *
95b9c2e62Sthorpej  * Redistribution and use in source and binary forms, with or without
105b9c2e62Sthorpej  * modification, are permitted provided that the following conditions
115b9c2e62Sthorpej  * are met:
125b9c2e62Sthorpej  * 1. Redistributions of source code must retain the above copyright
135b9c2e62Sthorpej  *    notice, this list of conditions and the following disclaimer.
145b9c2e62Sthorpej  * 2. Redistributions in binary form must reproduce the above copyright
155b9c2e62Sthorpej  *    notice, this list of conditions and the following disclaimer in the
165b9c2e62Sthorpej  *    documentation and/or other materials provided with the distribution.
175b9c2e62Sthorpej  * 3. All advertising materials mentioning features or use of this software
185b9c2e62Sthorpej  *    must display the following acknowledgement:
195b9c2e62Sthorpej  *	This product includes software developed for the NetBSD Project by
205b9c2e62Sthorpej  *	Wasabi Systems, Inc.
215b9c2e62Sthorpej  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
225b9c2e62Sthorpej  *    or promote products derived from this software without specific prior
235b9c2e62Sthorpej  *    written permission.
245b9c2e62Sthorpej  *
255b9c2e62Sthorpej  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
265b9c2e62Sthorpej  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
275b9c2e62Sthorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
285b9c2e62Sthorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
295b9c2e62Sthorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
305b9c2e62Sthorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
315b9c2e62Sthorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
325b9c2e62Sthorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
335b9c2e62Sthorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
345b9c2e62Sthorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
355b9c2e62Sthorpej  * POSSIBILITY OF SUCH DAMAGE.
365b9c2e62Sthorpej  */
375b9c2e62Sthorpej 
385b9c2e62Sthorpej /*
395b9c2e62Sthorpej  * IQ31244 PCI interrupt support.
405b9c2e62Sthorpej  */
415b9c2e62Sthorpej 
4208716eaeSlukem #include <sys/cdefs.h>
43*0f2ccb3aSmsaitoh __KERNEL_RCSID(0, "$NetBSD: iq31244_pci.c,v 1.7 2019/01/09 07:49:22 msaitoh Exp $");
4408716eaeSlukem 
455b9c2e62Sthorpej #include <sys/param.h>
465b9c2e62Sthorpej #include <sys/systm.h>
475b9c2e62Sthorpej #include <sys/device.h>
485b9c2e62Sthorpej 
495b9c2e62Sthorpej #include <machine/autoconf.h>
50f30521d0Sdyoung #include <sys/bus.h>
515b9c2e62Sthorpej 
525b9c2e62Sthorpej #include <evbarm/iq80321/iq80321reg.h>
535b9c2e62Sthorpej #include <evbarm/iq80321/iq80321var.h>
545b9c2e62Sthorpej 
555b9c2e62Sthorpej #include <arm/xscale/i80321reg.h>
565b9c2e62Sthorpej #include <arm/xscale/i80321var.h>
575b9c2e62Sthorpej 
585b9c2e62Sthorpej #include <dev/pci/pcidevs.h>
595b9c2e62Sthorpej #include <dev/pci/ppbreg.h>
605b9c2e62Sthorpej 
61dd3ec23bSdyoung int	iq80321_pci_intr_map(const struct pci_attach_args *,
62dd3ec23bSdyoung 	    pci_intr_handle_t *);
63b8930f84Schristos const char *iq80321_pci_intr_string(void *, pci_intr_handle_t, char *, size_t);
645b9c2e62Sthorpej const struct evcnt *iq80321_pci_intr_evcnt(void *, pci_intr_handle_t);
655b9c2e62Sthorpej void	*iq80321_pci_intr_establish(void *, pci_intr_handle_t,
66*0f2ccb3aSmsaitoh     int, int (*func)(void *), void *, const char *);
675b9c2e62Sthorpej void	iq80321_pci_intr_disestablish(void *, void *);
685b9c2e62Sthorpej 
695b9c2e62Sthorpej void
iq80321_pci_init(pci_chipset_tag_t pc,void * cookie)705b9c2e62Sthorpej iq80321_pci_init(pci_chipset_tag_t pc, void *cookie)
715b9c2e62Sthorpej {
725b9c2e62Sthorpej 
735b9c2e62Sthorpej 	pc->pc_intr_v = cookie;		/* the i80321 softc */
745b9c2e62Sthorpej 	pc->pc_intr_map = iq80321_pci_intr_map;
755b9c2e62Sthorpej 	pc->pc_intr_string = iq80321_pci_intr_string;
765b9c2e62Sthorpej 	pc->pc_intr_evcnt = iq80321_pci_intr_evcnt;
775b9c2e62Sthorpej 	pc->pc_intr_establish = iq80321_pci_intr_establish;
785b9c2e62Sthorpej 	pc->pc_intr_disestablish = iq80321_pci_intr_disestablish;
795b9c2e62Sthorpej }
805b9c2e62Sthorpej 
815b9c2e62Sthorpej int
iq80321_pci_intr_map(const struct pci_attach_args * pa,pci_intr_handle_t * ihp)82dd3ec23bSdyoung iq80321_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
835b9c2e62Sthorpej {
845b9c2e62Sthorpej 	struct i80321_softc *sc = pa->pa_pc->pc_intr_v;
855b9c2e62Sthorpej 	int b, d, f;
865b9c2e62Sthorpej 	uint32_t busno;
875b9c2e62Sthorpej 
885b9c2e62Sthorpej 	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
895b9c2e62Sthorpej 	busno = PCIXSR_BUSNO(busno);
905b9c2e62Sthorpej 	if (busno == 0xff)
915b9c2e62Sthorpej 		busno = 0;
925b9c2e62Sthorpej 
935b9c2e62Sthorpej 	pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &b, &d, &f);
945b9c2e62Sthorpej 
955b9c2e62Sthorpej 	/* No mappings for devices not on our bus. */
965b9c2e62Sthorpej 	if (b != busno)
975b9c2e62Sthorpej 		goto no_mapping;
985b9c2e62Sthorpej 
995b9c2e62Sthorpej 	switch (d) {
1005b9c2e62Sthorpej 	case 1:			/* PCIX-PCIX bridge */
1015b9c2e62Sthorpej 		/*
1025b9c2e62Sthorpej 		 * The S-ATA chips are behind the bridge, and all of
1035b9c2e62Sthorpej 		 * the S-ATA interrupts are wired together.
1045b9c2e62Sthorpej 		 */
1055b9c2e62Sthorpej 		*ihp = ICU_INT_XINT(2);
1065b9c2e62Sthorpej 		return (0);
1075b9c2e62Sthorpej 
1085b9c2e62Sthorpej 	case 2:			/* PCI slot */
1095b9c2e62Sthorpej 		/* All pins are wired together. */
1105b9c2e62Sthorpej 		*ihp = ICU_INT_XINT(3);
1115b9c2e62Sthorpej 		return (0);
1125b9c2e62Sthorpej 
1135b9c2e62Sthorpej 	case 3:			/* i82546 dual Gig-E */
1145b9c2e62Sthorpej 		if (pa->pa_intrpin == 1 || pa->pa_intrpin == 2) {
1155b9c2e62Sthorpej 			*ihp = ICU_INT_XINT(0);
1165b9c2e62Sthorpej 			return (0);
1175b9c2e62Sthorpej 		}
1185b9c2e62Sthorpej 		goto no_mapping;
1195b9c2e62Sthorpej 
1205b9c2e62Sthorpej 	default:
1215b9c2e62Sthorpej  no_mapping:
1225b9c2e62Sthorpej 		printf("iq80321_pci_intr_map: no mapping for %d/%d/%d/%c\n",
1235b9c2e62Sthorpej 		    pa->pa_bus, pa->pa_device, pa->pa_function,
1245b9c2e62Sthorpej 		    '@' + pa->pa_intrpin);
1255b9c2e62Sthorpej 		return (1);
1265b9c2e62Sthorpej 	}
1275b9c2e62Sthorpej 
1285b9c2e62Sthorpej 	return (0);
1295b9c2e62Sthorpej }
1305b9c2e62Sthorpej 
1315b9c2e62Sthorpej const char *
iq80321_pci_intr_string(void * v,pci_intr_handle_t ih,char * buf,size_t len)132b8930f84Schristos iq80321_pci_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
1335b9c2e62Sthorpej {
1345b9c2e62Sthorpej 
135b8930f84Schristos 	strlcpy(buf, i80321_irqnames[ih], len);
136b8930f84Schristos 	return buf;
1375b9c2e62Sthorpej }
1385b9c2e62Sthorpej 
1395b9c2e62Sthorpej const struct evcnt *
iq80321_pci_intr_evcnt(void * v,pci_intr_handle_t ih)1405b9c2e62Sthorpej iq80321_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
1415b9c2e62Sthorpej {
1425b9c2e62Sthorpej 
1435b9c2e62Sthorpej 	/* XXX For now. */
1445b9c2e62Sthorpej 	return (NULL);
1455b9c2e62Sthorpej }
1465b9c2e62Sthorpej 
1475b9c2e62Sthorpej void *
iq80321_pci_intr_establish(void * v,pci_intr_handle_t ih,int ipl,int (* func)(void *),void * arg,const char * xname)1485b9c2e62Sthorpej iq80321_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
149*0f2ccb3aSmsaitoh     int (*func)(void *), void *arg, const char *xname)
1505b9c2e62Sthorpej {
1515b9c2e62Sthorpej 
1525b9c2e62Sthorpej 	return (i80321_intr_establish(ih, ipl, func, arg));
1535b9c2e62Sthorpej }
1545b9c2e62Sthorpej 
1555b9c2e62Sthorpej void
iq80321_pci_intr_disestablish(void * v,void * cookie)1565b9c2e62Sthorpej iq80321_pci_intr_disestablish(void *v, void *cookie)
1575b9c2e62Sthorpej {
1585b9c2e62Sthorpej 
1595b9c2e62Sthorpej 	i80321_intr_disestablish(cookie);
1605b9c2e62Sthorpej }
161