1 /* $NetBSD: pci_machdep.c,v 1.66 2010/01/06 05:55:01 mrg Exp $ */
4 * Copyright (c) 1999, 2000 Matthew R. Green
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * functions expected by the MI PCI code.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.66 2010/01/06 05:55:01 mrg Exp $");
36 #include <sys/types.h>
37 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/errno.h>
41 #include <sys/device.h>
42 #include <sys/malloc.h>
44 #define _SPARC_BUS_DMA_PRIVATE
45 #include <machine/bus.h>
46 #include <machine/autoconf.h>
47 #include <machine/openfirm.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/pci/pcireg.h>
51 #include <dev/ofw/ofw_pci.h>
53 #include <sparc64/dev/iommureg.h>
54 #include <sparc64/dev/iommuvar.h>
55 #include <sparc64/dev/psychoreg.h>
56 #include <sparc64/dev/psychovar.h>
57 #include <sparc64/sparc64/cache.h>
62 #define SPDB_CONF 0x01
63 #define SPDB_INTR 0x04
64 #define SPDB_INTMAP 0x08
65 #define SPDB_PROBE 0x20
67 int sparc_pci_debug
= 0x0;
68 #define DPRINTF(l, s) do { if (sparc_pci_debug & l) printf s; } while (0)
73 /* this is a base to be copied */
74 struct sparc_pci_chipset _sparc_pci_chipset
= {
79 ofpci_make_tag(pci_chipset_tag_t pc
, int node
, int b
, int d
, int f
)
84 tag
= PCITAG_CREATE(node
, b
, d
, f
);
87 ("%s: creating tag for node %d bus %d dev %d fn %d\n",
88 __func__
, node
, b
, d
, f
));
90 /* Enable all the different spaces for this device */
91 reg
= pci_conf_read(pc
, tag
, PCI_COMMAND_STATUS_REG
);
92 reg
|= PCI_COMMAND_MEM_ENABLE
|PCI_COMMAND_MASTER_ENABLE
|
93 PCI_COMMAND_IO_ENABLE
;
94 pci_conf_write(pc
, tag
, PCI_COMMAND_STATUS_REG
, reg
);
100 * functions provided to the MI code.
104 pci_attach_hook(struct device
*parent
, struct device
*self
,
105 struct pcibus_attach_args
*pba
)
110 pci_bus_maxdevs(pci_chipset_tag_t pc
, int busno
)
117 pci_make_tag(pci_chipset_tag_t pc
, int b
, int d
, int f
)
119 struct ofw_pci_register reg
;
121 int (*valid
)(void *);
125 memset(name
, 0, sizeof(name
));
129 * Refer to the PCI/CardBus bus node first.
130 * It returns a tag if node is present and bus is valid.
132 if (0 <= b
&& b
< 256) {
133 KASSERT(pc
->spc_busnode
!= NULL
);
134 node
= (*pc
->spc_busnode
)[b
].node
;
135 valid
= (*pc
->spc_busnode
)[b
].valid
;
136 if (node
!= 0 && d
== 0 &&
137 (valid
== NULL
|| (*valid
)((*pc
->spc_busnode
)[b
].arg
)))
138 return ofpci_make_tag(pc
, node
, b
, d
, f
);
142 * Hunt for the node that corresponds to this device
144 * We could cache this info in an array in the parent
145 * device... except then we have problems with devices
146 * attached below pci-pci bridges, and we would need to
147 * add special code to the pci-pci bridge to cache this
151 tag
= PCITAG_CREATE(-1, b
, d
, f
);
154 * First make sure we're on the right bus. If our parent
155 * has a bus-range property and we're not in the range,
156 * then we're obviously on the wrong bus. So go up one
160 if (sparc_pci_debug
& SPDB_PROBE
) {
161 printf("curnode %x %s\n", node
,
162 prom_getpropstringA(node
, "name", name
, sizeof(name
)));
166 while ((OF_getprop(OF_parent(node
), "bus-range", (void *)&busrange
,
167 sizeof(busrange
)) == sizeof(busrange
)) &&
168 (b
< busrange
[0] || b
> busrange
[1])) {
169 /* Out of range, go up one */
170 node
= OF_parent(node
);
172 if (sparc_pci_debug
& SPDB_PROBE
) {
173 printf("going up to node %x %s\n", node
,
174 prom_getpropstringA(node
, "name", name
, sizeof(name
)));
180 * Now traverse all peers until we find the node or we find
183 * XXX We go up one and down one to make sure nobody's missed.
184 * but this should not be necessary.
186 for (node
= ((node
)); node
; node
= prom_nextsibling(node
)) {
189 if (sparc_pci_debug
& SPDB_PROBE
) {
190 printf("checking node %x %s\n", node
,
191 prom_getpropstringA(node
, "name", name
, sizeof(name
)));
198 * Check for PCI-PCI bridges. If the device we want is
199 * in the bus-range for that bridge, work our way down.
202 int busrange
[2], *brp
;
205 if (prom_getprop(node
, "bus-range", sizeof(*brp
),
208 if (len
!= 2 || b
< busrange
[0] || b
> busrange
[1])
210 /* Go down 1 level */
211 node
= prom_firstchild(node
);
213 if (sparc_pci_debug
& SPDB_PROBE
) {
214 printf("going down to node %x %s\n", node
,
215 prom_getpropstringA(node
, "name",
216 name
, sizeof(name
)));
222 * We only really need the first `reg' property.
224 * For simplicity, we'll query the `reg' when we
225 * need it. Otherwise we could malloc() it, but
226 * that gets more complicated.
228 len
= prom_getproplen(node
, "reg");
229 if (len
< sizeof(reg
))
231 if (OF_getprop(node
, "reg", (void *)®
, sizeof(reg
)) != len
)
232 panic("pci_probe_bus: OF_getprop len botch");
234 if (b
!= OFW_PCI_PHYS_HI_BUS(reg
.phys_hi
))
236 if (d
!= OFW_PCI_PHYS_HI_DEVICE(reg
.phys_hi
))
238 if (f
!= OFW_PCI_PHYS_HI_FUNCTION(reg
.phys_hi
))
242 tag
= ofpci_make_tag(pc
, node
, b
, d
, f
);
246 /* No device found -- return a dead tag */
251 pci_decompose_tag(pci_chipset_tag_t pc
, pcitag_t tag
, int *bp
, int *dp
, int *fp
)
255 *bp
= PCITAG_BUS(tag
);
257 *dp
= PCITAG_DEV(tag
);
259 *fp
= PCITAG_FUN(tag
);
263 sparc64_pci_enumerate_bus(struct pci_softc
*sc
, const int *locators
,
264 int (*match
)(struct pci_attach_args
*), struct pci_attach_args
*pap
)
266 struct ofw_pci_register reg
;
267 pci_chipset_tag_t pc
= sc
->sc_pc
;
269 pcireg_t
class, csr
, bhlc
, ic
;
270 int node
, b
, d
, f
, ret
;
271 int bus_frequency
, lt
, cl
, cacheline
;
273 extern int pci_config_dump
;
275 if (sc
->sc_bridgetag
)
276 node
= PCITAG_NODE(*sc
->sc_bridgetag
);
281 prom_getpropint(node
, "clock-frequency", 33000000) / 1000000;
284 * Make sure the cache line size is at least as big as the
285 * ecache line and the streaming cache (64 byte).
287 cacheline
= max(ecache_min_line_size
, 64);
288 KASSERT((cacheline
/64)*64 == cacheline
&&
289 (cacheline
/ecache_min_line_size
)*ecache_min_line_size
== cacheline
&&
290 (cacheline
/4)*4 == cacheline
);
292 /* Turn on parity for the bus. */
293 tag
= ofpci_make_tag(pc
, node
, sc
->sc_bus
, 0, 0);
294 csr
= pci_conf_read(pc
, tag
, PCI_COMMAND_STATUS_REG
);
295 csr
|= PCI_COMMAND_PARITY_ENABLE
;
296 pci_conf_write(pc
, tag
, PCI_COMMAND_STATUS_REG
, csr
);
299 * Initialize the latency timer register.
300 * The value 0x40 is from Solaris.
302 bhlc
= pci_conf_read(pc
, tag
, PCI_BHLC_REG
);
303 bhlc
&= ~(PCI_LATTIMER_MASK
<< PCI_LATTIMER_SHIFT
);
304 bhlc
|= 0x40 << PCI_LATTIMER_SHIFT
;
305 pci_conf_write(pc
, tag
, PCI_BHLC_REG
, bhlc
);
307 if (pci_config_dump
) pci_conf_print(pc
, tag
, NULL
);
309 for (node
= prom_firstchild(node
); node
!= 0 && node
!= -1;
310 node
= prom_nextsibling(node
)) {
311 name
[0] = name
[29] = 0;
312 prom_getpropstringA(node
, "name", name
, sizeof(name
));
314 if (OF_getprop(node
, "class-code", &class, sizeof(class)) !=
317 if (OF_getprop(node
, "reg", ®
, sizeof(reg
)) < sizeof(reg
))
318 panic("pci_enumerate_bus: \"%s\" regs too small", name
);
320 b
= OFW_PCI_PHYS_HI_BUS(reg
.phys_hi
);
321 d
= OFW_PCI_PHYS_HI_DEVICE(reg
.phys_hi
);
322 f
= OFW_PCI_PHYS_HI_FUNCTION(reg
.phys_hi
);
324 if (sc
->sc_bus
!= b
) {
325 aprint_error_dev(sc
->sc_dev
, "WARNING: incorrect "
326 "bus # for \"%s\" (%d/%d/%d)\n", name
, b
, d
, f
);
329 if ((locators
[PCICF_DEV
] != PCICF_DEV_DEFAULT
) &&
330 (locators
[PCICF_DEV
] != d
))
332 if ((locators
[PCICF_FUNCTION
] != PCICF_FUNCTION_DEFAULT
) &&
333 (locators
[PCICF_FUNCTION
] != f
))
336 tag
= ofpci_make_tag(pc
, node
, b
, d
, f
);
339 * Turn on parity and fast-back-to-back for the device.
341 csr
= pci_conf_read(pc
, tag
, PCI_COMMAND_STATUS_REG
);
342 if (csr
& PCI_STATUS_BACKTOBACK_SUPPORT
)
343 csr
|= PCI_COMMAND_BACKTOBACK_ENABLE
;
344 csr
|= PCI_COMMAND_PARITY_ENABLE
;
345 pci_conf_write(pc
, tag
, PCI_COMMAND_STATUS_REG
, csr
);
348 * Initialize the latency timer register for busmaster
349 * devices to work properly.
350 * latency-timer = min-grant * bus-freq / 4 (from FreeBSD)
351 * Also initialize the cache line size register.
352 * Solaris anytime sets this register to the value 0x10.
354 bhlc
= pci_conf_read(pc
, tag
, PCI_BHLC_REG
);
355 ic
= pci_conf_read(pc
, tag
, PCI_INTERRUPT_REG
);
357 lt
= min(PCI_MIN_GNT(ic
) * bus_frequency
/ 4, 255);
358 if (lt
== 0 || lt
< PCI_LATTIMER(bhlc
))
359 lt
= PCI_LATTIMER(bhlc
);
361 cl
= PCI_CACHELINE(bhlc
);
365 bhlc
&= ~((PCI_LATTIMER_MASK
<< PCI_LATTIMER_SHIFT
) |
366 (PCI_CACHELINE_MASK
<< PCI_CACHELINE_SHIFT
));
367 bhlc
|= (lt
<< PCI_LATTIMER_SHIFT
) |
368 (cl
<< PCI_CACHELINE_SHIFT
);
369 pci_conf_write(pc
, tag
, PCI_BHLC_REG
, bhlc
);
371 ret
= pci_probe_device(sc
, tag
, match
, pap
);
372 if (match
!= NULL
&& ret
!= 0)
379 pci_intr_string(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
383 sprintf(str
, "ivec %x", ih
);
384 DPRINTF(SPDB_INTR
, ("pci_intr_string: returning %s\n", str
));
390 pci_intr_evcnt(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
393 /* XXX for now, no evcnt parent reported */
398 pci_intr_setattr(pci_chipset_tag_t pc
, pci_intr_handle_t
*ih
,
399 int attr
, uint64_t data
)
403 case PCI_INTR_MPSAFE
:
411 * interrupt mapping foo.
412 * XXX: how does this deal with multiple interrupts for a device?
415 pci_intr_map(struct pci_attach_args
*pa
, pci_intr_handle_t
*ihp
)
417 pcitag_t tag
= pa
->pa_tag
;
418 int interrupts
[4], *intp
, int_used
;
419 int len
, node
= PCITAG_NODE(tag
);
422 intp
= &interrupts
[0];
423 len
= prom_getproplen(node
, "interrupts");
424 if (len
> sizeof(interrupts
)) {
426 ("pci_intr_map: too many available interrupts\n"));
429 if (prom_getprop(node
, "interrupts", len
,
430 &len
, &intp
) != 0 || len
!= 1) {
432 ("pci_intr_map: could not read interrupts\n"));
436 /* XXX We pick the first interrupt, but should do better */
437 int_used
= interrupts
[0];
438 if (OF_mapintr(node
, &int_used
, sizeof(int_used
),
439 sizeof(int_used
)) < 0) {
440 printf("OF_mapintr failed\n");
441 KASSERT(pa
->pa_pc
->spc_find_ino
);
442 pa
->pa_pc
->spc_find_ino(pa
, &int_used
);
444 DPRINTF(SPDB_INTMAP
, ("OF_mapintr() gave %x\n", int_used
));
446 /* Try to find an IPL for this type of device. */
447 prom_getpropstringA(node
, "device_type", devtype
, sizeof(devtype
));
448 for (len
= 0; intrmap
[len
].in_class
!= NULL
; len
++)
449 if (strcmp(intrmap
[len
].in_class
, devtype
) == 0) {
450 int_used
|= INTLEVENCODE(intrmap
[len
].in_lev
);
451 DPRINTF(SPDB_INTMAP
, ("reset to %x\n", int_used
));
457 /* Call the sub-driver is necessary */
458 if (pa
->pa_pc
->spc_intr_map
)
459 (*pa
->pa_pc
->spc_intr_map
)(pa
, ihp
);
465 pci_intr_disestablish(pci_chipset_tag_t pc
, void *cookie
)
468 DPRINTF(SPDB_INTR
, ("pci_intr_disestablish: cookie %p\n", cookie
));
471 /* panic("can't disestablish PCI interrupts yet"); */
475 sparc_pci_childspace(int type
)
480 case PCI_CONFIG_BUS_SPACE
:
483 case PCI_IO_BUS_SPACE
:
486 case PCI_MEMORY_BUS_SPACE
:
490 /* we don't do 64 bit memory space */
491 case PCI_MEMORY64_BUS_SPACE
:
496 panic("get_childspace: unknown bus type");