1*cce19cc2Sjmcneill /* $NetBSD: iq80321_pci.c,v 1.10 2018/11/16 15:06:23 jmcneill Exp $ */
2592e882aSthorpej
3592e882aSthorpej /*
4592e882aSthorpej * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5592e882aSthorpej * All rights reserved.
6592e882aSthorpej *
7592e882aSthorpej * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8592e882aSthorpej *
9592e882aSthorpej * Redistribution and use in source and binary forms, with or without
10592e882aSthorpej * modification, are permitted provided that the following conditions
11592e882aSthorpej * are met:
12592e882aSthorpej * 1. Redistributions of source code must retain the above copyright
13592e882aSthorpej * notice, this list of conditions and the following disclaimer.
14592e882aSthorpej * 2. Redistributions in binary form must reproduce the above copyright
15592e882aSthorpej * notice, this list of conditions and the following disclaimer in the
16592e882aSthorpej * documentation and/or other materials provided with the distribution.
17592e882aSthorpej * 3. All advertising materials mentioning features or use of this software
18592e882aSthorpej * must display the following acknowledgement:
19592e882aSthorpej * This product includes software developed for the NetBSD Project by
20592e882aSthorpej * Wasabi Systems, Inc.
21592e882aSthorpej * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22592e882aSthorpej * or promote products derived from this software without specific prior
23592e882aSthorpej * written permission.
24592e882aSthorpej *
25592e882aSthorpej * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26592e882aSthorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27592e882aSthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28592e882aSthorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29592e882aSthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30592e882aSthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31592e882aSthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32592e882aSthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33592e882aSthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34592e882aSthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35592e882aSthorpej * POSSIBILITY OF SUCH DAMAGE.
36592e882aSthorpej */
37592e882aSthorpej
38592e882aSthorpej /*
39592e882aSthorpej * IQ80321 PCI interrupt support.
40592e882aSthorpej */
41592e882aSthorpej
4208716eaeSlukem #include <sys/cdefs.h>
43*cce19cc2Sjmcneill __KERNEL_RCSID(0, "$NetBSD: iq80321_pci.c,v 1.10 2018/11/16 15:06:23 jmcneill Exp $");
4408716eaeSlukem
45592e882aSthorpej #include <sys/param.h>
46592e882aSthorpej #include <sys/systm.h>
47592e882aSthorpej #include <sys/device.h>
48213e0bd3Smatt #include <sys/bus.h>
49213e0bd3Smatt
50213e0bd3Smatt #include <dev/pci/pcidevs.h>
51213e0bd3Smatt #include <dev/pci/ppbreg.h>
52213e0bd3Smatt
53213e0bd3Smatt #include <arm/locore.h>
54592e882aSthorpej
55592e882aSthorpej #include <machine/autoconf.h>
56592e882aSthorpej
57592e882aSthorpej #include <evbarm/iq80321/iq80321reg.h>
58592e882aSthorpej #include <evbarm/iq80321/iq80321var.h>
59592e882aSthorpej
60592e882aSthorpej #include <arm/xscale/i80321reg.h>
61592e882aSthorpej #include <arm/xscale/i80321var.h>
62592e882aSthorpej
63a184f1f4Sdyoung int iq80321_pci_intr_map(const struct pci_attach_args *,
64a184f1f4Sdyoung pci_intr_handle_t *);
65e58a356cSchristos const char *iq80321_pci_intr_string(void *, pci_intr_handle_t, char *, size_t);
66592e882aSthorpej const struct evcnt *iq80321_pci_intr_evcnt(void *, pci_intr_handle_t);
67592e882aSthorpej void *iq80321_pci_intr_establish(void *, pci_intr_handle_t,
68*cce19cc2Sjmcneill int, int (*func)(void *), void *, const char *);
69592e882aSthorpej void iq80321_pci_intr_disestablish(void *, void *);
70592e882aSthorpej
71592e882aSthorpej void
iq80321_pci_init(pci_chipset_tag_t pc,void * cookie)72592e882aSthorpej iq80321_pci_init(pci_chipset_tag_t pc, void *cookie)
73592e882aSthorpej {
74592e882aSthorpej
75592e882aSthorpej pc->pc_intr_v = cookie; /* the i80321 softc */
76592e882aSthorpej pc->pc_intr_map = iq80321_pci_intr_map;
77592e882aSthorpej pc->pc_intr_string = iq80321_pci_intr_string;
78592e882aSthorpej pc->pc_intr_evcnt = iq80321_pci_intr_evcnt;
79592e882aSthorpej pc->pc_intr_establish = iq80321_pci_intr_establish;
80592e882aSthorpej pc->pc_intr_disestablish = iq80321_pci_intr_disestablish;
81592e882aSthorpej }
82592e882aSthorpej
83592e882aSthorpej int
iq80321_pci_intr_map(const struct pci_attach_args * pa,pci_intr_handle_t * ihp)84a184f1f4Sdyoung iq80321_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
85592e882aSthorpej {
86592e882aSthorpej struct i80321_softc *sc = pa->pa_pc->pc_intr_v;
879843692fSthorpej int b, d, f;
88592e882aSthorpej uint32_t busno;
89592e882aSthorpej
90592e882aSthorpej /*
91592e882aSthorpej * The IQ80321's interrupts are routed like so:
92592e882aSthorpej *
93592e882aSthorpej * XINT0 i82544 Gig-E
94592e882aSthorpej *
95592e882aSthorpej * XINT1 UART
96592e882aSthorpej *
97592e882aSthorpej * XINT2 INTA# from S-PCI-X slot
98592e882aSthorpej *
99592e882aSthorpej * XINT3 INTB# from S-PCI-X slot
100592e882aSthorpej */
101592e882aSthorpej
102592e882aSthorpej busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
103592e882aSthorpej busno = PCIXSR_BUSNO(busno);
104592e882aSthorpej if (busno == 0xff)
105592e882aSthorpej busno = 0;
106592e882aSthorpej
1079843692fSthorpej pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &b, &d, &f);
1089843692fSthorpej
109592e882aSthorpej /* No mappings for devices not on our bus. */
1109843692fSthorpej if (b != busno)
111592e882aSthorpej goto no_mapping;
112592e882aSthorpej
1139843692fSthorpej switch (d) {
114592e882aSthorpej case 4: /* i82544 Gig-E */
115592e882aSthorpej if (pa->pa_intrpin == 1) {
116592e882aSthorpej *ihp = ICU_INT_XINT(0);
117592e882aSthorpej return (0);
118592e882aSthorpej }
119592e882aSthorpej goto no_mapping;
120592e882aSthorpej
121592e882aSthorpej case 6: /* S-PCI-X slot */
122592e882aSthorpej if (pa->pa_intrpin == 1) {
123592e882aSthorpej *ihp = ICU_INT_XINT(2);
124592e882aSthorpej return (0);
125592e882aSthorpej }
126592e882aSthorpej if (pa->pa_intrpin == 2) {
127592e882aSthorpej *ihp = ICU_INT_XINT(3);
128592e882aSthorpej return (0);
129592e882aSthorpej }
130592e882aSthorpej goto no_mapping;
131592e882aSthorpej
132592e882aSthorpej default:
133592e882aSthorpej no_mapping:
134592e882aSthorpej printf("iq80321_pci_intr_map: no mapping for %d/%d/%d\n",
135592e882aSthorpej pa->pa_bus, pa->pa_device, pa->pa_function);
136592e882aSthorpej return (1);
137592e882aSthorpej }
138592e882aSthorpej
139592e882aSthorpej return (0);
140592e882aSthorpej }
141592e882aSthorpej
142592e882aSthorpej const char *
iq80321_pci_intr_string(void * v,pci_intr_handle_t ih,char * buf,size_t len)143e58a356cSchristos iq80321_pci_intr_string(void *v, pci_intr_handle_t ih, char *buf, size_t len)
144592e882aSthorpej {
145592e882aSthorpej
146e58a356cSchristos strlcpy(buf, i80321_irqnames[ih], len);
147e58a356cSchristos return buf;
148592e882aSthorpej }
149592e882aSthorpej
150592e882aSthorpej const struct evcnt *
iq80321_pci_intr_evcnt(void * v,pci_intr_handle_t ih)151592e882aSthorpej iq80321_pci_intr_evcnt(void *v, pci_intr_handle_t ih)
152592e882aSthorpej {
153592e882aSthorpej
154592e882aSthorpej /* XXX For now. */
155592e882aSthorpej return (NULL);
156592e882aSthorpej }
157592e882aSthorpej
158592e882aSthorpej void *
iq80321_pci_intr_establish(void * v,pci_intr_handle_t ih,int ipl,int (* func)(void *),void * arg,const char * xname)159592e882aSthorpej iq80321_pci_intr_establish(void *v, pci_intr_handle_t ih, int ipl,
160*cce19cc2Sjmcneill int (*func)(void *), void *arg, const char *xname)
161592e882aSthorpej {
162592e882aSthorpej
163592e882aSthorpej return (i80321_intr_establish(ih, ipl, func, arg));
164592e882aSthorpej }
165592e882aSthorpej
166592e882aSthorpej void
iq80321_pci_intr_disestablish(void * v,void * cookie)167592e882aSthorpej iq80321_pci_intr_disestablish(void *v, void *cookie)
168592e882aSthorpej {
169592e882aSthorpej
170592e882aSthorpej i80321_intr_disestablish(cookie);
171592e882aSthorpej }
172