161452Sdfr/*- 261452Sdfr * Copyright (c) 2000 Doug Rabson 361452Sdfr * All rights reserved. 461452Sdfr * 561452Sdfr * Redistribution and use in source and binary forms, with or without 661452Sdfr * modification, are permitted provided that the following conditions 761452Sdfr * are met: 861452Sdfr * 1. Redistributions of source code must retain the above copyright 961452Sdfr * notice, this list of conditions and the following disclaimer. 1061452Sdfr * 2. Redistributions in binary form must reproduce the above copyright 1161452Sdfr * notice, this list of conditions and the following disclaimer in the 1261452Sdfr * documentation and/or other materials provided with the distribution. 1361452Sdfr * 1461452Sdfr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1561452Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1661452Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1761452Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1861452Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1961452Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2061452Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2161452Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2261452Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2361452Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2461452Sdfr * SUCH DAMAGE. 2561452Sdfr */ 2661452Sdfr 27116192Sobrien#include <sys/cdefs.h> 28116192Sobrien__FBSDID("$FreeBSD$"); 29116192Sobrien 3061452Sdfr#include <sys/param.h> 3161452Sdfr#include <sys/systm.h> 3261452Sdfr#include <sys/malloc.h> 3361452Sdfr#include <sys/kernel.h> 34129878Sphk#include <sys/module.h> 3561452Sdfr#include <sys/bus.h> 3661452Sdfr#include <sys/lock.h> 3776827Salfred#include <sys/mutex.h> 3879339Sjhb#include <sys/proc.h> 3961452Sdfr 40173573Sjhb#include <dev/agp/agppriv.h> 41173573Sjhb#include <dev/agp/agpreg.h> 42119288Simp#include <dev/pci/pcivar.h> 43119288Simp#include <dev/pci/pcireg.h> 4461452Sdfr 4561452Sdfr#include <vm/vm.h> 4661452Sdfr#include <vm/vm_object.h> 4761452Sdfr#include <vm/pmap.h> 4861452Sdfr 49115355Sjhb#define MAX_APSIZE 0x3f /* 256 MB */ 50115355Sjhb 5161452Sdfrstruct agp_intel_softc { 5261452Sdfr struct agp_softc agp; 5361452Sdfr u_int32_t initial_aperture; /* aperture size at startup */ 5461452Sdfr struct agp_gatt *gatt; 55115355Sjhb u_int aperture_mask; 56165826Stakawata u_int32_t current_aperture; /* current aperture size */ 5761452Sdfr}; 5861452Sdfr 5961452Sdfrstatic const char* 6061452Sdfragp_intel_match(device_t dev) 6161452Sdfr{ 6261452Sdfr if (pci_get_class(dev) != PCIC_BRIDGE 6361452Sdfr || pci_get_subclass(dev) != PCIS_BRIDGE_HOST) 64165811Sjkim return (NULL); 6561452Sdfr 6661452Sdfr if (agp_find_caps(dev) == 0) 67165811Sjkim return (NULL); 6861452Sdfr 6961452Sdfr switch (pci_get_devid(dev)) { 7061452Sdfr /* Intel -- vendor 0x8086 */ 7161452Sdfr case 0x71808086: 7261452Sdfr return ("Intel 82443LX (440 LX) host to PCI bridge"); 7361452Sdfr case 0x71908086: 7461452Sdfr return ("Intel 82443BX (440 BX) host to PCI bridge"); 7561452Sdfr case 0x71a08086: 7661452Sdfr return ("Intel 82443GX host to PCI bridge"); 7761452Sdfr case 0x71a18086: 7861452Sdfr return ("Intel 82443GX host to AGP bridge"); 7967379Sache case 0x11308086: 8067379Sache return ("Intel 82815 (i815 GMCH) host to PCI bridge"); 8186192Skuriyama case 0x25008086: 82109115Sanholt case 0x25018086: 8386192Skuriyama return ("Intel 82820 host to AGP bridge"); 8490270Sbenno case 0x35758086: 8590270Sbenno return ("Intel 82830 host to AGP bridge"); 8686192Skuriyama case 0x1a218086: 8786192Skuriyama return ("Intel 82840 host to AGP bridge"); 8886192Skuriyama case 0x1a308086: 8986192Skuriyama return ("Intel 82845 host to AGP bridge"); 9086192Skuriyama case 0x25308086: 9186192Skuriyama return ("Intel 82850 host to AGP bridge"); 92116722Smdodd case 0x33408086: 93116722Smdodd return ("Intel 82855 host to AGP bridge"); 9486192Skuriyama case 0x25318086: 9586192Skuriyama return ("Intel 82860 host to AGP bridge"); 96115349Sjhb case 0x25708086: 97115349Sjhb return ("Intel 82865 host to AGP bridge"); 98134144Sanholt case 0x255d8086: 99134144Sanholt return ("Intel E7205 host to AGP bridge"); 100155772Sanholt case 0x25508086: 101155772Sanholt return ("Intel E7505 host to AGP bridge"); 102116722Smdodd case 0x25788086: 103116722Smdodd return ("Intel 82875P host to AGP bridge"); 104152914Sanholt case 0x25608086: 105126922Speadar return ("Intel 82845G host to AGP bridge"); 106152914Sanholt case 0x35808086: 107152914Sanholt return ("Intel 82855GM host to AGP bridge"); 108244926Santoine } 10961452Sdfr 110165811Sjkim return (NULL); 11161452Sdfr} 11261452Sdfr 11361452Sdfrstatic int 11461452Sdfragp_intel_probe(device_t dev) 11561452Sdfr{ 11661452Sdfr const char *desc; 11761452Sdfr 118241885Seadler if (resource_disabled("agp", device_get_unit(dev))) 119241885Seadler return (ENXIO); 12061452Sdfr desc = agp_intel_match(dev); 12161452Sdfr if (desc) { 12261452Sdfr device_set_desc(dev, desc); 123165811Sjkim return (BUS_PROBE_DEFAULT); 12461452Sdfr } 12561452Sdfr 126165811Sjkim return (ENXIO); 12761452Sdfr} 12861452Sdfr 129165811Sjkimstatic void 130165811Sjkimagp_intel_commit_gatt(device_t dev) 13161452Sdfr{ 132165811Sjkim struct agp_intel_softc *sc; 133165811Sjkim u_int32_t type; 134115354Sjhb u_int32_t value; 13561452Sdfr 136165811Sjkim sc = device_get_softc(dev); 137165811Sjkim type = pci_get_devid(dev); 138165811Sjkim 13961452Sdfr /* Install the gatt. */ 140165811Sjkim pci_write_config(dev, AGP_INTEL_ATTBASE, sc->gatt->ag_physical, 4); 141115355Sjhb 142100212Sjhb /* Enable the GLTB and setup the control register. */ 143100212Sjhb switch (type) { 144100212Sjhb case 0x71908086: /* 440LX/EX */ 145100212Sjhb pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2080, 4); 146100212Sjhb break; 147100212Sjhb case 0x71808086: /* 440BX */ 148100212Sjhb /* 149100212Sjhb * XXX: Should be 0xa080? Bit 9 is undefined, and 150100212Sjhb * bit 13 being on and bit 15 being clear is illegal. 151100212Sjhb */ 152100212Sjhb pci_write_config(dev, AGP_INTEL_AGPCTRL, 0x2280, 4); 153100212Sjhb break; 154100212Sjhb default: 155115349Sjhb value = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4); 156115349Sjhb pci_write_config(dev, AGP_INTEL_AGPCTRL, value | 0x80, 4); 157100212Sjhb } 158100212Sjhb 159165815Sjkim /* Enable aperture accesses. */ 16086192Skuriyama switch (type) { 16186192Skuriyama case 0x25008086: /* i820 */ 162109115Sanholt case 0x25018086: /* i820 */ 16386192Skuriyama pci_write_config(dev, AGP_INTEL_I820_RDCR, 16486192Skuriyama (pci_read_config(dev, AGP_INTEL_I820_RDCR, 1) 16586192Skuriyama | (1 << 1)), 1); 16686192Skuriyama break; 16786192Skuriyama case 0x1a308086: /* i845 */ 168165815Sjkim case 0x25608086: /* i845G */ 169116722Smdodd case 0x33408086: /* i855 */ 170152914Sanholt case 0x35808086: /* i855GM */ 171115349Sjhb case 0x25708086: /* i865 */ 172116722Smdodd case 0x25788086: /* i875P */ 173165815Sjkim pci_write_config(dev, AGP_INTEL_I845_AGPM, 174165815Sjkim (pci_read_config(dev, AGP_INTEL_I845_AGPM, 1) 17586192Skuriyama | (1 << 1)), 1); 17686192Skuriyama break; 177165815Sjkim case 0x1a218086: /* i840 */ 178165815Sjkim case 0x25308086: /* i850 */ 179165815Sjkim case 0x25318086: /* i860 */ 180165815Sjkim case 0x255d8086: /* E7205 */ 181165815Sjkim case 0x25508086: /* E7505 */ 182165815Sjkim pci_write_config(dev, AGP_INTEL_MCHCFG, 183165815Sjkim (pci_read_config(dev, AGP_INTEL_MCHCFG, 2) 184165815Sjkim | (1 << 9)), 2); 185165815Sjkim break; 18686192Skuriyama default: /* Intel Generic (maybe) */ 18786192Skuriyama pci_write_config(dev, AGP_INTEL_NBXCFG, 18886192Skuriyama (pci_read_config(dev, AGP_INTEL_NBXCFG, 4) 18986192Skuriyama & ~(1 << 10)) | (1 << 9), 4); 19086192Skuriyama } 19186192Skuriyama 192165815Sjkim /* Clear errors. */ 19386192Skuriyama switch (type) { 19486192Skuriyama case 0x1a218086: /* i840 */ 19586192Skuriyama pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0xc000, 2); 19686192Skuriyama break; 19786192Skuriyama case 0x25008086: /* i820 */ 198109115Sanholt case 0x25018086: /* i820 */ 19986192Skuriyama case 0x1a308086: /* i845 */ 200165815Sjkim case 0x25608086: /* i845G */ 20186192Skuriyama case 0x25308086: /* i850 */ 202116722Smdodd case 0x33408086: /* i855 */ 20386192Skuriyama case 0x25318086: /* i860 */ 204115349Sjhb case 0x25708086: /* i865 */ 205116722Smdodd case 0x25788086: /* i875P */ 206165815Sjkim case 0x255d8086: /* E7205 */ 207165815Sjkim case 0x25508086: /* E7505 */ 208115349Sjhb pci_write_config(dev, AGP_INTEL_I8XX_ERRSTS, 0x00ff, 2); 20986192Skuriyama break; 21086192Skuriyama default: /* Intel Generic (maybe) */ 21186192Skuriyama pci_write_config(dev, AGP_INTEL_ERRSTS + 1, 7, 1); 21286192Skuriyama } 213165805Stakawata} 21486192Skuriyama 215165805Stakawatastatic int 216165805Stakawataagp_intel_attach(device_t dev) 217165805Stakawata{ 218165811Sjkim struct agp_intel_softc *sc; 219165805Stakawata struct agp_gatt *gatt; 220165805Stakawata u_int32_t value; 221165805Stakawata int error; 222165805Stakawata 223165811Sjkim sc = device_get_softc(dev); 224165811Sjkim 225165805Stakawata error = agp_generic_attach(dev); 226165805Stakawata if (error) 227165811Sjkim return (error); 228165805Stakawata 229165805Stakawata /* Determine maximum supported aperture size. */ 230165805Stakawata value = pci_read_config(dev, AGP_INTEL_APSIZE, 1); 231165805Stakawata pci_write_config(dev, AGP_INTEL_APSIZE, MAX_APSIZE, 1); 232165805Stakawata sc->aperture_mask = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & 233165805Stakawata MAX_APSIZE; 234165805Stakawata pci_write_config(dev, AGP_INTEL_APSIZE, value, 1); 235165826Stakawata sc->current_aperture = sc->initial_aperture = AGP_GET_APERTURE(dev); 236165805Stakawata 237165805Stakawata for (;;) { 238165805Stakawata gatt = agp_alloc_gatt(dev); 239165805Stakawata if (gatt) 240165805Stakawata break; 241165805Stakawata 242165805Stakawata /* 243165805Stakawata * Probably contigmalloc failure. Try reducing the 244165805Stakawata * aperture so that the gatt size reduces. 245165805Stakawata */ 246165805Stakawata if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) { 247165805Stakawata agp_generic_detach(dev); 248165811Sjkim return (ENOMEM); 249165805Stakawata } 250165805Stakawata } 251165805Stakawata sc->gatt = gatt; 252165811Sjkim 253165805Stakawata agp_intel_commit_gatt(dev); 254165811Sjkim 255165811Sjkim return (0); 25661452Sdfr} 25761452Sdfr 25861452Sdfrstatic int 25961452Sdfragp_intel_detach(device_t dev) 26061452Sdfr{ 261165811Sjkim struct agp_intel_softc *sc; 262165815Sjkim u_int32_t reg; 26361452Sdfr 264165811Sjkim sc = device_get_softc(dev); 265165811Sjkim 266173203Sjhb agp_free_cdev(dev); 26761452Sdfr 268165815Sjkim /* Disable aperture accesses. */ 269165811Sjkim switch (pci_get_devid(dev)) { 27086192Skuriyama case 0x25008086: /* i820 */ 271109115Sanholt case 0x25018086: /* i820 */ 272165815Sjkim reg = pci_read_config(dev, AGP_INTEL_I820_RDCR, 1) & ~(1 << 1); 273165815Sjkim printf("%s: set RDCR to %02x\n", __func__, reg & 0xff); 274165815Sjkim pci_write_config(dev, AGP_INTEL_I820_RDCR, reg, 1); 275165815Sjkim break; 27686192Skuriyama case 0x1a308086: /* i845 */ 277126922Speadar case 0x25608086: /* i845G */ 278116722Smdodd case 0x33408086: /* i855 */ 279152914Sanholt case 0x35808086: /* i855GM */ 280165815Sjkim case 0x25708086: /* i865 */ 281165815Sjkim case 0x25788086: /* i875P */ 282165815Sjkim reg = pci_read_config(dev, AGP_INTEL_I845_AGPM, 1) & ~(1 << 1); 283165815Sjkim printf("%s: set AGPM to %02x\n", __func__, reg & 0xff); 284165815Sjkim pci_write_config(dev, AGP_INTEL_I845_AGPM, reg, 1); 285165815Sjkim break; 286165815Sjkim case 0x1a218086: /* i840 */ 287165815Sjkim case 0x25308086: /* i850 */ 288165815Sjkim case 0x25318086: /* i860 */ 289134144Sanholt case 0x255d8086: /* E7205 */ 290155772Sanholt case 0x25508086: /* E7505 */ 291165815Sjkim reg = pci_read_config(dev, AGP_INTEL_MCHCFG, 2) & ~(1 << 9); 292165815Sjkim printf("%s: set MCHCFG to %x04\n", __func__, reg & 0xffff); 293165815Sjkim pci_write_config(dev, AGP_INTEL_MCHCFG, reg, 2); 294165815Sjkim break; 29586192Skuriyama default: /* Intel Generic (maybe) */ 296165815Sjkim reg = pci_read_config(dev, AGP_INTEL_NBXCFG, 4) & ~(1 << 9); 297165815Sjkim printf("%s: set NBXCFG to %08x\n", __func__, reg); 298165815Sjkim pci_write_config(dev, AGP_INTEL_NBXCFG, reg, 4); 29986192Skuriyama } 30061452Sdfr pci_write_config(dev, AGP_INTEL_ATTBASE, 0, 4); 30161452Sdfr AGP_SET_APERTURE(dev, sc->initial_aperture); 30261452Sdfr agp_free_gatt(sc->gatt); 303173203Sjhb agp_free_res(dev); 30461452Sdfr 305165811Sjkim return (0); 30661452Sdfr} 30761452Sdfr 308165811Sjkimstatic int 309165811Sjkimagp_intel_resume(device_t dev) 310165805Stakawata{ 311165826Stakawata struct agp_intel_softc *sc; 312165826Stakawata sc = device_get_softc(dev); 313165826Stakawata 314165826Stakawata AGP_SET_APERTURE(dev, sc->current_aperture); 315165805Stakawata agp_intel_commit_gatt(dev); 316165811Sjkim return (bus_generic_resume(dev)); 317165805Stakawata} 318165805Stakawata 31961452Sdfrstatic u_int32_t 32061452Sdfragp_intel_get_aperture(device_t dev) 32161452Sdfr{ 322165811Sjkim struct agp_intel_softc *sc; 32361452Sdfr u_int32_t apsize; 32461452Sdfr 325165811Sjkim sc = device_get_softc(dev); 326165811Sjkim 327115355Sjhb apsize = pci_read_config(dev, AGP_INTEL_APSIZE, 1) & sc->aperture_mask; 32861452Sdfr 32961452Sdfr /* 33061452Sdfr * The size is determined by the number of low bits of 33161452Sdfr * register APBASE which are forced to zero. The low 22 bits 33261452Sdfr * are always forced to zero and each zero bit in the apsize 33361452Sdfr * field just read forces the corresponding bit in the 27:22 33461452Sdfr * to be zero. We calculate the aperture size accordingly. 33561452Sdfr */ 336165811Sjkim return ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1); 33761452Sdfr} 33861452Sdfr 33961452Sdfrstatic int 34061452Sdfragp_intel_set_aperture(device_t dev, u_int32_t aperture) 34161452Sdfr{ 342165811Sjkim struct agp_intel_softc *sc; 34361452Sdfr u_int32_t apsize; 34461452Sdfr 345165811Sjkim sc = device_get_softc(dev); 346165811Sjkim 34761452Sdfr /* 34861452Sdfr * Reverse the magic from get_aperture. 34961452Sdfr */ 350115355Sjhb apsize = ((aperture - 1) >> 22) ^ sc->aperture_mask; 35161452Sdfr 35261452Sdfr /* 35361452Sdfr * Double check for sanity. 35461452Sdfr */ 355115355Sjhb if ((((apsize ^ sc->aperture_mask) << 22) | ((1 << 22) - 1)) + 1 != aperture) 356165811Sjkim return (EINVAL); 35761452Sdfr 358165826Stakawata sc->current_aperture = apsize; 359165826Stakawata 36061452Sdfr pci_write_config(dev, AGP_INTEL_APSIZE, apsize, 1); 36161452Sdfr 362165811Sjkim return (0); 36361452Sdfr} 36461452Sdfr 36561452Sdfrstatic int 366189578Simpagp_intel_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical) 36761452Sdfr{ 368165811Sjkim struct agp_intel_softc *sc; 36961452Sdfr 370165811Sjkim sc = device_get_softc(dev); 371165811Sjkim 372190169Srnoland if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 373165811Sjkim return (EINVAL); 37461452Sdfr 37561452Sdfr sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical | 0x17; 376165811Sjkim return (0); 37761452Sdfr} 37861452Sdfr 37961452Sdfrstatic int 380189578Simpagp_intel_unbind_page(device_t dev, vm_offset_t offset) 38161452Sdfr{ 382165811Sjkim struct agp_intel_softc *sc; 38361452Sdfr 384165811Sjkim sc = device_get_softc(dev); 385165811Sjkim 386190169Srnoland if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) 387165811Sjkim return (EINVAL); 38861452Sdfr 38961452Sdfr sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0; 390165811Sjkim return (0); 39161452Sdfr} 39261452Sdfr 39361452Sdfrstatic void 39461452Sdfragp_intel_flush_tlb(device_t dev) 39561452Sdfr{ 396100212Sjhb u_int32_t val; 397100212Sjhb 398100212Sjhb val = pci_read_config(dev, AGP_INTEL_AGPCTRL, 4); 399120144Sanholt pci_write_config(dev, AGP_INTEL_AGPCTRL, val & ~(1 << 7), 4); 400100212Sjhb pci_write_config(dev, AGP_INTEL_AGPCTRL, val, 4); 40161452Sdfr} 40261452Sdfr 40361452Sdfrstatic device_method_t agp_intel_methods[] = { 40461452Sdfr /* Device interface */ 40561452Sdfr DEVMETHOD(device_probe, agp_intel_probe), 40661452Sdfr DEVMETHOD(device_attach, agp_intel_attach), 40761452Sdfr DEVMETHOD(device_detach, agp_intel_detach), 40861452Sdfr DEVMETHOD(device_shutdown, bus_generic_shutdown), 40961452Sdfr DEVMETHOD(device_suspend, bus_generic_suspend), 410165805Stakawata DEVMETHOD(device_resume, agp_intel_resume), 41161452Sdfr 41261452Sdfr /* AGP interface */ 41361452Sdfr DEVMETHOD(agp_get_aperture, agp_intel_get_aperture), 41461452Sdfr DEVMETHOD(agp_set_aperture, agp_intel_set_aperture), 41561452Sdfr DEVMETHOD(agp_bind_page, agp_intel_bind_page), 41661452Sdfr DEVMETHOD(agp_unbind_page, agp_intel_unbind_page), 41761452Sdfr DEVMETHOD(agp_flush_tlb, agp_intel_flush_tlb), 41861452Sdfr DEVMETHOD(agp_enable, agp_generic_enable), 41961452Sdfr DEVMETHOD(agp_alloc_memory, agp_generic_alloc_memory), 42061452Sdfr DEVMETHOD(agp_free_memory, agp_generic_free_memory), 42161452Sdfr DEVMETHOD(agp_bind_memory, agp_generic_bind_memory), 42261452Sdfr DEVMETHOD(agp_unbind_memory, agp_generic_unbind_memory), 42361452Sdfr 42461452Sdfr { 0, 0 } 42561452Sdfr}; 42661452Sdfr 42761452Sdfrstatic driver_t agp_intel_driver = { 42861452Sdfr "agp", 42961452Sdfr agp_intel_methods, 43061452Sdfr sizeof(struct agp_intel_softc), 43161452Sdfr}; 43261452Sdfr 43361452Sdfrstatic devclass_t agp_devclass; 43461452Sdfr 435153572SjhbDRIVER_MODULE(agp_intel, hostb, agp_intel_driver, agp_devclass, 0, 0); 436113506SmdoddMODULE_DEPEND(agp_intel, agp, 1, 1, 1); 437113506SmdoddMODULE_DEPEND(agp_intel, pci, 1, 1, 1); 438