xref: /netbsd-src/sys/arch/powerpc/pci/pchb.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: pchb.c,v 1.2 2007/10/17 19:56:44 garbled Exp $	*/
2 
3 /*-
4  * Copyright (c) 2007 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Tim Rightnour
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
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.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.2 2007/10/17 19:56:44 garbled Exp $");
41 
42 #include <sys/types.h>
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
46 
47 #include <machine/bus.h>
48 #include <machine/pio.h>
49 
50 #include <dev/pci/pcivar.h>
51 #include <dev/pci/pcireg.h>
52 #include <dev/pci/pcidevs.h>
53 #include <dev/pci/agpreg.h>
54 #include <dev/pci/agpvar.h>
55 
56 #include <dev/ic/mpc105reg.h>
57 #include <dev/ic/mpc106reg.h>
58 #include <dev/ic/ibm82660reg.h>
59 
60 #include "agp.h"
61 
62 int	pchbmatch(struct device *, struct cfdata *, void *);
63 void	pchbattach(struct device *, struct device *, void *);
64 
65 CFATTACH_DECL(pchb, sizeof(struct device),
66     pchbmatch, pchbattach, NULL, NULL);
67 
68 int
69 pchbmatch(struct device *parent, struct cfdata *cf, void *aux)
70 {
71 	struct pci_attach_args *pa = aux;
72 
73 	/*
74 	 * Match all known PCI host chipsets.
75 	 */
76 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
77 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) {
78 		return (1);
79 	}
80 
81 	return (0);
82 }
83 
84 static void
85 mpc105_print(struct pci_attach_args *pa, struct device *self)
86 {
87 	pcireg_t reg1, reg2;
88 	const char *s1;
89 
90 	reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC105_PICR1);
91 	reg2 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC105_PICR2);
92 	aprint_normal("%s: L2 cache: ", self->dv_xname);
93 
94 	switch (reg2 & MPC105_PICR2_L2_SIZE) {
95 	case MPC105_PICR2_L2_SIZE_256K:
96 		s1 = "256K";
97 		break;
98 	case MPC105_PICR2_L2_SIZE_512K:
99 		s1 = "512K";
100 		break;
101 	case MPC105_PICR2_L2_SIZE_1M:
102 		s1 = "1M";
103 		break;
104 	default:
105 		s1 = "reserved size";
106 		break;
107 	}
108 
109 	aprint_normal("%s, ", s1);
110 	switch (reg1 & MPC105_PICR1_L2_MP) {
111 	case MPC105_PICR1_L2_MP_NONE:
112 		s1 = "uniprocessor/none";
113 		break;
114 	case MPC105_PICR1_L2_MP_WT:
115 		s1 = "write-through";
116 		break;
117 	case MPC105_PICR1_L2_MP_WB:
118 		s1 = "write-back";
119 		break;
120 	case MPC105_PICR1_L2_MP_MP:
121 		s1 = "multiprocessor";
122 		break;
123 	}
124 	aprint_normal("%s mode\n", s1);
125 }
126 
127 static void
128 mpc106_print(struct pci_attach_args *pa, struct device *self)
129 {
130 	pcireg_t reg1, reg2;
131 	const char *s1;
132 
133 	reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC106_PICR1);
134 	reg2 = pci_conf_read(pa->pa_pc, pa->pa_tag, MPC106_PICR2);
135 	aprint_normal("%s: L2 cache: ", self->dv_xname);
136 
137 	switch (reg2 & MPC106_PICR2_L2_SIZE) {
138 	case MPC106_PICR2_L2_SIZE_256K:
139 		s1 = "256K";
140 		break;
141 	case MPC106_PICR2_L2_SIZE_512K:
142 		s1 = "512K";
143 		break;
144 	case MPC106_PICR2_L2_SIZE_1M:
145 		s1 = "1M";
146 		break;
147 	default:
148 		s1 = "reserved size";
149 		break;
150 	}
151 
152 	aprint_normal("%s, ", s1);
153 	switch (reg1 & MPC106_PICR1_EXT_L2_EN) {
154 	case 0:
155 		switch (reg1 & MPC106_PICR1_L2_MP) {
156 		case MPC106_PICR1_L2_MP_NONE:
157 			s1 = "uniprocessor/none";
158 			break;
159 		case MPC106_PICR1_L2_MP_WT:
160 			s1 = "internally controlled write-through";
161 			break;
162 		case MPC106_PICR1_L2_MP_WB:
163 			s1 = "internally controlled write-back";
164 			break;
165 		case MPC106_PICR1_L2_MP_MP:
166 			s1 = "multiprocessor/none";
167 			break;
168 		}
169 		break;
170 	case 1:
171 		switch (reg1 & MPC106_PICR1_L2_MP) {
172 		case MPC106_PICR1_L2_MP_NONE:
173 			s1 = "uniprocessor/external";
174 			break;
175 		case MPC106_PICR1_L2_MP_MP:
176 			s1 = "multiprocessors/external";
177 			break;
178 		default:
179 			s1 = "reserved";
180 			break;
181 		}
182 	}
183 	aprint_normal("%s mode\n", s1);
184 }
185 
186 static void
187 ibm82660_print(struct pci_attach_args *pa, struct device *self)
188 {
189 	pcireg_t reg1;
190 #ifdef PREP_BUS_SPACE_IO
191 	pcireg_t reg2;
192 #endif
193 	const char *s1, *s2;
194 
195 	reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag,
196 	    IBM_82660_CACHE_STATUS);
197 #ifdef PREP_BUS_SPACE_IO
198 	reg2 = in32rb(PREP_BUS_SPACE_IO+IBM_82660_SYSTEM_CTRL);
199 	if (reg2 & IBM_82660_SYSTEM_CTRL_L2_EN) {
200 		if (reg1 & IBM_82660_CACHE_STATUS_L2_EN)
201 			s1 = "internal enabled";
202 		else
203 			s1 = "enabled";
204 		if (reg2 & IBM_82660_SYSTEM_CTRL_L2_MI)
205 			s2 = "(normal operation)";
206 		else
207 			s2 = "(miss updates inhibited)";
208 	} else {
209 		s1 = "disabled";
210 		s2 = "";
211 	}
212 #else
213 	if (reg1 & IBM_82660_CACHE_STATUS_L2_EN)
214 		s1 = "enabled";
215 	else
216 		s1 = "disabled";
217 	s2 = "";
218 #endif
219 	aprint_normal("%s: L1: %s L2: %s %s\n", self->dv_xname,
220 	    (reg1 & IBM_82660_CACHE_STATUS_L1_EN) ? "enabled" : "disabled",
221 	    s1, s2);
222 
223 	reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, IBM_82660_OPTIONS_1);
224 	aprint_verbose("%s: MCP# assertion %s "
225 	    "TEA# assertion %s\n", self->dv_xname,
226 	    (reg1 & IBM_82660_OPTIONS_1_MCP) ? "enabled" : "disabled",
227 	    (reg1 & IBM_82660_OPTIONS_1_TEA) ? "enabled" : "disabled");
228 	aprint_verbose("%s: PCI/ISA I/O mapping %s\n", self->dv_xname,
229 	    (reg1 & IBM_82660_OPTIONS_1_ISA) ? "contiguous" : "non-contiguous");
230 
231 	reg1 = pci_conf_read(pa->pa_pc, pa->pa_tag, IBM_82660_OPTIONS_3);
232 	aprint_normal("%s: DRAM %s (%s) SRAM %s\n", self->dv_xname,
233 	    (reg1 & IBM_82660_OPTIONS_3_DRAM) ? "EDO" : "standard",
234 	    (reg1 & IBM_82660_OPTIONS_3_ECC) ? "ECC" : "parity",
235 	    (reg1 & IBM_82660_OPTIONS_3_SRAM) ? "sync" : "async");
236 	aprint_verbose("%s: Snoop mode %s\n", self->dv_xname,
237 	    (reg1 & IBM_82660_OPTIONS_3_SNOOP) ? "603" : "601/604");
238 }
239 
240 void
241 pchbattach(struct device *parent, struct device *self, void *aux)
242 {
243 	struct pci_attach_args *pa = aux;
244 	char devinfo[256];
245 #if NAGP > 0
246 	struct agpbus_attach_args apa;
247 #endif
248 
249 	printf("\n");
250 
251 	/*
252 	 * All we do is print out a description.  Eventually, we
253 	 * might want to add code that does something that's
254 	 * possibly chipset-specific.
255 	 */
256 
257 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
258 	printf("%s: %s (rev. 0x%02x)\n", self->dv_xname, devinfo,
259 	    PCI_REVISION(pa->pa_class));
260 
261 	switch (PCI_VENDOR(pa->pa_id)) {
262 	case PCI_VENDOR_IBM:
263 		switch (PCI_PRODUCT(pa->pa_id)) {
264 		case PCI_PRODUCT_IBM_82660:
265 			ibm82660_print(pa, self);
266 			break;
267 		}
268 		break;
269 	case PCI_VENDOR_MOT:
270 		switch (PCI_PRODUCT(pa->pa_id)) {
271 		case PCI_PRODUCT_MOT_MPC105:
272 			mpc105_print(pa, self);
273 			break;
274 		case PCI_PRODUCT_MOT_MPC106:
275 			mpc106_print(pa, self);
276 			break;
277 		}
278 		break;
279 	}
280 
281 #if NAGP > 0
282 	if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP,
283 			       NULL, NULL) != 0) {
284 		apa.apa_pci_args = *pa;
285 		config_found_ia(self, "agpbus", &apa, agpbusprint);
286 	}
287 #endif /* NAGP */
288 }
289