Lines Matching +full:pci +full:- +full:dev
1 /*-
35 #include <dev/ofw/openfirm.h>
36 #include <dev/ofw/ofw_pci.h>
37 #include <dev/ofw/ofw_bus.h>
38 #include <dev/ofw/ofw_bus_subr.h>
39 #include <dev/ofw/ofwpci.h>
41 #include <dev/pci/pcivar.h>
42 #include <dev/pci/pcireg.h>
43 #include <dev/pci/pcib_private.h>
141 ofw_pcib_init(device_t dev) in ofw_pcib_init() argument
150 node = ofw_bus_get_node(dev); in ofw_pcib_init()
151 sc = device_get_softc(dev); in ofw_pcib_init()
152 sc->sc_initialized = 1; in ofw_pcib_init()
153 sc->sc_range = NULL; in ofw_pcib_init()
154 sc->sc_pci_domain = device_get_unit(dev); in ofw_pcib_init()
159 sc->sc_cell_info = cell_info; in ofw_pcib_init()
161 if (OF_getencprop(node, "bus-range", busrange, sizeof(busrange)) != 8) in ofw_pcib_init()
164 sc->sc_dev = dev; in ofw_pcib_init()
165 sc->sc_node = node; in ofw_pcib_init()
166 sc->sc_bus = busrange[0]; in ofw_pcib_init()
168 if (sc->sc_quirks & OFW_PCI_QUIRK_RANGES_ON_CHILDREN) { in ofw_pcib_init()
172 sc->sc_nrange = 0; in ofw_pcib_init()
176 sc->sc_nrange += n; in ofw_pcib_init()
178 if (sc->sc_nrange == 0) { in ofw_pcib_init()
182 sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]), in ofw_pcib_init()
186 n = ofw_pcib_fill_ranges(c, &sc->sc_range[i]); in ofw_pcib_init()
190 KASSERT(i == sc->sc_nrange, ("range count mismatch")); in ofw_pcib_init()
192 sc->sc_nrange = ofw_pcib_nranges(node, cell_info); in ofw_pcib_init()
193 if (sc->sc_nrange <= 0) { in ofw_pcib_init()
194 device_printf(dev, "could not getranges\n"); in ofw_pcib_init()
198 sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]), in ofw_pcib_init()
200 ofw_pcib_fill_ranges(node, sc->sc_range); in ofw_pcib_init()
203 sc->sc_io_rman.rm_type = RMAN_ARRAY; in ofw_pcib_init()
204 sc->sc_io_rman.rm_descr = "PCI I/O Ports"; in ofw_pcib_init()
205 error = rman_init(&sc->sc_io_rman); in ofw_pcib_init()
207 device_printf(dev, "rman_init() failed. error = %d\n", error); in ofw_pcib_init()
211 sc->sc_mem_rman.rm_type = RMAN_ARRAY; in ofw_pcib_init()
212 sc->sc_mem_rman.rm_descr = "PCI Non Prefetchable Memory"; in ofw_pcib_init()
213 error = rman_init(&sc->sc_mem_rman); in ofw_pcib_init()
215 device_printf(dev, "rman_init() failed. error = %d\n", error); in ofw_pcib_init()
219 sc->sc_pmem_rman.rm_type = RMAN_ARRAY; in ofw_pcib_init()
220 sc->sc_pmem_rman.rm_descr = "PCI Prefetchable Memory"; in ofw_pcib_init()
221 error = rman_init(&sc->sc_pmem_rman); in ofw_pcib_init()
223 device_printf(dev, "rman_init() failed. error = %d\n", error); in ofw_pcib_init()
227 for (i = 0; i < sc->sc_nrange; i++) { in ofw_pcib_init()
229 rp = sc->sc_range + i; in ofw_pcib_init()
231 if (sc->sc_range_mask & ((uint64_t)1 << i)) in ofw_pcib_init()
233 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { in ofw_pcib_init()
237 error = rman_manage_region(&sc->sc_io_rman, rp->pci, in ofw_pcib_init()
238 rp->pci + rp->size - 1); in ofw_pcib_init()
242 if (rp->pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { in ofw_pcib_init()
243 sc->sc_have_pmem = 1; in ofw_pcib_init()
244 error = rman_manage_region(&sc->sc_pmem_rman, in ofw_pcib_init()
245 rp->pci, rp->pci + rp->size - 1); in ofw_pcib_init()
247 error = rman_manage_region(&sc->sc_mem_rman, in ofw_pcib_init()
248 rp->pci, rp->pci + rp->size - 1); in ofw_pcib_init()
254 device_printf(dev, in ofw_pcib_init()
256 "error = %d\n", rp->pci_hi & in ofw_pcib_init()
257 OFW_PCI_PHYS_HI_SPACEMASK, rp->pci, in ofw_pcib_init()
258 rp->pci + rp->size - 1, error); in ofw_pcib_init()
263 ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t)); in ofw_pcib_init()
267 rman_fini(&sc->sc_pmem_rman); in ofw_pcib_init()
269 rman_fini(&sc->sc_mem_rman); in ofw_pcib_init()
271 rman_fini(&sc->sc_io_rman); in ofw_pcib_init()
273 free(sc->sc_cell_info, M_DEVBUF); in ofw_pcib_init()
274 free(sc->sc_range, M_DEVBUF); in ofw_pcib_init()
280 ofw_pcib_fini(device_t dev) in ofw_pcib_fini() argument
284 sc = device_get_softc(dev); in ofw_pcib_fini()
285 free(sc->sc_cell_info, M_DEVBUF); in ofw_pcib_fini()
286 free(sc->sc_range, M_DEVBUF); in ofw_pcib_fini()
287 rman_fini(&sc->sc_io_rman); in ofw_pcib_fini()
288 rman_fini(&sc->sc_mem_rman); in ofw_pcib_fini()
289 rman_fini(&sc->sc_pmem_rman); in ofw_pcib_fini()
293 ofw_pcib_attach(device_t dev) in ofw_pcib_attach() argument
298 sc = device_get_softc(dev); in ofw_pcib_attach()
299 if (!sc->sc_initialized) { in ofw_pcib_attach()
300 error = ofw_pcib_init(dev); in ofw_pcib_attach()
305 device_add_child(dev, "pci", DEVICE_UNIT_ANY); in ofw_pcib_attach()
306 bus_attach_children(dev); in ofw_pcib_attach()
311 ofw_pcib_maxslots(device_t dev) in ofw_pcib_maxslots() argument
318 ofw_pcib_route_interrupt(device_t bus, device_t dev, int pin) in ofw_pcib_route_interrupt() argument
331 reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) | in ofw_pcib_route_interrupt()
332 (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) | in ofw_pcib_route_interrupt()
333 (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT); in ofw_pcib_route_interrupt()
335 intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), in ofw_pcib_route_interrupt()
336 &sc->sc_pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr), in ofw_pcib_route_interrupt()
339 pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr); in ofw_pcib_route_interrupt()
350 pin, pci_get_slot(dev), pci_get_function(dev)); in ofw_pcib_route_interrupt()
355 ofw_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) in ofw_pcib_read_ivar() argument
359 sc = device_get_softc(dev); in ofw_pcib_read_ivar()
363 *result = sc->sc_pci_domain; in ofw_pcib_read_ivar()
366 *result = sc->sc_bus; in ofw_pcib_read_ivar()
376 ofw_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) in ofw_pcib_write_ivar() argument
380 sc = device_get_softc(dev); in ofw_pcib_write_ivar()
384 sc->sc_bus = value; in ofw_pcib_write_ivar()
399 return (-1); in ofw_pcib_nranges()
401 info->host_address_cells = 1; in ofw_pcib_nranges()
402 info->size_cells = 2; in ofw_pcib_nranges()
403 info->pci_address_cell = 3; in ofw_pcib_nranges()
405 OF_getencprop(OF_parent(node), "#address-cells", in ofw_pcib_nranges()
406 &(info->host_address_cells), sizeof(info->host_address_cells)); in ofw_pcib_nranges()
407 OF_getencprop(node, "#address-cells", in ofw_pcib_nranges()
408 &(info->pci_address_cell), sizeof(info->pci_address_cell)); in ofw_pcib_nranges()
409 OF_getencprop(node, "#size-cells", &(info->size_cells), in ofw_pcib_nranges()
410 sizeof(info->size_cells)); in ofw_pcib_nranges()
414 return (-1); in ofw_pcib_nranges()
417 (info->pci_address_cell + info->host_address_cells + in ofw_pcib_nranges()
418 info->size_cells)); in ofw_pcib_nranges()
430 return (pci_domain_alloc_bus(sc->sc_pci_domain, child, rid, in ofw_pcib_alloc_resource()
450 return (pci_domain_release_bus(sc->sc_pci_domain, child, res)); in ofw_pcib_release_resource()
472 for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && in ofw_pcib_translate_resource()
473 rp->pci_hi != 0; rp++) { in ofw_pcib_translate_resource()
474 if (start < rp->pci || start >= rp->pci + rp->size) in ofw_pcib_translate_resource()
477 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { in ofw_pcib_translate_resource()
486 space = -1; in ofw_pcib_translate_resource()
490 start += (rp->host - rp->pci); in ofw_pcib_translate_resource()
506 return (pci_domain_activate_bus(sc->sc_pci_domain, child, res)); in ofw_pcib_activate_resource()
516 ofw_pcib_map_resource(device_t dev, device_t child, struct resource *r, in ofw_pcib_map_resource() argument
545 sc = device_get_softc(dev); in ofw_pcib_map_resource()
546 for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && in ofw_pcib_map_resource()
547 rp->pci_hi != 0; rp++) { in ofw_pcib_map_resource()
548 if (start < rp->pci || start >= rp->pci + rp->size) in ofw_pcib_map_resource()
551 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { in ofw_pcib_map_resource()
560 space = -1; in ofw_pcib_map_resource()
564 start += (rp->host - rp->pci); in ofw_pcib_map_resource()
572 map->r_bustag = BUS_GET_BUS_TAG(child, child); in ofw_pcib_map_resource()
573 if (map->r_bustag == NULL) in ofw_pcib_map_resource()
576 error = bus_space_map(map->r_bustag, start, length, 0, in ofw_pcib_map_resource()
577 &map->r_bushandle); in ofw_pcib_map_resource()
582 map->r_vaddr = (void *)map->r_bushandle; in ofw_pcib_map_resource()
583 map->r_size = length; in ofw_pcib_map_resource()
588 ofw_pcib_unmap_resource(device_t dev, device_t child, struct resource *r, in ofw_pcib_unmap_resource() argument
594 bus_space_unmap(map->r_bustag, map->r_bushandle, map->r_size); in ofw_pcib_unmap_resource()
618 return (pci_domain_deactivate_bus(sc->sc_pci_domain, child, in ofw_pcib_deactivate_resource()
637 return (pci_domain_adjust_bus(sc->sc_pci_domain, child, res, in ofw_pcib_adjust_resource()
650 ofw_pcib_get_node(device_t bus, device_t dev) in ofw_pcib_get_node() argument
655 /* We only have one child, the PCI bus, which needs our own node. */ in ofw_pcib_get_node()
657 return (sc->sc_node); in ofw_pcib_get_node()
669 OF_getencprop(OF_parent(node), "#address-cells", &host_address_cells, in ofw_pcib_fill_ranges()
671 OF_getencprop(node, "#address-cells", &pci_address_cells, in ofw_pcib_fill_ranges()
673 OF_getencprop(node, "#size-cells", &size_cells, sizeof(size_cells)); in ofw_pcib_fill_ranges()
677 return (-1); in ofw_pcib_fill_ranges()
686 ranges[i].pci = 0; in ofw_pcib_fill_ranges()
687 for (k = 0; k < pci_address_cells - 1; k++) { in ofw_pcib_fill_ranges()
688 ranges[i].pci <<= 32; in ofw_pcib_fill_ranges()
689 ranges[i].pci |= base_ranges[j++]; in ofw_pcib_fill_ranges()
715 return (&sc->sc_io_rman); in ofw_pcib_get_rman()
717 if (sc->sc_have_pmem && (flags & RF_PREFETCHABLE)) in ofw_pcib_get_rman()
718 return (&sc->sc_pmem_rman); in ofw_pcib_get_rman()
720 return (&sc->sc_mem_rman); in ofw_pcib_get_rman()