1 /* $NetBSD: pchb.c,v 1.3 2008/01/28 18:24:21 garbled Exp $ */
4 * Copyright (c) 2007 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.3 2008/01/28 18:24:21 garbled Exp $");
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
40 #include <machine/bus.h>
41 #include <machine/pio.h>
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
45 #include <dev/pci/pcidevs.h>
46 #include <dev/pci/agpreg.h>
47 #include <dev/pci/agpvar.h>
49 #include <dev/ic/mpc105reg.h>
50 #include <dev/ic/mpc106reg.h>
51 #include <dev/ic/ibm82660reg.h>
55 int pchbmatch(struct device
*, struct cfdata
*, void *);
56 void pchbattach(struct device
*, struct device
*, void *);
58 CFATTACH_DECL(pchb
, sizeof(struct device
),
59 pchbmatch
, pchbattach
, NULL
, NULL
);
62 pchbmatch(struct device
*parent
, struct cfdata
*cf
, void *aux
)
64 struct pci_attach_args
*pa
= aux
;
67 * Match all known PCI host chipsets.
69 if (PCI_CLASS(pa
->pa_class
) == PCI_CLASS_BRIDGE
&&
70 PCI_SUBCLASS(pa
->pa_class
) == PCI_SUBCLASS_BRIDGE_HOST
) {
78 mpc105_print(struct pci_attach_args
*pa
, struct device
*self
)
83 reg1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, MPC105_PICR1
);
84 reg2
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, MPC105_PICR2
);
85 aprint_normal("%s: L2 cache: ", self
->dv_xname
);
87 switch (reg2
& MPC105_PICR2_L2_SIZE
) {
88 case MPC105_PICR2_L2_SIZE_256K
:
91 case MPC105_PICR2_L2_SIZE_512K
:
94 case MPC105_PICR2_L2_SIZE_1M
:
102 aprint_normal("%s, ", s1
);
103 switch (reg1
& MPC105_PICR1_L2_MP
) {
104 case MPC105_PICR1_L2_MP_NONE
:
105 s1
= "uniprocessor/none";
107 case MPC105_PICR1_L2_MP_WT
:
108 s1
= "write-through";
110 case MPC105_PICR1_L2_MP_WB
:
113 case MPC105_PICR1_L2_MP_MP
:
114 s1
= "multiprocessor";
117 aprint_normal("%s mode\n", s1
);
121 mpc106_print(struct pci_attach_args
*pa
, struct device
*self
)
126 reg1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, MPC106_PICR1
);
127 reg2
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, MPC106_PICR2
);
128 aprint_normal("%s: L2 cache: ", self
->dv_xname
);
130 switch (reg2
& MPC106_PICR2_L2_SIZE
) {
131 case MPC106_PICR2_L2_SIZE_256K
:
134 case MPC106_PICR2_L2_SIZE_512K
:
137 case MPC106_PICR2_L2_SIZE_1M
:
141 s1
= "reserved size";
145 aprint_normal("%s, ", s1
);
146 switch (reg1
& MPC106_PICR1_EXT_L2_EN
) {
148 switch (reg1
& MPC106_PICR1_L2_MP
) {
149 case MPC106_PICR1_L2_MP_NONE
:
150 s1
= "uniprocessor/none";
152 case MPC106_PICR1_L2_MP_WT
:
153 s1
= "internally controlled write-through";
155 case MPC106_PICR1_L2_MP_WB
:
156 s1
= "internally controlled write-back";
158 case MPC106_PICR1_L2_MP_MP
:
159 s1
= "multiprocessor/none";
164 switch (reg1
& MPC106_PICR1_L2_MP
) {
165 case MPC106_PICR1_L2_MP_NONE
:
166 s1
= "uniprocessor/external";
168 case MPC106_PICR1_L2_MP_MP
:
169 s1
= "multiprocessors/external";
176 aprint_normal("%s mode\n", s1
);
180 ibm82660_print(struct pci_attach_args
*pa
, struct device
*self
)
183 #ifdef PREP_BUS_SPACE_IO
188 reg1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
189 IBM_82660_CACHE_STATUS
);
190 #ifdef PREP_BUS_SPACE_IO
191 reg2
= in32rb(PREP_BUS_SPACE_IO
+IBM_82660_SYSTEM_CTRL
);
192 if (reg2
& IBM_82660_SYSTEM_CTRL_L2_EN
) {
193 if (reg1
& IBM_82660_CACHE_STATUS_L2_EN
)
194 s1
= "internal enabled";
197 if (reg2
& IBM_82660_SYSTEM_CTRL_L2_MI
)
198 s2
= "(normal operation)";
200 s2
= "(miss updates inhibited)";
206 if (reg1
& IBM_82660_CACHE_STATUS_L2_EN
)
212 aprint_normal("%s: L1: %s L2: %s %s\n", self
->dv_xname
,
213 (reg1
& IBM_82660_CACHE_STATUS_L1_EN
) ? "enabled" : "disabled",
216 reg1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, IBM_82660_OPTIONS_1
);
217 aprint_verbose("%s: MCP# assertion %s "
218 "TEA# assertion %s\n", self
->dv_xname
,
219 (reg1
& IBM_82660_OPTIONS_1_MCP
) ? "enabled" : "disabled",
220 (reg1
& IBM_82660_OPTIONS_1_TEA
) ? "enabled" : "disabled");
221 aprint_verbose("%s: PCI/ISA I/O mapping %s\n", self
->dv_xname
,
222 (reg1
& IBM_82660_OPTIONS_1_ISA
) ? "contiguous" : "non-contiguous");
224 reg1
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, IBM_82660_OPTIONS_3
);
225 aprint_normal("%s: DRAM %s (%s) SRAM %s\n", self
->dv_xname
,
226 (reg1
& IBM_82660_OPTIONS_3_DRAM
) ? "EDO" : "standard",
227 (reg1
& IBM_82660_OPTIONS_3_ECC
) ? "ECC" : "parity",
228 (reg1
& IBM_82660_OPTIONS_3_SRAM
) ? "sync" : "async");
229 aprint_verbose("%s: Snoop mode %s\n", self
->dv_xname
,
230 (reg1
& IBM_82660_OPTIONS_3_SNOOP
) ? "603" : "601/604");
234 pchbattach(struct device
*parent
, struct device
*self
, void *aux
)
236 struct pci_attach_args
*pa
= aux
;
239 struct agpbus_attach_args apa
;
241 volatile unsigned char *python
;
247 * All we do is print out a description. Eventually, we
248 * might want to add code that does something that's
249 * possibly chipset-specific.
252 pci_devinfo(pa
->pa_id
, pa
->pa_class
, 0, devinfo
, sizeof(devinfo
));
253 aprint_normal("%s: %s (rev. 0x%02x)\n", self
->dv_xname
, devinfo
,
254 PCI_REVISION(pa
->pa_class
));
256 switch (PCI_VENDOR(pa
->pa_id
)) {
258 switch (PCI_PRODUCT(pa
->pa_id
)) {
259 case PCI_PRODUCT_IBM_82660
:
260 ibm82660_print(pa
, self
);
262 case PCI_PRODUCT_IBM_PYTHON
:
263 python
= mapiodev(0xfeff6000, 0x60);
264 v
= 0x88b78e01; /* taken from linux */
265 out32rb(python
+0x30, v
);
266 v
= in32rb(python
+0x30);
267 aprint_debug("Reset python reg 30 to 0x%x\n", v
);
272 switch (PCI_PRODUCT(pa
->pa_id
)) {
273 case PCI_PRODUCT_MOT_MPC105
:
274 mpc105_print(pa
, self
);
276 case PCI_PRODUCT_MOT_MPC106
:
277 mpc106_print(pa
, self
);
284 if (pci_get_capability(pa
->pa_pc
, pa
->pa_tag
, PCI_CAP_AGP
,
286 apa
.apa_pci_args
= *pa
;
287 config_found_ia(self
, "agpbus", &apa
, agpbusprint
);