Lines Matching +full:dma +full:- +full:window

1 /*-
2 * SPDX-License-Identifier: ISC
22 * BCM2838-compatible PCI-express controller.
95 * is 8 GiB). However, the system DMA controller is capable of accessing only a
96 * limited portion of the address space. Worse, the PCI-e controller has further
97 * constraints for DMA, and those limitations are not wholly clear to the
98 * author. NetBSD and Linux allow DMA on the lower 3 GiB of the physical memory,
99 * but experimentation shows DMA performed above 960 MiB results in data
108 #define REG_VALUE_DMA_WINDOW_LOW (MAX_MEMORY_LOG2 - 0xf)
112 (((MAX_MEMORY_LOG2 - 0xf) << 0x1b) | DMA_WINDOW_ENABLE)
135 {"brcm,bcm2711-pcie", 1},
136 {"brcm,bcm7211-pcie", 1},
137 {"brcm,bcm7445-pcie", 1},
148 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) in bcm_pcib_probe()
152 "BCM2838-compatible PCI-express controller"); in bcm_pcib_probe()
162 return (sc->dmat); in bcm_pcib_get_dma_tag()
169 bus_write_4(sc->base.base.res, reg, htole32(val)); in bcm_pcib_set_reg()
176 return (le32toh(bus_read_4(sc->base.base.res, reg))); in bcm_pcib_read_reg()
221 ranges = &sc->base.base.ranges[0]; in bcm_pcib_check_ranges()
223 /* The first range needs to be non-zero. */ in bcm_pcib_check_ranges()
270 * Config for an end point is only available through a narrow window for in bcm_get_offset_and_prepare_config()
272 * we want, then access it through the window. in bcm_get_offset_and_prepare_config()
279 * through the zero-offset. in bcm_get_offset_and_prepare_config()
295 if ((bus < sc->base.base.bus_start) || (bus > sc->base.base.bus_end)) in bcm_pcib_is_valid_quad()
324 mtx_lock(&sc->config_mtx); in bcm_pcib_read_config()
329 data = bus_read_1(sc->base.base.res, offset); in bcm_pcib_read_config()
332 data = le16toh(bus_read_2(sc->base.base.res, offset)); in bcm_pcib_read_config()
335 data = le32toh(bus_read_4(sc->base.base.res, offset)); in bcm_pcib_read_config()
342 mtx_unlock(&sc->config_mtx); in bcm_pcib_read_config()
357 mtx_lock(&sc->config_mtx); in bcm_pcib_write_config()
362 bus_write_1(sc->base.base.res, offset, val); in bcm_pcib_write_config()
365 bus_write_2(sc->base.base.res, offset, htole16(val)); in bcm_pcib_write_config()
368 bus_write_4(sc->base.base.res, offset, htole32(val)); in bcm_pcib_write_config()
374 mtx_unlock(&sc->config_mtx); in bcm_pcib_write_config()
385 irq = bit - 1; in bcm_pcib_msi_intr_process()
394 irqsrc = &sc->msi_isrcs[irq]; in bcm_pcib_msi_intr_process()
395 if (intr_isrc_dispatch(&irqsrc->isrc, tf)) in bcm_pcib_msi_intr_process()
396 device_printf(sc->dev, in bcm_pcib_msi_intr_process()
413 tf = curthread->td_intr_frame; in bcm_pcib_msi_intr()
429 mtx_lock(&sc->msi_mtx); in bcm_pcib_alloc_msi()
431 /* Find a continguous region of free message-signalled interrupts. */ in bcm_pcib_alloc_msi()
434 if (sc->msi_isrcs[i].allocated) in bcm_pcib_alloc_msi()
443 mtx_unlock(&sc->msi_mtx); in bcm_pcib_alloc_msi()
451 sc->msi_isrcs[i + first_int].allocated = true; in bcm_pcib_alloc_msi()
452 srcs[i] = &(sc->msi_isrcs[i + first_int].isrc); in bcm_pcib_alloc_msi()
455 mtx_unlock(&sc->msi_mtx); in bcm_pcib_alloc_msi()
471 *addr = sc->msi_addr; in bcm_pcib_map_msi()
472 *data = (REG_VALUE_MSI_CONFIG & 0xffff) | msi_msg->irq; in bcm_pcib_map_msi()
485 mtx_lock(&sc->msi_mtx); in bcm_pcib_release_msi()
489 msi_isrc->allocated = false; in bcm_pcib_release_msi()
492 mtx_unlock(&sc->msi_mtx); in bcm_pcib_release_msi()
505 sc->msi_addr = 0xffffffffc; in bcm_pcib_msi_attach()
511 sc->msi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in bcm_pcib_msi_attach()
513 if (sc->msi_irq_res == NULL) { in bcm_pcib_msi_attach()
518 sc->msi_isrcs = malloc(sizeof(*sc->msi_isrcs) * NUM_MSI, M_DEVBUF, in bcm_pcib_msi_attach()
521 error = bus_setup_intr(dev, sc->msi_irq_res, INTR_TYPE_BIO | in bcm_pcib_msi_attach()
522 INTR_MPSAFE, bcm_pcib_msi_intr, NULL, sc, &sc->msi_intr_cookie); in bcm_pcib_msi_attach()
530 sc->msi_isrcs[i].irq = i; in bcm_pcib_msi_attach()
531 error = intr_isrc_register(&sc->msi_isrcs[i].isrc, dev, 0, in bcm_pcib_msi_attach()
548 mtx_init(&sc->msi_mtx, "bcm_pcib: msi_mtx", NULL, MTX_DEF); in bcm_pcib_msi_attach()
551 bcm_pcib_set_reg(sc, REG_MSI_ADDR_LOW, (sc->msi_addr & 0xffffffff) | 1); in bcm_pcib_msi_attach()
552 bcm_pcib_set_reg(sc, REG_MSI_ADDR_HIGH, (sc->msi_addr >> 32)); in bcm_pcib_msi_attach()
562 * In principle an out-of-bounds bridge window could be automatically in bcm_pcib_relocate_bridge_window()
563 * adjusted at resource-activation time to lie within the bus address in bcm_pcib_relocate_bridge_window()
565 * out-of-bounds resource allocation fails at allocation time. Instead, in bcm_pcib_relocate_bridge_window()
566 * we will just fix up the window on the controller here, before it is in bcm_pcib_relocate_bridge_window()
567 * re-discovered by pcib_probe_windows(). in bcm_pcib_relocate_bridge_window()
580 size = PCI_PPBMEMLIMIT(0, val) - base; in bcm_pcib_relocate_bridge_window()
582 new_base = sc->base.base.ranges[0].pci_base; in bcm_pcib_relocate_bridge_window()
596 ((phys_base + size - 1) & 0xfff00000)); in encode_cpu_window_low()
610 return (((phys_base + size - 1) >> 0x20) & 0xff); in encode_cpu_window_end_high()
623 sc->dev = dev; in bcm_pcib_attach()
639 &sc->dmat); in bcm_pcib_attach()
651 mtx_init(&sc->config_mtx, "bcm_pcib: config_mtx", NULL, MTX_DEF); in bcm_pcib_attach()
660 * Set PCI->CPU memory window. This encodes the inbound window showing in bcm_pcib_attach()
700 * Set the CPU->PCI memory window. The map in this direction is not 1:1. in bcm_pcib_attach()
702 * controller as they pass through the window. in bcm_pcib_attach()
704 pci_base = sc->base.base.ranges[0].pci_base; in bcm_pcib_attach()
705 phys_base = sc->base.base.ranges[0].phys_base; in bcm_pcib_attach()
706 size = sc->base.base.ranges[0].size; in bcm_pcib_attach()
728 if (ofw_bus_has_prop(dev, "brcm,enable-l1ss")) { in bcm_pcib_attach()
731 "property brcm,enable-l1ss\n"); in bcm_pcib_attach()