11.5Smsaitoh/*	$NetBSD: npwr_fc_pci.c,v 1.5 2019/01/09 07:49:22 msaitoh Exp $	*/
21.1Sbriggs
31.1Sbriggs/*
41.1Sbriggs * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
51.1Sbriggs * All rights reserved.
61.1Sbriggs *
71.1Sbriggs * Written by Jason R. Thorpe for Wasabi Systems, Inc.
81.1Sbriggs *
91.1Sbriggs * Redistribution and use in source and binary forms, with or without
101.1Sbriggs * modification, are permitted provided that the following conditions
111.1Sbriggs * are met:
121.1Sbriggs * 1. Redistributions of source code must retain the above copyright
131.1Sbriggs *    notice, this list of conditions and the following disclaimer.
141.1Sbriggs * 2. Redistributions in binary form must reproduce the above copyright
151.1Sbriggs *    notice, this list of conditions and the following disclaimer in the
161.1Sbriggs *    documentation and/or other materials provided with the distribution.
171.1Sbriggs * 3. All advertising materials mentioning features or use of this software
181.1Sbriggs *    must display the following acknowledgement:
191.1Sbriggs *	This product includes software developed for the NetBSD Project by
201.1Sbriggs *	Wasabi Systems, Inc.
211.1Sbriggs * 4. The name of Wasabi Systems, Inc. may not be used to endorse
221.1Sbriggs *    or promote products derived from this software without specific prior
231.1Sbriggs *    written permission.
241.1Sbriggs *
251.1Sbriggs * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
261.1Sbriggs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
271.1Sbriggs * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
281.1Sbriggs * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
291.1Sbriggs * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
301.1Sbriggs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
311.1Sbriggs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
321.1Sbriggs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
331.1Sbriggs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
341.1Sbriggs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
351.1Sbriggs * POSSIBILITY OF SUCH DAMAGE.
361.1Sbriggs */
371.1Sbriggs
381.1Sbriggs/*
391.1Sbriggs * IQ80321 PCI interrupt support.
401.1Sbriggs */
411.1Sbriggs
421.1Sbriggs#include <sys/cdefs.h>
431.5Smsaitoh__KERNEL_RCSID(0, "$NetBSD: npwr_fc_pci.c,v 1.5 2019/01/09 07:49:22 msaitoh Exp $");
441.1Sbriggs
451.1Sbriggs#include <sys/param.h>
461.1Sbriggs#include <sys/systm.h>
471.1Sbriggs#include <sys/device.h>
481.1Sbriggs
491.1Sbriggs#include <machine/autoconf.h>
501.3Sdyoung#include <sys/bus.h>
511.1Sbriggs
521.1Sbriggs#include <evbarm/iq80321/iq80321reg.h>
531.1Sbriggs#include <evbarm/iq80321/iq80321var.h>
541.1Sbriggs
551.1Sbriggs#include <arm/xscale/i80321reg.h>
561.1Sbriggs#include <arm/xscale/i80321var.h>
571.1Sbriggs
581.1Sbriggs#include <dev/pci/pcidevs.h>
591.1Sbriggs#include <dev/pci/ppbreg.h>
601.1Sbriggs
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.1Sbriggsconst struct evcnt *iq80321_pci_intr_evcnt(void *, pci_intr_handle_t);
651.1Sbriggsvoid	*iq80321_pci_intr_establish(void *, pci_intr_handle_t,
661.5Smsaitoh    int, int (*func)(void *), void *, const char *);
671.1Sbriggsvoid	iq80321_pci_intr_disestablish(void *, void *);
681.1Sbriggs
691.1Sbriggsvoid
701.1Sbriggsiq80321_pci_init(pci_chipset_tag_t pc, void *cookie)
711.1Sbriggs{
721.1Sbriggs
731.1Sbriggs	pc->pc_intr_v = cookie;		/* the i80321 softc */
741.1Sbriggs	pc->pc_intr_map = iq80321_pci_intr_map;
751.1Sbriggs	pc->pc_intr_string = iq80321_pci_intr_string;
761.1Sbriggs	pc->pc_intr_evcnt = iq80321_pci_intr_evcnt;
771.1Sbriggs	pc->pc_intr_establish = iq80321_pci_intr_establish;
781.1Sbriggs	pc->pc_intr_disestablish = iq80321_pci_intr_disestablish;
791.1Sbriggs}
801.1Sbriggs
811.1Sbriggsint
821.2Sdyoungiq80321_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
831.1Sbriggs{
841.1Sbriggs	struct i80321_softc *sc = pa->pa_pc->pc_intr_v;
851.1Sbriggs	int b, d, f;
861.1Sbriggs	uint32_t busno;
871.1Sbriggs
881.1Sbriggs	/*
891.1Sbriggs	 * The IQ80321's interrupts are routed like so:
901.1Sbriggs	 *
911.1Sbriggs	 *	XINT0	i82544 Gig-E
921.1Sbriggs	 *
931.1Sbriggs	 *	XINT1	UART
941.1Sbriggs	 *
951.1Sbriggs	 *	XINT2	INTA# from S-PCI-X slot
961.1Sbriggs	 *
971.1Sbriggs	 *	XINT3	INTB# from S-PCI-X slot
981.1Sbriggs	 */
991.1Sbriggs
1001.1Sbriggs	busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
1011.1Sbriggs	busno = PCIXSR_BUSNO(busno);
1021.1Sbriggs	if (busno == 0xff)
1031.1Sbriggs		busno = 0;
1041.1Sbriggs
1051.1Sbriggs	pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &b, &d, &f);
1061.1Sbriggs
1071.1Sbriggs	/* No mappings for devices not on our bus. */
1081.1Sbriggs	if (b != busno)
1091.1Sbriggs		goto no_mapping;
1101.1Sbriggs
1111.1Sbriggs	switch (d) {
1121.1Sbriggs	case 0:			/* i82546 Dual Gig-E */
1131.1Sbriggs		if (pa->pa_intrpin == 1) {
1141.1Sbriggs			*ihp = ICU_INT_XINT(0);
1151.1Sbriggs			return (0);
1161.1Sbriggs		}
1171.1Sbriggs		if (pa->pa_intrpin == 2) {
1181.1Sbriggs			*ihp = ICU_INT_XINT(1);
1191.1Sbriggs			return (0);
1201.1Sbriggs		}
1211.1Sbriggs		goto no_mapping;
1221.1Sbriggs
1231.1Sbriggs	case 1:			/* i31244 SATA */
1241.1Sbriggs		if (pa->pa_intrpin == 1) {
1251.1Sbriggs			*ihp = ICU_INT_XINT(2);
1261.1Sbriggs			return (0);
1271.1Sbriggs		}
1281.1Sbriggs		goto no_mapping;
1291.1Sbriggs
1301.1Sbriggs	case 2:			/* LSI Fibre */
1311.1Sbriggs		if (pa->pa_intrpin == 1) {
1321.1Sbriggs			*ihp = ICU_INT_XINT(3);
1331.1Sbriggs			return (0);
1341.1Sbriggs		}
1351.1Sbriggs		goto no_mapping;
1361.1Sbriggs
1371.1Sbriggs	default:
1381.1Sbriggs no_mapping:
1391.1Sbriggs		printf("iq80321_pci_intr_map: no mapping for %d/%d/%d\n",
1401.1Sbriggs		    pa->pa_bus, pa->pa_device, pa->pa_function);
1411.1Sbriggs		return (1);
1421.1Sbriggs	}
1431.1Sbriggs
1441.1Sbriggs	return (0);
1451.1Sbriggs}
1461.1Sbriggs
1471.1Sbriggsconst char *
1481.4Schristosiq80321_pci_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
1491.1Sbriggs{
1501.1Sbriggs
1511.4Schristos	strlcpy(buf, i80321_irqnames[ih], len);
1521.4Schristos	return buf;
1531.1Sbriggs}
1541.1Sbriggs
1551.1Sbriggsconst struct evcnt *
1561.1Sbriggsiq80321_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
1571.1Sbriggs{
1581.1Sbriggs
1591.1Sbriggs	/* XXX For now. */
1601.1Sbriggs	return (NULL);
1611.1Sbriggs}
1621.1Sbriggs
1631.1Sbriggsvoid *
1641.1Sbriggsiq80321_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
1651.5Smsaitoh    int (*func)(void *), void *arg, const char *xname)
1661.1Sbriggs{
1671.1Sbriggs
1681.1Sbriggs	return (i80321_intr_establish(ih, ipl, func, arg));
1691.1Sbriggs}
1701.1Sbriggs
1711.1Sbriggsvoid
1721.1Sbriggsiq80321_pci_intr_disestablish(void *v, void *cookie)
1731.1Sbriggs{
1741.1Sbriggs
1751.1Sbriggs	i80321_intr_disestablish(cookie);
1761.1Sbriggs}
177