1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2000 Doug Rabson 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, 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 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/param.h> 30 #include <sys/systm.h> 31 #include <sys/malloc.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <sys/bus.h> 35 #include <sys/lock.h> 36 #include <sys/mutex.h> 37 #include <sys/proc.h> 38 39 #include <dev/agp/agppriv.h> 40 #include <dev/agp/agpreg.h> 41 #include <dev/pci/pcivar.h> 42 #include <dev/pci/pcireg.h> 43 44 #include <vm/vm.h> 45 #include <vm/vm_object.h> 46 #include <vm/pmap.h> 47 48 #define MAX_APSIZE 0x3f /* 256 MB */ 49 50 struct agp_intel_softc { 51 struct agp_softc agp; 52 u_int32_t initial_aperture; /* aperture size at startup */ 53 struct agp_gatt *gatt; 54 u_int aperture_mask; 55 u_int32_t current_aperture; /* current aperture size */ 56 }; 57 58 static const char* 59 agp_intel_match(device_t dev) 60 { 61 if (pci_get_class(dev) != PCIC_BRIDGE 62 || pci_get_subclass(dev) != PCIS_BRIDGE_HOST) 63 return (NULL); 64 65 if (agp_find_caps(dev) == 0) 66 return (NULL); 67 68 switch (pci_get_devid(dev)) { 69 /* Intel -- vendor 0x8086 */ 70 case 0x71808086: 71 return ("Intel 82443LX (440 LX) host to PCI bridge"); 72 case 0x71908086: 73 return ("Intel 82443BX (440 BX) host to PCI bridge"); 74 case 0x71a08086: 75 return ("Intel 82443GX host to PCI bridge"); 76 case 0x71a18086: 77 return ("Intel 82443GX host to AGP bridge"); 78 case 0x11308086: 79 return ("Intel 82815 (i815 GMCH) host to PCI bridge"); 80 case 0x25008086: 81 case 0x25018086: 82 return ("Intel 82820 host to AGP bridge"); 83 case 0x35758086: 84 return ("Intel 82830 host to AGP bridge"); 85 case 0x1a218086: 86 return ("Intel 82840 host to AGP bridge"); 87 case 0x1a308086: 88 return ("Intel 82845 host to AGP bridge"); 89 case 0x25308086: 90 return ("Intel 82850 host to AGP bridge"); 91 case 0x33408086: 92 return ("Intel 82855 host to AGP bridge"); 93 case 0x25318086: 94 return ("Intel 82860 host to AGP bridge"); 95 case 0x25708086: 96 return ("Intel 82865 host to AGP bridge"); 97 case 0x255d8086: 98 return ("Intel E7205 host to AGP bridge"); 99 case 0x25508086: 100 return ("Intel E7505 host to AGP bridge"); 101 case 0x25788086: 102 return ("Intel 82875P host to AGP bridge"); 103 case 0x25608086: 104 return ("Intel 82845G host to AGP bridge"); 105 case 0x35808086: 106 return ("Intel 82855GM host to AGP bridge"); 107 } 108 109 return (NULL); 110 } 111 112 static int 113 agp_intel_probe(device_t dev) 114 { 115 const char *desc; 116 117 if (resource_disabled("agp", device_get_unit(dev))) 118 return (ENXIO); 119 desc = agp_intel_match(dev); 120 if (desc) { 121 device_set_desc(dev, desc); 122 return (BUS_PROBE_DEFAULT); 123 } 124 125 return (ENXIO); 126 } 127 128 static void 129 agp_intel_commit_gatt(device_t dev) 130 { 131 struct agp_intel_softc *sc; 132 u_int32_t type; 133 u_int32_t value; 134 135 sc = device_get_softc(dev); 136 type = pci_get_devid(dev); 137 138 /* Install the gatt. */ 139 pci_write_config(dev, AGP_INTEL_ATTBASE, sc->gatt->ag_physical, 4); 140 141 /* Enable the GLTB and setup the control register. */ 142 switch (type) { 143 case 0x71908086: /* 440LX/EX */ 144 pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4); 145 break; 146 case 0x71808086: /* 440BX */ 147 /* 148 * XXX: Should be 0xa080? Bit 9 is undefined, and 149 * bit 13 being on and bit 15 being clear is illegal. 150 */ 151 pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4); 152 break; 153 default: 154 value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4); 155 pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4); 156 } 157 158 /* Enable aperture accesses. */ 159 switch (type) { 160 case 0x25008086: /* i820 */ 161 case 0x25018086: /* i820 */ 162 pci_write_config(dev, AGP_INTEL_I820_RDCR, 163 (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1) 164 | (1 << 1)), 1); 165 break; 166 case 0x1a308086: /* i845 */ 167 case 0x25608086: /* i845G */ 168 case 0x33408086: /* i855 */ 169 case 0x35808086: /* i855GM */ 170 case 0x25708086: /* i865 */ 171 case 0x25788086: /* i875P */ 172 pci_write_config(dev, AGP_INTEL_I845_AGPM, 173 (pci_read_config(dev, AGP_INTEL_I845_AGPM, 1) 174 | (1 << 1)), 1); 175 break; 176 case 0x1a218086: /* i840 */ 177 case 0x25308086: /* i850 */ 178 case 0x25318086: /* i860 */ 179 case 0x255d8086: /* E7205 */ 180 case 0x25508086: /* E7505 */ 181 pci_write_config(dev, AGP_INTEL_MCHCFG, 182 (pci_read_config(dev, AGP_INTEL_MCHCFG, 2) 183 | (1 << 9)), 2); 184 break; 185 default: /* Intel Generic (maybe) */ 186 pci_write_config(dev, AGP_INTEL_NBXCFG, 187 (pci_read_config(dev, AGP_INTEL_NBXCFG, 4) 188 & ~(1 << 10)) | (1 << 9), 4); 189 } 190 191 /* Clear errors. */ 192 switch (type) { 193 case 0x1a218086: /* i840 */ 194 pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2); 195 break; 196 case 0x25008086: /* i820 */ 197 case 0x25018086: /* i820 */ 198 case 0x1a308086: /* i845 */ 199 case 0x25608086: /* i845G */ 200 case 0x25308086: /* i850 */ 201 case 0x33408086: /* i855 */ 202 case 0x25318086: /* i860 */ 203 case 0x25708086: /* i865 */ 204 case 0x25788086: /* i875P */ 205 case 0x255d8086: /* E7205 */ 206 case 0x25508086: /* E7505 */ 207 pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2); 208 break; 209 default: /* Intel Generic (maybe) */ 210 pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1); 211 } 212 } 213 214 static int 215 agp_intel_attach(device_t dev) 216 { 217 struct agp_intel_softc *sc; 218 struct agp_gatt *gatt; 219 u_int32_t value; 220 int error; 221 222 sc = device_get_softc(dev); 223 224 error = agp_generic_attach(dev); 225 if (error) 226 return (error); 227 228 /* Determine maximum supported aperture size. */ 229 value = pci_read_config(dev, AGP_INTEL_APSIZE, 1); 230 pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1); 231 sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & 232 MAX_APSIZE; 233 pci_write_config(dev, AGP_INTEL_APSIZE, value, 1); 234 sc->current_aperture = sc->initial_aperture = AGP_GET_APERTURE(dev); 235 236 for (;;) { 237 gatt = agp_alloc_gatt(dev); 238 if (gatt) 239 break; 240 241 /* 242 * Probably contigmalloc failure. Try reducing the 243 * aperture so that the gatt size reduces. 244 */ 245 if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) { 246 agp_generic_detach(dev); 247 return (ENOMEM); 248 } 249 } 250 sc->gatt = gatt; 251 252 agp_intel_commit_gatt(dev); 253 254 return (0); 255 } 256 257 static int 258 agp_intel_detach(device_t dev) 259 { 260 struct agp_intel_softc *sc; 261 u_int32_t reg; 262 263 sc = device_get_softc(dev); 264 265 agp_free_cdev(dev); 266 267 /* Disable aperture accesses. */ 268 switch (pci_get_devid(dev)) { 269 case 0x25008086: /* i820 */ 270 case 0x25018086: /* i820 */ 271 reg = pci_read_config(dev, AGP_INTEL_I820_RDCR, 1) & ~(1 << 1); 272 printf("%s: set RDCR to %02x\n", __func__, reg & 0xff); 273 pci_write_config(dev, AGP_INTEL_I820_RDCR, reg, 1); 274 break; 275 case 0x1a308086: /* i845 */ 276 case 0x25608086: /* i845G */ 277 case 0x33408086: /* i855 */ 278 case 0x35808086: /* i855GM */ 279 case 0x25708086: /* i865 */ 280 case 0x25788086: /* i875P */ 281 reg = pci_read_config(dev, AGP_INTEL_I845_AGPM, 1) & ~(1 << 1); 282 printf("%s: set AGPM to %02x\n", __func__, reg & 0xff); 283 pci_write_config(dev, AGP_INTEL_I845_AGPM, reg, 1); 284 break; 285 case 0x1a218086: /* i840 */ 286 case 0x25308086: /* i850 */ 287 case 0x25318086: /* i860 */ 288 case 0x255d8086: /* E7205 */ 289 case 0x25508086: /* E7505 */ 290 reg = pci_read_config(dev, AGP_INTEL_MCHCFG, 2) & ~(1 << 9); 291 printf("%s: set MCHCFG to %x04\n", __func__, reg & 0xffff); 292 pci_write_config(dev, AGP_INTEL_MCHCFG, reg, 2); 293 break; 294 default: /* Intel Generic (maybe) */ 295 reg = pci_read_config(dev, AGP_INTEL_NBXCFG, 4) & ~(1 << 9); 296 printf("%s: set NBXCFG to %08x\n", __func__, reg); 297 pci_write_config(dev, AGP_INTEL_NBXCFG, reg, 4); 298 } 299 pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4); 300 AGP_SET_APERTURE(dev, sc->initial_aperture); 301 agp_free_gatt(sc->gatt); 302 agp_free_res(dev); 303 304 return (0); 305 } 306 307 static int 308 agp_intel_resume(device_t dev) 309 { 310 struct agp_intel_softc *sc; 311 sc = device_get_softc(dev); 312 313 AGP_SET_APERTURE(dev, sc->current_aperture); 314 agp_intel_commit_gatt(dev); 315 return (bus_generic_resume(dev)); 316 } 317 318 static u_int32_t 319 agp_intel_get_aperture(device_t dev) 320 { 321 struct agp_intel_softc *sc; 322 u_int32_t apsize; 323 324 sc = device_get_softc(dev); 325 326 apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask; 327 328 /* 329 * The size is determined by the number of low bits of 330 * register APBASE which are forced to zero. The low 22 bits 331 * are always forced to zero and each zero bit in the apsize 332 * field just read forces the corresponding bit in the 27:22 333 * to be zero. We calculate the aperture size accordingly. 334 */ 335 return ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1); 336 } 337 338 static int 339 agp_intel_set_aperture(device_t dev, u_int32_t aperture) 340 { 341 struct agp_intel_softc *sc; 342 u_int32_t apsize; 343 344 sc = device_get_softc(dev); 345 346 /* 347 * Reverse the magic from get_aperture. 348 */ 349 apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask; 350 351 /* 352 * Double check for sanity. 353 */ 354 if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture) 355 return (EINVAL); 356 357 sc->current_aperture = apsize; 358 359 pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1); 360 361 return (0); 362 } 363 364 static int 365 agp_intel_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical) 366 { 367 struct agp_intel_softc *sc; 368 369 sc = device_get_softc(dev); 370 371 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 372 return (EINVAL); 373 374 sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17; 375 return (0); 376 } 377 378 static int 379 agp_intel_unbind_page(device_t dev, vm_offset_t offset) 380 { 381 struct agp_intel_softc *sc; 382 383 sc = device_get_softc(dev); 384 385 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 386 return (EINVAL); 387 388 sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0; 389 return (0); 390 } 391 392 static void 393 agp_intel_flush_tlb(device_t dev) 394 { 395 u_int32_t val; 396 397 val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4); 398 pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 7), 4); 399 pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4); 400 } 401 402 static device_method_t agp_intel_methods[] = { 403 /* Device interface */ 404 DEVMETHOD(device_probe, agp_intel_probe), 405 DEVMETHOD(device_attach, agp_intel_attach), 406 DEVMETHOD(device_detach, agp_intel_detach), 407 DEVMETHOD(device_shutdown, bus_generic_shutdown), 408 DEVMETHOD(device_suspend, bus_generic_suspend), 409 DEVMETHOD(device_resume, agp_intel_resume), 410 411 /* AGP interface */ 412 DEVMETHOD(agp_get_aperture, agp_intel_get_aperture), 413 DEVMETHOD(agp_set_aperture, agp_intel_set_aperture), 414 DEVMETHOD(agp_bind_page, agp_intel_bind_page), 415 DEVMETHOD(agp_unbind_page, agp_intel_unbind_page), 416 DEVMETHOD(agp_flush_tlb, agp_intel_flush_tlb), 417 DEVMETHOD(agp_enable, agp_generic_enable), 418 DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory), 419 DEVMETHOD(agp_free_memory, agp_generic_free_memory), 420 DEVMETHOD(agp_bind_memory, agp_generic_bind_memory), 421 DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory), 422 { 0, 0 } 423 }; 424 425 static driver_t agp_intel_driver = { 426 "agp", 427 agp_intel_methods, 428 sizeof(struct agp_intel_softc), 429 }; 430 431 DRIVER_MODULE(agp_intel, hostb, agp_intel_driver, 0, 0); 432 MODULE_DEPEND(agp_intel, agp, 1, 1, 1); 433 MODULE_DEPEND(agp_intel, pci, 1, 1, 1); 434