1 /* $NetBSD: pchb.c,v 1.4 2008/04/28 20:23:32 martin 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 * 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. 30 */ 31 32 #include <sys/cdefs.h> 33 __KERNEL_RCSID(0, "$NetBSD: pchb.c,v 1.4 2008/04/28 20:23:32 martin Exp $"); 34 35 #include <sys/types.h> 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/device.h> 39 40 #include <machine/bus.h> 41 #include <machine/pio.h> 42 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> 48 49 #include <dev/ic/mpc105reg.h> 50 #include <dev/ic/mpc106reg.h> 51 #include <dev/ic/ibm82660reg.h> 52 53 #include "agp.h" 54 55 int pchbmatch(struct device *, struct cfdata *, void *); 56 void pchbattach(struct device *, struct device *, void *); 57 58 CFATTACH_DECL(pchb, sizeof(struct device), 59 pchbmatch, pchbattach, NULL, NULL); 60 61 int 62 pchbmatch(struct device *parent, struct cfdata *cf, void *aux) 63 { 64 struct pci_attach_args *pa = aux; 65 66 /* 67 * Match all known PCI host chipsets. 68 */ 69 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 70 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_HOST) { 71 return (1); 72 } 73 74 return (0); 75 } 76 77 static void 78 mpc105_print(struct pci_attach_args *pa, struct device *self) 79 { 80 pcireg_t reg1, reg2; 81 const char *s1; 82 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); 86 87 switch (reg2 & MPC105_PICR2_L2_SIZE) { 88 case MPC105_PICR2_L2_SIZE_256K: 89 s1 = "256K"; 90 break; 91 case MPC105_PICR2_L2_SIZE_512K: 92 s1 = "512K"; 93 break; 94 case MPC105_PICR2_L2_SIZE_1M: 95 s1 = "1M"; 96 break; 97 default: 98 s1 = "reserved size"; 99 break; 100 } 101 102 aprint_normal("%s, ", s1); 103 switch (reg1 & MPC105_PICR1_L2_MP) { 104 case MPC105_PICR1_L2_MP_NONE: 105 s1 = "uniprocessor/none"; 106 break; 107 case MPC105_PICR1_L2_MP_WT: 108 s1 = "write-through"; 109 break; 110 case MPC105_PICR1_L2_MP_WB: 111 s1 = "write-back"; 112 break; 113 case MPC105_PICR1_L2_MP_MP: 114 s1 = "multiprocessor"; 115 break; 116 } 117 aprint_normal("%s mode\n", s1); 118 } 119 120 static void 121 mpc106_print(struct pci_attach_args *pa, struct device *self) 122 { 123 pcireg_t reg1, reg2; 124 const char *s1; 125 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); 129 130 switch (reg2 & MPC106_PICR2_L2_SIZE) { 131 case MPC106_PICR2_L2_SIZE_256K: 132 s1 = "256K"; 133 break; 134 case MPC106_PICR2_L2_SIZE_512K: 135 s1 = "512K"; 136 break; 137 case MPC106_PICR2_L2_SIZE_1M: 138 s1 = "1M"; 139 break; 140 default: 141 s1 = "reserved size"; 142 break; 143 } 144 145 aprint_normal("%s, ", s1); 146 switch (reg1 & MPC106_PICR1_EXT_L2_EN) { 147 case 0: 148 switch (reg1 & MPC106_PICR1_L2_MP) { 149 case MPC106_PICR1_L2_MP_NONE: 150 s1 = "uniprocessor/none"; 151 break; 152 case MPC106_PICR1_L2_MP_WT: 153 s1 = "internally controlled write-through"; 154 break; 155 case MPC106_PICR1_L2_MP_WB: 156 s1 = "internally controlled write-back"; 157 break; 158 case MPC106_PICR1_L2_MP_MP: 159 s1 = "multiprocessor/none"; 160 break; 161 } 162 break; 163 case 1: 164 switch (reg1 & MPC106_PICR1_L2_MP) { 165 case MPC106_PICR1_L2_MP_NONE: 166 s1 = "uniprocessor/external"; 167 break; 168 case MPC106_PICR1_L2_MP_MP: 169 s1 = "multiprocessors/external"; 170 break; 171 default: 172 s1 = "reserved"; 173 break; 174 } 175 } 176 aprint_normal("%s mode\n", s1); 177 } 178 179 static void 180 ibm82660_print(struct pci_attach_args *pa, struct device *self) 181 { 182 pcireg_t reg1; 183 #ifdef PREP_BUS_SPACE_IO 184 pcireg_t reg2; 185 #endif 186 const char *s1, *s2; 187 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"; 195 else 196 s1 = "enabled"; 197 if (reg2 & IBM_82660_SYSTEM_CTRL_L2_MI) 198 s2 = "(normal operation)"; 199 else 200 s2 = "(miss updates inhibited)"; 201 } else { 202 s1 = "disabled"; 203 s2 = ""; 204 } 205 #else 206 if (reg1 & IBM_82660_CACHE_STATUS_L2_EN) 207 s1 = "enabled"; 208 else 209 s1 = "disabled"; 210 s2 = ""; 211 #endif 212 aprint_normal("%s: L1: %s L2: %s %s\n", self->dv_xname, 213 (reg1 & IBM_82660_CACHE_STATUS_L1_EN) ? "enabled" : "disabled", 214 s1, s2); 215 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"); 223 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"); 231 } 232 233 void 234 pchbattach(struct device *parent, struct device *self, void *aux) 235 { 236 struct pci_attach_args *pa = aux; 237 char devinfo[256]; 238 #if NAGP > 0 239 struct agpbus_attach_args apa; 240 #endif 241 volatile unsigned char *python; 242 uint32_t v; 243 244 aprint_normal("\n"); 245 246 /* 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. 250 */ 251 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)); 255 256 switch (PCI_VENDOR(pa->pa_id)) { 257 case PCI_VENDOR_IBM: 258 switch (PCI_PRODUCT(pa->pa_id)) { 259 case PCI_PRODUCT_IBM_82660: 260 ibm82660_print(pa, self); 261 break; 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); 268 break; 269 } 270 break; 271 case PCI_VENDOR_MOT: 272 switch (PCI_PRODUCT(pa->pa_id)) { 273 case PCI_PRODUCT_MOT_MPC105: 274 mpc105_print(pa, self); 275 break; 276 case PCI_PRODUCT_MOT_MPC106: 277 mpc106_print(pa, self); 278 break; 279 } 280 break; 281 } 282 283 #if NAGP > 0 284 if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, 285 NULL, NULL) != 0) { 286 apa.apa_pci_args = *pa; 287 config_found_ia(self, "agpbus", &apa, agpbusprint); 288 } 289 #endif /* NAGP */ 290 } 291