pci_machdep.c revision 1.12
1/*	$NetBSD: pci_machdep.c,v 1.12 2002/01/13 23:02:35 augustss Exp $	*/
2
3/*
4 * Copyright (c) 2000 Soren S. Jorvang.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions, and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/types.h>
29#include <sys/param.h>
30#include <sys/time.h>
31#include <sys/systm.h>
32#include <sys/errno.h>
33#include <sys/device.h>
34
35#define _COBALT_BUS_DMA_PRIVATE
36#include <machine/bus.h>
37#include <machine/intr.h>
38#include <machine/intr_machdep.h>
39
40#include <dev/pci/pcivar.h>
41#include <dev/pci/pcireg.h>
42#include <dev/pci/pcidevs.h>
43
44/*
45 * PCI doesn't have any special needs; just use
46 * the generic versions of these functions.
47 */
48struct cobalt_bus_dma_tag pci_bus_dma_tag = {
49	_bus_dmamap_create,
50	_bus_dmamap_destroy,
51	_bus_dmamap_load,
52	_bus_dmamap_load_mbuf,
53	_bus_dmamap_load_uio,
54	_bus_dmamap_load_raw,
55	_bus_dmamap_unload,
56	_bus_dmamap_sync,
57	_bus_dmamem_alloc,
58	_bus_dmamem_free,
59	_bus_dmamem_map,
60	_bus_dmamem_unmap,
61	_bus_dmamem_mmap,
62};
63
64void
65pci_attach_hook(parent, self, pba)
66	struct device *parent, *self;
67	struct pcibus_attach_args *pba;
68{
69	/* XXX */
70
71	return;
72}
73
74int
75pci_bus_maxdevs(pc, busno)
76	pci_chipset_tag_t pc;
77	int busno;
78{
79	return 32;
80}
81
82pcitag_t
83pci_make_tag(pc, bus, device, function)
84	pci_chipset_tag_t pc;
85	int bus, device, function;
86{
87	return (bus << 16) | (device << 11) | (function << 8);
88}
89
90void
91pci_decompose_tag(pc, tag, bp, dp, fp)
92	pci_chipset_tag_t pc;
93	pcitag_t tag;
94	int *bp, *dp, *fp;
95{
96	if (bp != NULL)
97		*bp = (tag >> 16) & 0xff;
98	if (dp != NULL)
99		*dp = (tag >> 11) & 0x1f;
100	if (fp != NULL)
101		*fp = (tag >> 8) & 0x07;
102}
103
104#define PCI_CFG_ADDR	((volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000cf8))
105#define PCI_CFG_DATA	((volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000cfc))
106
107pcireg_t
108pci_conf_read(pc, tag, reg)
109	pci_chipset_tag_t pc;
110	pcitag_t tag;
111	int reg;
112{
113	pcireg_t data;
114	int bus, dev, func;
115
116	pci_decompose_tag(pc, tag, &bus, &dev, &func);
117
118	/*
119	 * 2700 hardware wedges on accesses to device 6.
120	 */
121	if (bus == 0 && dev == 6)
122		return 0;
123	/*
124	 * 2800 hardware wedges on accesses to device 31.
125	 */
126	if (bus == 0 && dev == 31)
127		return 0;
128
129	*PCI_CFG_ADDR = 0x80000000 | tag | reg;
130	data = *PCI_CFG_DATA;
131	*PCI_CFG_ADDR = 0;
132
133	return data;
134}
135
136void
137pci_conf_write(pc, tag, reg, data)
138	pci_chipset_tag_t pc;
139	pcitag_t tag;
140	int reg;
141	pcireg_t data;
142{
143	*PCI_CFG_ADDR = 0x80000000 | tag | reg;
144	*PCI_CFG_DATA = data;
145	*PCI_CFG_ADDR = 0;
146
147	return;
148}
149
150int
151pci_intr_map(pa, ihp)
152	struct pci_attach_args *pa;
153	pci_intr_handle_t *ihp;
154{
155	pci_chipset_tag_t pc = pa->pa_pc;
156	pcitag_t intrtag = pa->pa_intrtag;
157	int pin = pa->pa_intrpin;
158	int line = pa->pa_intrline;
159	int bus, dev, func;
160
161	pci_decompose_tag(pc, intrtag, &bus, &dev, &func);
162
163	/*
164	 * The interrupt lines of the two Tulips are connected
165	 * directly to the CPU.
166	 */
167
168	if (bus == 0 && dev == 7 && pin == PCI_INTERRUPT_PIN_A)
169		*ihp = 16 + 1;
170	else if (bus == 0 && dev == 12 && pin == PCI_INTERRUPT_PIN_A)
171		*ihp = 16 + 2;
172	else
173		*ihp = line;
174
175	return 0;
176}
177
178const char *
179pci_intr_string(pc, ih)
180	pci_chipset_tag_t pc;
181	pci_intr_handle_t ih;
182{
183	static char irqstr[8];
184
185	if (ih >= 16)
186		sprintf(irqstr, "level %d", ih - 16);
187	else
188		sprintf(irqstr, "irq %d", ih);
189
190	return irqstr;
191}
192
193const struct evcnt *
194pci_intr_evcnt(pc, ih)
195	pci_chipset_tag_t pc;
196	pci_intr_handle_t ih;
197{
198
199	/* XXX for now, no evcnt parent reported */
200	return NULL;
201}
202
203void *
204pci_intr_establish(pc, ih, level, func, arg)
205	pci_chipset_tag_t pc;
206	pci_intr_handle_t ih;
207	int level, (*func)(void *);
208	void *arg;
209{
210	if (ih >= 16)
211		return cpu_intr_establish(ih - 16, level, func, arg);
212	else
213		return icu_intr_establish(ih, IST_LEVEL, level, func, arg);
214}
215
216void
217pci_intr_disestablish(pc, cookie)
218	pci_chipset_tag_t pc;
219	void *cookie;
220{
221	/* Try both, only the valid one will disestablish. */
222	cpu_intr_disestablish(cookie);
223	icu_intr_disestablish(cookie);
224}
225