11.5Sjmcneill/*	$NetBSD: cp3100_pci.c,v 1.5 2018/11/16 15:06:23 jmcneill Exp $	*/
21.1Sscw
31.1Sscw/*
41.1Sscw * Copyright 2006 Wasabi Systems, Inc.
51.1Sscw * All rights reserved.
61.1Sscw *
71.1Sscw * Written by Steve C. Woodford for Wasabi Systems, Inc.
81.1Sscw *
91.1Sscw * Redistribution and use in source and binary forms, with or without
101.1Sscw * modification, are permitted provided that the following conditions
111.1Sscw * are met:
121.1Sscw * 1. Redistributions of source code must retain the above copyright
131.1Sscw *    notice, this list of conditions and the following disclaimer.
141.1Sscw * 2. Redistributions in binary form must reproduce the above copyright
151.1Sscw *    notice, this list of conditions and the following disclaimer in the
161.1Sscw *    documentation and/or other materials provided with the distribution.
171.1Sscw * 3. All advertising materials mentioning features or use of this software
181.1Sscw *    must display the following acknowledgement:
191.1Sscw *      This product includes software developed for the NetBSD Project by
201.1Sscw *      Wasabi Systems, Inc.
211.1Sscw * 4. The name of Wasabi Systems, Inc. may not be used to endorse
221.1Sscw *    or promote products derived from this software without specific prior
231.1Sscw *    written permission.
241.1Sscw *
251.1Sscw * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
261.1Sscw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
271.1Sscw * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
281.1Sscw * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
291.1Sscw * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
301.1Sscw * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
311.1Sscw * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
321.1Sscw * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
331.1Sscw * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
341.1Sscw * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
351.1Sscw * POSSIBILITY OF SUCH DAMAGE.
361.1Sscw */
371.1Sscw
381.1Sscw/*
391.1Sscw * CP3100 PCI interrupt support.
401.1Sscw */
411.1Sscw
421.1Sscw#include <sys/cdefs.h>
431.5Sjmcneill__KERNEL_RCSID(0, "$NetBSD: cp3100_pci.c,v 1.5 2018/11/16 15:06:23 jmcneill Exp $");
441.1Sscw
451.1Sscw#include <sys/param.h>
461.1Sscw#include <sys/systm.h>
471.1Sscw#include <sys/device.h>
481.1Sscw
491.1Sscw#include <machine/autoconf.h>
501.3Sdyoung#include <sys/bus.h>
511.1Sscw
521.1Sscw#include <evbarm/iq80321/iq80321reg.h>
531.1Sscw#include <evbarm/iq80321/iq80321var.h>
541.1Sscw
551.1Sscw#include <arm/xscale/i80321reg.h>
561.1Sscw#include <arm/xscale/i80321var.h>
571.1Sscw
581.1Sscw#include <dev/pci/pcidevs.h>
591.1Sscw#include <dev/pci/ppbreg.h>
601.1Sscw
611.2Sdyoungint	iq80321_pci_intr_map(const struct pci_attach_args *,
621.2Sdyoung	    pci_intr_handle_t *);
631.4Schristosconst char *iq80321_pci_intr_string(void *, pci_intr_handle_t, char *, size_t);
641.1Sscwconst struct evcnt *iq80321_pci_intr_evcnt(void *, pci_intr_handle_t);
651.1Sscwvoid	*iq80321_pci_intr_establish(void *, pci_intr_handle_t,
661.5Sjmcneill	    int, int (*func)(void *), void *, const char *);
671.1Sscwvoid	iq80321_pci_intr_disestablish(void *, void *);
681.1Sscw
691.1Sscwvoid
701.1Sscwiq80321_pci_init(pci_chipset_tag_t pc, void *cookie)
711.1Sscw{
721.1Sscw
731.1Sscw	pc->pc_intr_v = cookie;		/* the i80321 softc */
741.1Sscw	pc->pc_intr_map = iq80321_pci_intr_map;
751.1Sscw	pc->pc_intr_string = iq80321_pci_intr_string;
761.1Sscw	pc->pc_intr_evcnt = iq80321_pci_intr_evcnt;
771.1Sscw	pc->pc_intr_establish = iq80321_pci_intr_establish;
781.1Sscw	pc->pc_intr_disestablish = iq80321_pci_intr_disestablish;
791.1Sscw}
801.1Sscw
811.1Sscwint
821.2Sdyoungiq80321_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
831.1Sscw{
841.1Sscw	struct i80321_softc *sc = pa->pa_pc->pc_intr_v;
851.1Sscw	int b, d, f;
861.1Sscw	uint32_t busno;
871.1Sscw
881.1Sscw	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
891.1Sscw	busno = PCIXSR_BUSNO(busno);
901.1Sscw	if (busno == 0xff)
911.1Sscw		busno = 0;
921.1Sscw
931.1Sscw	pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &b, &d, &f);
941.1Sscw
951.1Sscw	/* No mappings for devices not on our bus. */
961.1Sscw	if (b != busno)
971.1Sscw		goto no_mapping;
981.1Sscw
991.1Sscw	switch (d) {
1001.1Sscw	case 0:			/* i82546EB Dual GigE */
1011.1Sscw		/*
1021.1Sscw		 * This is a dual-function chip which uses INTA and INTB,
1031.1Sscw		 * connected to XINT0 and XINT1 respectively.
1041.1Sscw		 */
1051.1Sscw		if (f != 0 && f != 1)
1061.1Sscw			goto no_mapping;
1071.1Sscw		*ihp = ICU_INT_XINT(f);
1081.1Sscw		return (0);
1091.1Sscw
1101.1Sscw	case 1:			/* i31244 S-ATA Interface */
1111.1Sscw		*ihp = ICU_INT_XINT(2);
1121.1Sscw		return (0);
1131.1Sscw
1141.1Sscw	case 2:			/* Symbios Logic 53c1010 SCSI Controllers */
1151.1Sscw	case 3:
1161.1Sscw		/*
1171.1Sscw		 * Both controllers share a single pin
1181.1Sscw		 */
1191.1Sscw		*ihp = ICU_INT_XINT(3);
1201.1Sscw		return (0);
1211.1Sscw
1221.1Sscw	default:
1231.1Sscw no_mapping:
1241.1Sscw		printf("iq80321_pci_intr_map: no mapping for %d/%d/%d/%c\n",
1251.1Sscw		    pa->pa_bus, pa->pa_device, pa->pa_function,
1261.1Sscw		    '@' + pa->pa_intrpin);
1271.1Sscw		return (1);
1281.1Sscw	}
1291.1Sscw
1301.1Sscw	return (0);
1311.1Sscw}
1321.1Sscw
1331.1Sscwconst char *
1341.4Schristosiq80321_pci_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
1351.1Sscw{
1361.1Sscw
1371.4Schristos	strlcpy(buf, i80321_irqnames[ih], len);
1381.4Schristos	return buf;
1391.1Sscw}
1401.1Sscw
1411.1Sscwconst struct evcnt *
1421.1Sscwiq80321_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
1431.1Sscw{
1441.1Sscw
1451.1Sscw	/* XXX For now. */
1461.1Sscw	return (NULL);
1471.1Sscw}
1481.1Sscw
1491.1Sscwvoid *
1501.1Sscwiq80321_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
1511.5Sjmcneill    int (*func)(void *), void *arg, const char *xname)
1521.1Sscw{
1531.1Sscw
1541.1Sscw	return (i80321_intr_establish(ih, ipl, func, arg));
1551.1Sscw}
1561.1Sscw
1571.1Sscwvoid
1581.1Sscwiq80321_pci_intr_disestablish(void *v, void *cookie)
1591.1Sscw{
1601.1Sscw
1611.1Sscw	i80321_intr_disestablish(cookie);
1621.1Sscw}
163