2 * SPDX-License-Identifier: ISC
4 * Copyright (c) 2020 Dr Robert Harvey Crowston <crowston@protonmail.com>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * BCM2838-compatible PCI-express controller.
26 * Broadcom likes to give the same chip lots of different names. The name of
27 * this driver is taken from the Raspberry Pi 4 Broadcom 2838 chip.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/endian.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
42 #include <sys/mutex.h>
44 #include <dev/ofw/openfirm.h>
45 #include <dev/ofw/ofw_bus.h>
46 #include <dev/ofw/ofw_bus_subr.h>
48 #include <dev/pci/pci_host_generic.h>
49 #include <dev/pci/pci_host_generic_fdt.h>
50 #include <dev/pci/pcivar.h>
51 #include <dev/pci/pcireg.h>
52 #include <dev/pci/pcib_private.h>
54 #include <machine/bus.h>
55 #include <machine/intr.h>
60 extern struct bus_space memmap_bus;
62 #define BUS_SPACE_3G_MAXADDR 0xc0000000
63 #define PCI_ID_VAL3 0x43c
64 #define CLASS_SHIFT 0x10
65 #define SUBCLASS_SHIFT 0x8
67 #define REG_CONTROLLER_HW_REV 0x406c
68 #define REG_BRIDGE_CTRL 0x9210
69 #define BRIDGE_DISABLE_FLAG 0x1
70 #define BRIDGE_RESET_FLAG 0x2
71 #define REG_BRIDGE_SERDES_MODE 0x4204
72 #define REG_BRIDGE_CONFIG 0x4008
73 #define REG_BRIDGE_MEM_WINDOW_LOW 0x4034
74 #define REG_BRIDGE_MEM_WINDOW_HIGH 0x4038
75 #define REG_BRIDGE_MEM_WINDOW_1 0x403c
76 #define REG_BRIDGE_GISB_WINDOW 0x402c
77 #define REG_BRIDGE_STATE 0x4068
78 #define REG_BRIDGE_LINK_STATE 0x00bc
79 #define REG_BRIDGE_BUS_WINDOW_LOW 0x400c
80 #define REG_BRIDGE_BUS_WINDOW_HIGH 0x4010
81 #define REG_BRIDGE_CPU_WINDOW_LOW 0x4070
82 #define REG_BRIDGE_CPU_WINDOW_START_HIGH 0x4080
83 #define REG_BRIDGE_CPU_WINDOW_END_HIGH 0x4084
85 #define REG_MSI_ADDR_LOW 0x4044
86 #define REG_MSI_ADDR_HIGH 0x4048
87 #define REG_MSI_CONFIG 0x404c
88 #define REG_MSI_CLR 0x4508
89 #define REG_MSI_MASK_CLR 0x4514
90 #define REG_MSI_RAISED 0x4500
91 #define REG_MSI_EOI 0x4060
94 #define REG_EP_CONFIG_CHOICE 0x9000
95 #define REG_EP_CONFIG_DATA 0x8000
98 * These values were obtained from runtime inspection of a Linux system using a
99 * JTAG. The very limited documentation I have obtained from Broadcom does not
100 * explain how to compute them.
102 #define REG_VALUE_4GB_WINDOW 0x11
103 #define REG_VALUE_4GB_CONFIG 0x88003000
104 #define REG_VALUE_MSI_CONFIG 0xffe06540
106 struct bcm_pcib_irqsrc {
107 struct intr_irqsrc isrc;
112 struct bcm_pcib_softc {
113 struct generic_pcie_fdt_softc base;
115 struct mtx config_mtx;
117 struct resource *msi_irq_res;
118 void *msi_intr_cookie;
119 struct bcm_pcib_irqsrc *msi_isrcs;
123 static struct ofw_compat_data compat_data[] = {
124 {"brcm,bcm2711-pcie", 1},
125 {"brcm,bcm7211-pcie", 1},
126 {"brcm,bcm7445-pcie", 1},
131 bcm_pcib_probe(device_t dev)
134 if (!ofw_bus_status_okay(dev))
137 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
141 "BCM2838-compatible PCI-express controller");
142 return (BUS_PROBE_DEFAULT);
146 bcm_pcib_set_reg(struct bcm_pcib_softc *sc, uint32_t reg, uint32_t val)
149 bus_space_write_4(sc->base.base.bst, sc->base.base.bsh, reg,
154 bcm_pcib_read_reg(struct bcm_pcib_softc *sc, uint32_t reg)
157 return (le32toh(bus_space_read_4(sc->base.base.bst, sc->base.base.bsh,
162 bcm_pcib_reset_controller(struct bcm_pcib_softc *sc)
166 val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
167 val = val | BRIDGE_RESET_FLAG | BRIDGE_DISABLE_FLAG;
168 bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
172 val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
173 val = val & ~BRIDGE_RESET_FLAG;
174 bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
178 bcm_pcib_set_reg(sc, REG_BRIDGE_SERDES_MODE, 0);
184 bcm_pcib_enable_controller(struct bcm_pcib_softc *sc)
188 val = bcm_pcib_read_reg(sc, REG_BRIDGE_CTRL);
189 val = val & ~BRIDGE_DISABLE_FLAG;
190 bcm_pcib_set_reg(sc, REG_BRIDGE_CTRL, val);
196 bcm_pcib_check_ranges(device_t dev)
198 struct bcm_pcib_softc *sc;
199 struct pcie_range *ranges;
202 sc = device_get_softc(dev);
203 ranges = &sc->base.base.ranges[0];
205 /* The first range needs to be non-zero. */
206 if (ranges[0].size == 0) {
207 device_printf(dev, "error: first outbound memory range "
208 "(pci addr: 0x%jx, cpu addr: 0x%jx) has zero size.\n",
209 ranges[0].pci_base, ranges[0].phys_base);
214 * The controller can actually handle three distinct ranges, but we
215 * only implement support for one.
217 for (i = 1; (bootverbose || error) && i < MAX_RANGES_TUPLES; ++i) {
218 if (ranges[i].size > 0)
220 "note: outbound memory range %d (pci addr: 0x%jx, "
221 "cpu addr: 0x%jx, size: 0x%jx) will be ignored.\n",
222 i, ranges[i].pci_base, ranges[i].phys_base,
230 bcm_pcib_link_state_string(uint32_t mode)
233 switch(mode & PCIEM_LINK_STA_SPEED) {
248 bcm_get_offset_and_prepare_config(struct bcm_pcib_softc *sc, u_int bus,
249 u_int slot, u_int func, u_int reg)
252 * Config for an end point is only available through a narrow window for
253 * one end point at a time. We first tell the controller which end point
254 * we want, then access it through the window.
258 if (bus == 0 && slot == 0 && func == 0)
260 * Special case for root device; its config is always available
261 * through the zero-offset.
265 /* Tell the controller to show us the config in question. */
266 func_index = PCIE_ADDR_OFFSET(bus, slot, func, 0);
267 bcm_pcib_set_reg(sc, REG_EP_CONFIG_CHOICE, func_index);
269 return (REG_EP_CONFIG_DATA + reg);
273 bcm_pcib_is_valid_quad(struct bcm_pcib_softc *sc, u_int bus, u_int slot,
274 u_int func, u_int reg)
277 if ((bus < sc->base.base.bus_start) || (bus > sc->base.base.bus_end))
279 if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
282 if (bus == 0 && slot == 0 && func == 0)
286 * Probing other slots and funcs on bus 0 will lock up the
295 bcm_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
298 struct bcm_pcib_softc *sc;
299 bus_space_handle_t h;
304 sc = device_get_softc(dev);
305 if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
308 mtx_lock(&sc->config_mtx);
309 offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
311 t = sc->base.base.bst;
312 h = sc->base.base.bsh;
316 data = bus_space_read_1(t, h, offset);
319 data = le16toh(bus_space_read_2(t, h, offset));
322 data = le32toh(bus_space_read_4(t, h, offset));
329 mtx_unlock(&sc->config_mtx);
334 bcm_pcib_write_config(device_t dev, u_int bus, u_int slot,
335 u_int func, u_int reg, uint32_t val, int bytes)
337 struct bcm_pcib_softc *sc;
338 bus_space_handle_t h;
342 sc = device_get_softc(dev);
343 if (!bcm_pcib_is_valid_quad(sc, bus, slot, func, reg))
346 mtx_lock(&sc->config_mtx);
347 offset = bcm_get_offset_and_prepare_config(sc, bus, slot, func, reg);
349 t = sc->base.base.bst;
350 h = sc->base.base.bsh;
354 bus_space_write_1(t, h, offset, val);
357 bus_space_write_2(t, h, offset, htole16(val));
360 bus_space_write_4(t, h, offset, htole32(val));
366 mtx_unlock(&sc->config_mtx);
370 bcm_pcib_msi_intr_process(struct bcm_pcib_softc *sc, uint32_t interrupt_bitmap,
371 struct trapframe *tf)
373 struct bcm_pcib_irqsrc *irqsrc;
376 while ((bit = ffs(interrupt_bitmap))) {
379 /* Acknowledge interrupt. */
380 bcm_pcib_set_reg(sc, REG_MSI_CLR, 1 << irq);
383 bcm_pcib_set_reg(sc, REG_MSI_EOI, 1);
385 /* Despatch to handler. */
386 irqsrc = &sc->msi_isrcs[irq];
387 if (intr_isrc_dispatch(&irqsrc->isrc, tf))
388 device_printf(sc->dev,
389 "note: unexpected interrupt (%d) triggered.\n",
392 /* Done with this interrupt. */
393 interrupt_bitmap = interrupt_bitmap & ~(1 << irq);
398 bcm_pcib_msi_intr(void *arg)
400 struct bcm_pcib_softc *sc;
401 struct trapframe *tf;
402 uint32_t interrupt_bitmap;
404 sc = (struct bcm_pcib_softc *) arg;
405 tf = curthread->td_intr_frame;
407 while ((interrupt_bitmap = bcm_pcib_read_reg(sc, REG_MSI_RAISED)))
408 bcm_pcib_msi_intr_process(sc, interrupt_bitmap, tf);
410 return (FILTER_HANDLED);
414 bcm_pcib_alloc_msi(device_t dev, device_t child, int count, int maxcount,
415 device_t *pic, struct intr_irqsrc **srcs)
417 struct bcm_pcib_softc *sc;
420 sc = device_get_softc(dev);
421 mtx_lock(&sc->msi_mtx);
423 /* Find a continguous region of free message-signalled interrupts. */
424 for (first_int = 0; first_int + count < NUM_MSI; ) {
425 for (i = first_int; i < first_int + count; ++i) {
426 if (sc->msi_isrcs[i].allocated)
434 /* No appropriate region available. */
435 mtx_unlock(&sc->msi_mtx);
436 device_printf(dev, "warning: failed to allocate %d MSI messages.\n",
441 /* Mark the messages as in use. */
442 for (i = 0; i < count; ++i) {
443 sc->msi_isrcs[i + first_int].allocated = true;
444 srcs[i] = &(sc->msi_isrcs[i + first_int].isrc);
447 mtx_unlock(&sc->msi_mtx);
448 *pic = device_get_parent(dev);
454 bcm_pcib_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
455 uint64_t *addr, uint32_t *data)
457 struct bcm_pcib_softc *sc;
458 struct bcm_pcib_irqsrc *msi_msg;
460 sc = device_get_softc(dev);
461 msi_msg = (struct bcm_pcib_irqsrc *) isrc;
463 *addr = sc->msi_addr;
464 *data = (REG_VALUE_MSI_CONFIG & 0xffff) | msi_msg->irq;
469 bcm_pcib_release_msi(device_t dev, device_t child, int count,
470 struct intr_irqsrc **isrc)
472 struct bcm_pcib_softc *sc;
473 struct bcm_pcib_irqsrc *msi_isrc;
476 sc = device_get_softc(dev);
477 mtx_lock(&sc->msi_mtx);
479 for (i = 0; i < count; i++) {
480 msi_isrc = (struct bcm_pcib_irqsrc *) isrc[i];
481 msi_isrc->allocated = false;
484 mtx_unlock(&sc->msi_mtx);
489 bcm_pcib_msi_attach(device_t dev)
491 struct bcm_pcib_softc *sc;
492 phandle_t node, xref;
493 char const *bcm_name;
496 sc = device_get_softc(dev);
497 sc->msi_addr = 0xffffffffc;
499 /* Clear any pending interrupts. */
500 bcm_pcib_set_reg(sc, REG_MSI_CLR, 0xffffffff);
503 sc->msi_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
505 if (sc->msi_irq_res == NULL) {
506 device_printf(dev, "could not allocate MSI irq resource.\n");
510 sc->msi_isrcs = malloc(sizeof(*sc->msi_isrcs) * NUM_MSI, M_DEVBUF,
513 int error = bus_setup_intr(dev, sc->msi_irq_res, INTR_TYPE_BIO |
514 INTR_MPSAFE, bcm_pcib_msi_intr, NULL, sc, &sc->msi_intr_cookie);
516 device_printf(dev, "error: failed to setup MSI handler.\n");
520 bcm_name = device_get_nameunit(dev);
521 for (i = 0; i < NUM_MSI; i++) {
522 sc->msi_isrcs[i].irq = i;
523 error = intr_isrc_register(&sc->msi_isrcs[i].isrc, dev, 0,
524 "%s,%u", bcm_name, i);
527 "error: failed to register interrupt %d.\n", i);
532 node = ofw_bus_get_node(dev);
533 xref = OF_xref_from_node(node);
534 OF_device_register_xref(xref, dev);
536 error = intr_msi_register(dev, xref);
540 mtx_init(&sc->msi_mtx, "bcm_pcib: msi_mtx", NULL, MTX_DEF);
542 bcm_pcib_set_reg(sc, REG_MSI_MASK_CLR, 0xffffffff);
543 bcm_pcib_set_reg(sc, REG_MSI_ADDR_LOW, (sc->msi_addr & 0xffffffff) | 1);
544 bcm_pcib_set_reg(sc, REG_MSI_ADDR_HIGH, (sc->msi_addr >> 32));
545 bcm_pcib_set_reg(sc, REG_MSI_CONFIG, REG_VALUE_MSI_CONFIG);
551 bcm_pcib_relocate_bridge_window(device_t dev)
554 * In principle an out-of-bounds bridge window could be automatically
555 * adjusted at resource-activation time to lie within the bus address
556 * space by pcib_grow_window(), but that is not possible because the
557 * out-of-bounds resource allocation fails at allocation time. Instead,
558 * we will just fix up the window on the controller here, before it is
559 * re-discovered by pcib_probe_windows().
562 struct bcm_pcib_softc *sc;
563 pci_addr_t base, size, new_base, new_limit;
566 sc = device_get_softc(dev);
568 val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMBASE_1, 2);
569 base = PCI_PPBMEMBASE(0, val);
571 val = bcm_pcib_read_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, 2);
572 size = PCI_PPBMEMLIMIT(0, val) - base;
574 new_base = sc->base.base.ranges[0].pci_base;
575 val = (uint16_t) (new_base >> 16);
576 bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMBASE_1, val, 2);
578 new_limit = new_base + size;
579 val = (uint16_t) (new_limit >> 16);
580 bcm_pcib_write_config(dev, 0, 0, 0, PCIR_MEMLIMIT_1, val, 2);
584 encode_cpu_window_low(pci_addr_t phys_base, bus_size_t size)
587 return (((phys_base >> 0x10) & 0xfff0) |
588 ((phys_base + size - 1) & 0xfff00000));
592 encode_cpu_window_start_high(pci_addr_t phys_base)
595 return ((phys_base >> 0x20) & 0xff);
599 encode_cpu_window_end_high(pci_addr_t phys_base, bus_size_t size)
602 return (((phys_base + size - 1) >> 0x20) & 0xff);
606 bcm_pcib_attach(device_t dev)
608 struct bcm_pcib_softc *sc;
609 pci_addr_t phys_base, pci_base;
611 uint32_t hardware_rev, bridge_state, link_state;
614 sc = device_get_softc(dev);
617 error = pci_host_generic_setup_fdt(dev);
621 error = bcm_pcib_check_ranges(dev);
625 mtx_init(&sc->config_mtx, "bcm_pcib: config_mtx", NULL, MTX_DEF);
627 bcm_pcib_reset_controller(sc);
629 hardware_rev = bcm_pcib_read_reg(sc, REG_CONTROLLER_HW_REV) & 0xffff;
630 device_printf(dev, "hardware identifies as revision 0x%x.\n",
634 * Set PCI->CPU memory window. This encodes the inbound window showing
635 * up to 4 GiB of system memory to the controller, with zero offset.
636 * Thus, from the perspective of a device on the PCI-E bus, there is a
637 * 1:1 map from PCI-E bus addresses to system memory addresses. However,
638 * a hardware limitation means that the controller can only perform DMA
639 * on the lower 3 GiB of system memory.
641 bcm_pcib_set_reg(sc, REG_BRIDGE_MEM_WINDOW_LOW, REG_VALUE_4GB_WINDOW);
642 bcm_pcib_set_reg(sc, REG_BRIDGE_MEM_WINDOW_HIGH, 0);
643 bcm_pcib_set_reg(sc, REG_BRIDGE_CONFIG, REG_VALUE_4GB_CONFIG);
644 bcm_pcib_set_reg(sc, REG_BRIDGE_GISB_WINDOW, 0);
645 bcm_pcib_set_reg(sc, REG_BRIDGE_MEM_WINDOW_1, 0);
647 bcm_pcib_enable_controller(sc);
649 /* Wait for controller to start. */
650 for(tries = 0; ; ++tries) {
651 bridge_state = bcm_pcib_read_reg(sc, REG_BRIDGE_STATE);
653 if ((bridge_state & 0x30) == 0x30)
654 /* Controller ready. */
659 "error: controller failed to start.\n");
666 link_state = bcm_pcib_read_reg(sc, REG_BRIDGE_LINK_STATE) >> 0x10;
668 device_printf(dev, "error: controller started but link is not "
673 device_printf(dev, "note: reported link speed is %s.\n",
674 bcm_pcib_link_state_string(link_state));
677 * Set the CPU->PCI memory window. The map in this direction is not 1:1.
678 * Addresses seen by the CPU need to be adjusted to make sense to the
679 * controller as they pass through the window.
681 pci_base = sc->base.base.ranges[0].pci_base;
682 phys_base = sc->base.base.ranges[0].phys_base;
683 size = sc->base.base.ranges[0].size;
685 bcm_pcib_set_reg(sc, REG_BRIDGE_BUS_WINDOW_LOW, pci_base & 0xffffffff);
686 bcm_pcib_set_reg(sc, REG_BRIDGE_BUS_WINDOW_HIGH, pci_base >> 32);
688 bcm_pcib_set_reg(sc, REG_BRIDGE_CPU_WINDOW_LOW,
689 encode_cpu_window_low(phys_base, size));
690 bcm_pcib_set_reg(sc, REG_BRIDGE_CPU_WINDOW_START_HIGH,
691 encode_cpu_window_start_high(phys_base));
692 bcm_pcib_set_reg(sc, REG_BRIDGE_CPU_WINDOW_END_HIGH,
693 encode_cpu_window_end_high(phys_base, size));
696 * The controller starts up declaring itself an endpoint; readvertise it
699 bcm_pcib_set_reg(sc, PCI_ID_VAL3,
700 PCIC_BRIDGE << CLASS_SHIFT | PCIS_BRIDGE_PCI << SUBCLASS_SHIFT);
702 bcm_pcib_set_reg(sc, REG_BRIDGE_SERDES_MODE, 0x2);
705 bcm_pcib_relocate_bridge_window(dev);
707 /* Configure interrupts. */
708 error = bcm_pcib_msi_attach(dev);
713 device_add_child(dev, "pci", -1);
714 return (bus_generic_attach(dev));
718 * Device method table.
720 static device_method_t bcm_pcib_methods[] = {
721 /* Device interface. */
722 DEVMETHOD(device_probe, bcm_pcib_probe),
723 DEVMETHOD(device_attach, bcm_pcib_attach),
725 /* PCIB interface. */
726 DEVMETHOD(pcib_read_config, bcm_pcib_read_config),
727 DEVMETHOD(pcib_write_config, bcm_pcib_write_config),
730 DEVMETHOD(msi_alloc_msi, bcm_pcib_alloc_msi),
731 DEVMETHOD(msi_release_msi, bcm_pcib_release_msi),
732 DEVMETHOD(msi_map_msi, bcm_pcib_map_msi),
737 DEFINE_CLASS_1(pcib, bcm_pcib_driver, bcm_pcib_methods,
738 sizeof(struct bcm_pcib_softc), generic_pcie_fdt_driver);
740 static devclass_t bcm_pcib_devclass;
741 DRIVER_MODULE(bcm_pcib, simplebus, bcm_pcib_driver, bcm_pcib_devclass, 0, 0);