static int agp_nvidia_detach (device_t dev) { struct agp_nvidia_softc *sc = device_get_softc(dev); u_int32_t temp; agp_free_cdev(dev); /* GART Control */ temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4); pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp & ~(0x100), 4); /* GTLB Control */ temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4); pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp & ~(0x11), 4); /* Put the aperture back the way it started. */ AGP_SET_APERTURE(dev, sc->initial_aperture); /* restore iorr for previous aperture size */ nvidia_init_iorr(rman_get_start(sc->agp.as_aperture), sc->initial_aperture); agp_free_gatt(sc->gatt); agp_free_res(dev); return (0); }
static int agp_via_detach(struct agp_softc *sc) { struct agp_via_softc *asc = sc->as_chipc; int error; error = agp_generic_detach(sc); if (error) return error; pci_conf_write(sc->as_pc, sc->as_tag, asc->regs[REG_GARTCTRL], 0); pci_conf_write(sc->as_pc, sc->as_tag, asc->regs[REG_ATTBASE], 0); AGP_SET_APERTURE(sc, asc->initial_aperture); agp_free_gatt(sc, asc->gatt); return 0; }
static int agp_nvidia_attach (device_t dev) { struct agp_nvidia_softc *sc = device_get_softc(dev); struct agp_gatt *gatt; u_int32_t apbase; u_int32_t aplimit; u_int32_t temp; int size; int i; int error; switch (pci_get_device(dev)) { case NVIDIA_DEVICEID_NFORCE: sc->wbc_mask = 0x00010000; break; case NVIDIA_DEVICEID_NFORCE2: sc->wbc_mask = 0x80000000; break; default: device_printf(dev, "Bad chip id\n"); return (ENODEV); } /* AGP Controller */ sc->dev = dev; /* Memory Controller 1 */ sc->mc1_dev = pci_find_bsf(pci_get_bus(dev), 0, 1); if (sc->mc1_dev == NULL) { device_printf(dev, "Unable to find NVIDIA Memory Controller 1.\n"); return (ENODEV); } /* Memory Controller 2 */ sc->mc2_dev = pci_find_bsf(pci_get_bus(dev), 0, 2); if (sc->mc2_dev == NULL) { device_printf(dev, "Unable to find NVIDIA Memory Controller 2.\n"); return (ENODEV); } /* AGP Host to PCI Bridge */ sc->bdev = pci_find_bsf(pci_get_bus(dev), 30, 0); if (sc->bdev == NULL) { device_printf(dev, "Unable to find NVIDIA AGP Host to PCI Bridge.\n"); return (ENODEV); } error = agp_generic_attach(dev); if (error) return (error); sc->initial_aperture = AGP_GET_APERTURE(dev); if (sc->initial_aperture == 0) { device_printf(dev, "bad initial aperture size, disabling\n"); return ENXIO; } for (;;) { gatt = agp_alloc_gatt(dev); if (gatt) break; /* * Probably contigmalloc failure. Try reducing the * aperture so that the gatt size reduces. */ if (AGP_SET_APERTURE(dev, AGP_GET_APERTURE(dev) / 2)) goto fail; } sc->gatt = gatt; apbase = rman_get_start(sc->agp.as_aperture); aplimit = apbase + AGP_GET_APERTURE(dev) - 1; pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APBASE, apbase, 4); pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_APLIMIT, aplimit, 4); pci_write_config(sc->bdev, AGP_NVIDIA_3_APBASE, apbase, 4); pci_write_config(sc->bdev, AGP_NVIDIA_3_APLIMIT, aplimit, 4); error = nvidia_init_iorr(apbase, AGP_GET_APERTURE(dev)); if (error) { device_printf(dev, "Failed to setup IORRs\n"); goto fail; } /* directory size is 64k */ size = AGP_GET_APERTURE(dev) / 1024 / 1024; sc->num_dirs = size / 64; sc->num_active_entries = (size == 32) ? 16384 : ((size * 1024) / 4); sc->pg_offset = 0; if (sc->num_dirs == 0) { sc->num_dirs = 1; sc->num_active_entries /= (64 / size); sc->pg_offset = (apbase & (64 * 1024 * 1024 - 1) & ~(AGP_GET_APERTURE(dev) - 1)) / PAGE_SIZE; } /* (G)ATT Base Address */ for (i = 0; i < 8; i++) { pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_ATTBASE(i), (sc->gatt->ag_physical + (i % sc->num_dirs) * 64 * 1024) | 1, 4); } /* GTLB Control */ temp = pci_read_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, 4); pci_write_config(sc->mc2_dev, AGP_NVIDIA_2_GARTCTRL, temp | 0x11, 4); /* GART Control */ temp = pci_read_config(sc->dev, AGP_NVIDIA_0_APSIZE, 4); pci_write_config(sc->dev, AGP_NVIDIA_0_APSIZE, temp | 0x100, 4); return (0); fail: agp_generic_detach(dev); return (ENOMEM); }
int agp_via_attach(device_t parent, device_t self, void *aux) { struct pci_attach_args *pa = aux; struct agp_softc *sc = device_private(self); struct agp_via_softc *asc; struct agp_gatt *gatt; pcireg_t agpsel, capval; asc = malloc(sizeof *asc, M_AGP, M_NOWAIT|M_ZERO); if (asc == NULL) { aprint_error(": can't allocate chipset-specific softc\n"); return ENOMEM; } sc->as_chipc = asc; sc->as_methods = &agp_via_methods; pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_AGP, &sc->as_capoff, &capval); if (PCI_CAP_AGP_MAJOR(capval) >= 3) { agpsel = pci_conf_read(pa->pa_pc, pa->pa_tag, AGP_VIA_AGPSEL); if ((agpsel & (1 << 9)) == 0) { asc->regs = via_v3_regs; aprint_debug(" (v3)"); } else { asc->regs = via_v2_regs; aprint_debug(" (v2 compat mode)"); } } else { asc->regs = via_v2_regs; aprint_debug(" (v2)"); } if (agp_map_aperture(pa, sc, AGP_APBASE) != 0) { aprint_error(": can't map aperture\n"); free(asc, M_AGP); return ENXIO; } asc->initial_aperture = AGP_GET_APERTURE(sc); for (;;) { gatt = agp_alloc_gatt(sc); if (gatt) break; /* * Probably contigmalloc failure. Try reducing the * aperture so that the gatt size reduces. */ if (AGP_SET_APERTURE(sc, AGP_GET_APERTURE(sc) / 2)) { agp_generic_detach(sc); aprint_error(": can't set aperture size\n"); return ENOMEM; } } asc->gatt = gatt; if (asc->regs == via_v2_regs) { /* Install the gatt. */ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_ATTBASE], gatt->ag_physical | 3); /* Enable the aperture. */ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_GARTCTRL], 0x0000000f); } else { pcireg_t gartctrl; /* Install the gatt. */ pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_ATTBASE], gatt->ag_physical); /* Enable the aperture. */ gartctrl = pci_conf_read(pa->pa_pc, pa->pa_tag, asc->regs[REG_GARTCTRL]); pci_conf_write(pa->pa_pc, pa->pa_tag, asc->regs[REG_GARTCTRL], gartctrl | (3 << 7)); } return 0; }