xref: /netbsd/sys/arch/sandpoint/pci/pci_machdep.c (revision bf9ec67e)
1 /*	$NetBSD: pci_machdep.c,v 1.9 2002/05/24 15:47:17 briggs Exp $	*/
2 
3 /*
4  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
5  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Charles M. Hannum.
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Machine-specific functions for PCI autoconfiguration.
35  *
36  * On PCs, there are two methods of generating PCI configuration cycles.
37  * We try to detect the appropriate mechanism for this machine and set
38  * up a few function pointers to access the correct method directly.
39  *
40  * The configuration method can be hard-coded in the config file by
41  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
42  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
43  */
44 #include "opt_openpic.h"
45 
46 #include <sys/types.h>
47 #include <sys/param.h>
48 #include <sys/device.h>
49 #include <sys/errno.h>
50 #include <sys/extent.h>
51 #include <sys/malloc.h>
52 #include <sys/queue.h>
53 #include <sys/systm.h>
54 #include <sys/time.h>
55 
56 #include <uvm/uvm.h>
57 
58 #define _POWERPC_BUS_DMA_PRIVATE
59 #include <machine/bus.h>
60 #include <machine/pio.h>
61 #include <machine/intr.h>
62 #include <machine/openpicreg.h>
63 
64 #include <dev/isa/isavar.h>
65 #include <dev/pci/pcivar.h>
66 #include <dev/pci/pcireg.h>
67 #include <dev/pci/pciconf.h>
68 
69 #include <sandpoint/isa/icu.h>
70 
71 struct powerpc_bus_dma_tag pci_bus_dma_tag = {
72 	0,			/* _bounce_thresh */
73 	_bus_dmamap_create,
74 	_bus_dmamap_destroy,
75 	_bus_dmamap_load,
76 	_bus_dmamap_load_mbuf,
77 	_bus_dmamap_load_uio,
78 	_bus_dmamap_load_raw,
79 	_bus_dmamap_unload,
80 	NULL,			/* _dmamap_sync */
81 	_bus_dmamem_alloc,
82 	_bus_dmamem_free,
83 	_bus_dmamem_map,
84 	_bus_dmamem_unmap,
85 	_bus_dmamem_mmap,
86 };
87 
88 #define	PCI_CONFIG_ENABLE	0x80000000UL
89 
90 void
91 pci_attach_hook(parent, self, pba)
92 	struct device *parent, *self;
93 	struct pcibus_attach_args *pba;
94 {
95 }
96 
97 int
98 pci_bus_maxdevs(pc, busno)
99 	pci_chipset_tag_t pc;
100 	int busno;
101 {
102 
103 	/*
104 	 * Bus number is irrelevant.  Configuration Mechanism 1 is in
105 	 * use, can have devices 0-32 (i.e. the `normal' range).
106 	 */
107 	return (32);
108 }
109 
110 pcitag_t
111 pci_make_tag(pc, bus, device, function)
112 	pci_chipset_tag_t pc;
113 	int bus, device, function;
114 {
115 	pcitag_t tag;
116 
117 	if (bus >= 256 || device >= 32 || function >= 8)
118 		panic("pci_make_tag: bad request");
119 
120 	tag = PCI_CONFIG_ENABLE |
121 		    (bus << 16) | (device << 11) | (function << 8);
122 	return tag;
123 }
124 
125 void
126 pci_decompose_tag(pc, tag, bp, dp, fp)
127 	pci_chipset_tag_t pc;
128 	pcitag_t tag;
129 	int *bp, *dp, *fp;
130 {
131 
132 	if (bp != NULL)
133 		*bp = (tag >> 16) & 0xff;
134 	if (dp != NULL)
135 		*dp = (tag >> 11) & 0x1f;
136 	if (fp != NULL)
137 		*fp = (tag >> 8) & 0x7;
138 	return;
139 }
140 
141 /*
142  * The Kahlua documentation says that "reg" should be left-shifted by two
143  * and be in bits 2-7.  Apparently not.  It doesn't work that way, and the
144  * DINK32 ROM doesn't do it that way (I peeked at 0xfec00000 after running
145  * the DINK32 "pcf" command).
146  */
147 #define SP_PCI(tag, reg) ((tag) | (reg))
148 
149 pcireg_t
150 pci_conf_read(pc, tag, reg)
151 	pci_chipset_tag_t pc;
152 	pcitag_t tag;
153 	int reg;
154 {
155 	pcireg_t data;
156 
157 	out32rb(SANDPOINT_PCI_CONFIG_ADDR, SP_PCI(tag,reg));
158 	data = in32rb(SANDPOINT_PCI_CONFIG_DATA);
159 	out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
160 	return data;
161 }
162 
163 void
164 pci_conf_write(pc, tag, reg, data)
165 	pci_chipset_tag_t pc;
166 	pcitag_t tag;
167 	int reg;
168 	pcireg_t data;
169 {
170 	out32rb(SANDPOINT_PCI_CONFIG_ADDR, SP_PCI(tag, reg));
171 	out32rb(SANDPOINT_PCI_CONFIG_DATA, data);
172 	out32rb(SANDPOINT_PCI_CONFIG_ADDR, 0);
173 }
174 
175 int
176 pci_intr_map(pa, ihp)
177 	struct pci_attach_args *pa;
178 	pci_intr_handle_t *ihp;
179 {
180 	int	pin = pa->pa_intrpin;
181 	int	line = pa->pa_intrline;
182 
183 	if (pin == 0) {
184 		/* No IRQ used. */
185 		goto bad;
186 	}
187 
188 	if (pin > 4) {
189 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
190 		goto bad;
191 	}
192 
193 	/*
194 	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
195 	 * `unknown' or `no connection' on a PC.  We assume that a device with
196 	 * `no connection' either doesn't have an interrupt (in which case the
197 	 * pin number should be 0, and would have been noticed above), or
198 	 * wasn't configured by the BIOS (in which case we punt, since there's
199 	 * no real way we can know how the interrupt lines are mapped in the
200 	 * hardware).
201 	 *
202 	 * XXX
203 	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
204 	 * that the BIOS did its job, we also recognize that as meaning that
205 	 * the BIOS has not configured the device.
206 	 */
207 	if (line == 255) {
208 		printf("pci_intr_map: no mapping for pin %c\n", '@' + pin);
209 		goto bad;
210 	}
211 #if defined(OPENPIC_SERIAL_MODE)
212 	if (line == 11) {
213 		switch (pin) {
214 		case PCI_INTERRUPT_PIN_A:
215 			*ihp = SANDPOINT_INTR_WINBOND_A;
216 			break;
217 		case PCI_INTERRUPT_PIN_B:
218 			*ihp = SANDPOINT_INTR_WINBOND_B;
219 			break;
220 		case PCI_INTERRUPT_PIN_C:
221 			*ihp = SANDPOINT_INTR_WINBOND_C;
222 			break;
223 		case PCI_INTERRUPT_PIN_D:
224 			*ihp = SANDPOINT_INTR_WINBOND_D;
225 			break;
226 		default:
227 			printf("pci_intr_map: bad interrupt line %d,%c\n",
228 				line, pin + '@');
229 			goto bad;
230 			break;
231 		}
232 			*ihp = SANDPOINT_INTR_WINBOND_C;
233 	} else {
234 #else
235 	if (1) {
236 #endif
237 		/*
238 		 * Sandpoint has 4 PCI slots.
239 		 * Sandpoint rev. X2 has them in a weird order.  Counting
240 		 * from center out toward the edge, we have:
241 		 * 	Slot 1 (dev 14?) (labelled 1)
242 		 * 	Slot 0 (dev 13?) (labelled 2)
243 		 * 	Slot 3 (dev 16)  (labelled 3)
244 		 * 	Slot 2 (dev 15)  (labelled 4)
245 		 * To keep things confusing, we will consistently use a zero-
246 		 * based numbering scheme where Motorola's is usually 1-based.
247 		 */
248 		if (line < 13 || line > 16) {
249 			printf("pci_intr_map: bad interrupt line %d,%c\n",
250 				line, pin + '@');
251 			goto bad;
252 		}
253 
254 		/*
255 		 * In the PCI configuration code, we simply assign the dev
256 		 * number to the interrupt line.  We extract it here for the
257 		 * interrupt, but subtract off the lowest dev (13) to get
258 		 * the IRQ.
259 		 */
260 #if defined(OPENPIC_SERIAL_MODE)
261 		*ihp = line - 11;
262 #else
263 		*ihp = line - 13;
264 #endif
265 	}
266 	return 0;
267 
268 bad:
269 	*ihp = -1;
270 	return 1;
271 }
272 
273 const char *
274 pci_intr_string(pc, ih)
275 	pci_chipset_tag_t pc;
276 	pci_intr_handle_t ih;
277 {
278 	static char irqstr[8];		/* 4 + 2 + NULL + sanity */
279 
280 	if (ih < 0 || ih >= ICU_LEN)
281 		panic("pci_intr_string: bogus handle 0x%x\n", ih);
282 
283 	sprintf(irqstr, "irq %d", ih);
284 	return (irqstr);
285 
286 }
287 
288 const struct evcnt *
289 pci_intr_evcnt(pc, ih)
290 	pci_chipset_tag_t pc;
291 	pci_intr_handle_t ih;
292 {
293 
294 	/* XXX for now, no evcnt parent reported */
295 	return NULL;
296 }
297 
298 void *
299 pci_intr_establish(pc, ih, level, func, arg)
300 	pci_chipset_tag_t pc;
301 	pci_intr_handle_t ih;
302 	int level, (*func) __P((void *));
303 	void *arg;
304 {
305 #if 0
306 	if (ih < SANDPOINT_INTR_PCI0 || ih > SANDPOINT_INTR_PCI3)
307 		panic("pci_intr_establish: bogus handle 0x%x\n", ih);
308 #endif
309 
310 	/*
311 	 * ih is the value assigned in pci_intr_map(), above.
312 	 * For the Sandpoint, this is the zero-based slot #,
313 	 * configured when the bus is set up.
314 	 */
315 	return intr_establish(ih, IST_LEVEL, level, func, arg);
316 }
317 
318 void
319 pci_intr_disestablish(pc, cookie)
320 	pci_chipset_tag_t pc;
321 	void *cookie;
322 {
323 	intr_disestablish(cookie);
324 }
325 
326 void
327 pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin, int swiz,
328     int *iline)
329 {
330 	if (bus == 0) {
331 		*iline = dev;
332 	} else {
333 		/*
334 		 * If we are not on bus zero, we're behind a bridge, so we
335 		 * swizzle.
336 		 *
337 		 * The documentation lies about this.  In slot 3 (numbering
338 		 * from 0) aka device 16, INTD# becomes an interrupt for
339 		 * slot 2.  INTC# becomes an interrupt for slot 1, etc.
340 		 * In slot 2 aka device 16, INTD# becomes an interrupt for
341 		 * slot 1, etc.
342 		 *
343 		 * Verified for INTD# on device 16, INTC# on device 16,
344 		 * INTD# on device 15, INTD# on device 13, and INTC# on
345 		 * device 14.  I presume that the rest follow the same
346 		 * pattern.
347 		 *
348 		 * Slot 0 is device 13, and is the base for the rest.
349 		 */
350 		*iline = 13 + ((swiz + dev + 3) & 3);
351 	}
352 }
353