1 /* $NetBSD: pci_machdep.c,v 1.26 2008/03/22 18:32:20 tsutsui Exp $ */
4 * Copyright (c) 2000 Soren S. Jorvang. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.26 2008/03/22 18:32:20 tsutsui Exp $");
31 #include <sys/types.h>
32 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/errno.h>
36 #include <sys/device.h>
37 #include <sys/extent.h>
39 #define _COBALT_BUS_DMA_PRIVATE
40 #include <machine/bus.h>
41 #include <machine/intr.h>
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pcidevs.h>
46 #include <dev/pci/pciconf.h>
47 #include <dev/pci/pciide_apollo_reg.h>
49 #include <cobalt/dev/gtreg.h>
52 * PCI doesn't have any special needs; just use
53 * the generic versions of these functions.
55 struct cobalt_bus_dma_tag pci_bus_dma_tag
= {
59 _bus_dmamap_load_mbuf
,
72 pci_attach_hook(struct device
*parent
, struct device
*self
,
73 struct pcibus_attach_args
*pba
)
81 pci_bus_maxdevs(pci_chipset_tag_t pc
, int busno
)
88 pci_make_tag(pci_chipset_tag_t pc
, int bus
, int device
, int function
)
91 return (bus
<< 16) | (device
<< 11) | (function
<< 8);
95 pci_decompose_tag(pci_chipset_tag_t pc
, pcitag_t tag
, int *bp
, int *dp
, int *fp
)
99 *bp
= (tag
>> 16) & 0xff;
101 *dp
= (tag
>> 11) & 0x1f;
103 *fp
= (tag
>> 8) & 0x07;
107 pci_conf_read(pci_chipset_tag_t pc
, pcitag_t tag
, int reg
)
112 pci_decompose_tag(pc
, tag
, &bus
, &dev
, &func
);
115 * 2700 hardware wedges on accesses to device 6.
117 if (bus
== 0 && dev
== 6)
120 * 2800 hardware wedges on accesses to device 31.
122 if (bus
== 0 && dev
== 31)
125 bus_space_write_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_ADDR
,
126 PCICFG_ENABLE
| tag
| reg
);
127 data
= bus_space_read_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_DATA
);
128 bus_space_write_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_ADDR
, 0);
134 pci_conf_write(pci_chipset_tag_t pc
, pcitag_t tag
, int reg
, pcireg_t data
)
137 bus_space_write_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_ADDR
,
138 PCICFG_ENABLE
| tag
| reg
);
139 bus_space_write_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_DATA
, data
);
140 bus_space_write_4(pc
->pc_bst
, pc
->pc_bsh
, GT_PCICFG_ADDR
, 0);
144 pci_intr_map(struct pci_attach_args
*pa
, pci_intr_handle_t
*ihp
)
146 pci_chipset_tag_t pc
= pa
->pa_pc
;
147 pcitag_t intrtag
= pa
->pa_intrtag
;
148 int pin
= pa
->pa_intrpin
;
149 int line
= pa
->pa_intrline
;
152 pci_decompose_tag(pc
, intrtag
, &bus
, &dev
, &func
);
155 * The interrupt lines of the internal Tulips are connected
156 * directly to the CPU.
158 if (cobalt_id
== COBALT_ID_QUBE2700
) {
159 if (bus
== 0 && dev
== 7 && pin
== PCI_INTERRUPT_PIN_A
) {
160 /* tulip is connected to CPU INT2 on Qube2700 */
165 if (bus
== 0 && dev
== 7 && pin
== PCI_INTERRUPT_PIN_A
) {
166 /* the primary tulip is connected to CPU INT1 */
170 if (bus
== 0 && dev
== 12 && pin
== PCI_INTERRUPT_PIN_A
) {
171 /* the secondary tulip is connected to CPU INT2 */
178 if (line
== 0 || line
>= NICU_INT
)
186 pci_intr_string(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
188 static char irqstr
[8];
191 sprintf(irqstr
, "level %d", ih
- NICU_INT
);
193 sprintf(irqstr
, "irq %d", ih
);
199 pci_intr_evcnt(pci_chipset_tag_t pc
, pci_intr_handle_t ih
)
202 /* XXX for now, no evcnt parent reported */
207 pci_intr_setattr(pci_chipset_tag_t pc
, pci_intr_handle_t
*ih
,
208 int attr
, uint64_t data
)
212 case PCI_INTR_MPSAFE
:
220 pci_intr_establish(pci_chipset_tag_t pc
, pci_intr_handle_t ih
, int level
,
221 int (*func
)(void *), void *arg
)
225 return cpu_intr_establish(ih
- NICU_INT
, level
, func
, arg
);
227 return icu_intr_establish(ih
, IST_LEVEL
, level
, func
, arg
);
231 pci_intr_disestablish(pci_chipset_tag_t pc
, void *cookie
)
234 /* Try both, only the valid one will disestablish. */
235 cpu_intr_disestablish(cookie
);
236 icu_intr_disestablish(cookie
);
240 pci_conf_interrupt(pci_chipset_tag_t pc
, int bus
, int dev
, int pin
, int swiz
,
245 * Use irq 9 on all devices on the Qube's PCI slot.
246 * XXX doesn't handle devices over PCI-PCI bridges
248 if (bus
== 0 && dev
== 10 && pin
!= PCI_INTERRUPT_PIN_NONE
)
253 pci_conf_hook(pci_chipset_tag_t pc
, int bus
, int dev
, int func
, pcireg_t id
)
256 /* ignore bogus IDs */
257 if (PCI_VENDOR(id
) == 0)
260 /* 2700 hardware wedges on accesses to device 6. */
261 if (bus
== 0 && dev
== 6)
264 /* 2800 hardware wedges on accesses to device 31. */
265 if (bus
== 0 && dev
== 31)
268 /* Don't configure the bridge and PCI probe. */
269 if (PCI_VENDOR(id
) == PCI_VENDOR_MARVELL
&&
270 PCI_PRODUCT(id
) == PCI_PRODUCT_MARVELL_GT64011
)
273 /* Don't configure on-board VIA VT82C586 (pcib, uhci) */
274 if (bus
== 0 && dev
== 9 && (func
== 0 || func
== 2))
277 /* Enable viaide secondary port. Some firmware doesn't enable it. */
278 if (bus
== 0 && dev
== 9 && func
== 1) {
282 #define APO_VIAIDECONF (APO_VIA_REGBASE + 0x00)
284 tag
= pci_make_tag(pc
, bus
, dev
, func
);
285 csr
= pci_conf_read(pc
, tag
, APO_VIAIDECONF
);
286 pci_conf_write(pc
, tag
, APO_VIAIDECONF
,
287 csr
| APO_IDECONF_EN(1));
289 return PCI_CONF_DEFAULT
& ~(PCI_COMMAND_SERR_ENABLE
|
290 PCI_COMMAND_PARITY_ENABLE
);