aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Wojtas <mw@FreeBSD.org>2021-05-27 08:05:35 +0000
committerMarcin Wojtas <mw@FreeBSD.org>2021-06-08 15:51:11 +0000
commitf0f7b0868a94d33ca3362702832b772bc01c65d6 (patch)
tree48b3e8ddccf59135f383229ffdd0e15f5ac71619
parentb38239433258683bdd45a5627815a56ea6e79b64 (diff)
downloadsrc-f0f7b0868a94d33ca3362702832b772bc01c65d6.tar.gz
src-f0f7b0868a94d33ca3362702832b772bc01c65d6.zip
Remove ThunderX PCIe FDT quirks from pci_host_generic_fdt.c
ThunderX is the only board known to use them. Move them to the ThunderX PCIe driver. Submitted by: Kornel Duleba <mindal@semihalf.com> Reviewed by: andrew Obtained from: Semihalf Sponsored by: Alstom Group Differential Revision: https://reviews.freebsd.org/D30179
-rw-r--r--sys/arm64/cavium/thunder_pcie_fdt.c164
-rw-r--r--sys/dev/pci/pci_host_generic_fdt.c178
2 files changed, 158 insertions, 184 deletions
diff --git a/sys/arm64/cavium/thunder_pcie_fdt.c b/sys/arm64/cavium/thunder_pcie_fdt.c
index 115b89b67b88..b89b4e345d31 100644
--- a/sys/arm64/cavium/thunder_pcie_fdt.c
+++ b/sys/arm64/cavium/thunder_pcie_fdt.c
@@ -59,23 +59,43 @@ __FBSDID("$FreeBSD$");
#ifdef THUNDERX_PASS_1_1_ERRATA
static struct resource * thunder_pcie_fdt_alloc_resource(device_t, device_t,
int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
+static int thunder_pcie_fdt_release_resource(device_t, device_t,
+ int, int, struct resource*);
#endif
static int thunder_pcie_fdt_attach(device_t);
static int thunder_pcie_fdt_probe(device_t);
static int thunder_pcie_fdt_get_id(device_t, device_t, enum pci_id_type,
uintptr_t *);
+static const struct ofw_bus_devinfo *thunder_pcie_ofw_get_devinfo(device_t,
+ device_t);
+
+/* OFW bus interface */
+struct thunder_pcie_ofw_devinfo {
+ struct ofw_bus_devinfo di_dinfo;
+ struct resource_list di_rl;
+};
+
static device_method_t thunder_pcie_fdt_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, thunder_pcie_fdt_probe),
DEVMETHOD(device_attach, thunder_pcie_fdt_attach),
#ifdef THUNDERX_PASS_1_1_ERRATA
DEVMETHOD(bus_alloc_resource, thunder_pcie_fdt_alloc_resource),
+ DEVMETHOD(bus_release_resource, thunder_pcie_fdt_release_resource),
#endif
/* pcib interface */
DEVMETHOD(pcib_get_id, thunder_pcie_fdt_get_id),
+ /* ofw interface */
+ DEVMETHOD(ofw_bus_get_devinfo, thunder_pcie_ofw_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
/* End */
DEVMETHOD_END
};
@@ -90,6 +110,70 @@ DRIVER_MODULE(thunder_pcib, simplebus, thunder_pcie_fdt_driver,
DRIVER_MODULE(thunder_pcib, ofwbus, thunder_pcie_fdt_driver,
thunder_pcie_fdt_devclass, 0, 0);
+static const struct ofw_bus_devinfo *
+thunder_pcie_ofw_get_devinfo(device_t bus __unused, device_t child)
+{
+ struct thunder_pcie_ofw_devinfo *di;
+
+ di = device_get_ivars(child);
+ return (&di->di_dinfo);
+}
+
+static void
+get_addr_size_cells(phandle_t node, pcell_t *addr_cells, pcell_t *size_cells)
+{
+
+ *addr_cells = 2;
+ /* Find address cells if present */
+ OF_getencprop(node, "#address-cells", addr_cells, sizeof(*addr_cells));
+
+ *size_cells = 2;
+ /* Find size cells if present */
+ OF_getencprop(node, "#size-cells", size_cells, sizeof(*size_cells));
+}
+
+static int
+thunder_pcie_ofw_bus_attach(device_t dev)
+{
+ struct thunder_pcie_ofw_devinfo *di;
+ device_t child;
+ phandle_t parent, node;
+ pcell_t addr_cells, size_cells;
+
+ parent = ofw_bus_get_node(dev);
+ if (parent > 0) {
+ get_addr_size_cells(parent, &addr_cells, &size_cells);
+ /* Iterate through all bus subordinates */
+ for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
+ /* Allocate and populate devinfo. */
+ di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
+ free(di, M_DEVBUF);
+ continue;
+ }
+
+ /* Initialize and populate resource list. */
+ resource_list_init(&di->di_rl);
+ ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
+ &di->di_rl);
+ ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
+
+ /* Add newbus device for this FDT node */
+ child = device_add_child(dev, NULL, -1);
+ if (child == NULL) {
+ resource_list_free(&di->di_rl);
+ ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
+ free(di, M_DEVBUF);
+ continue;
+ }
+
+ device_set_ivars(child, di);
+ }
+ }
+
+ return (0);
+}
+
static int
thunder_pcie_fdt_probe(device_t dev)
{
@@ -121,6 +205,10 @@ thunder_pcie_fdt_attach(device_t dev)
thunder_pcie_identify_ecam(dev, &sc->base.ecam);
sc->base.coherent = 1;
+ /* Attach OFW bus */
+ if (thunder_pcie_ofw_bus_attach(dev) != 0)
+ return (ENXIO);
+
return (pci_host_generic_attach(dev));
}
@@ -145,16 +233,76 @@ thunder_pcie_fdt_get_id(device_t pci, device_t child, enum pci_id_type type,
}
#ifdef THUNDERX_PASS_1_1_ERRATA
-static struct resource *
-thunder_pcie_fdt_alloc_resource(device_t dev, device_t child, int type, int *rid,
- rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
+struct resource *
+thunder_pcie_fdt_alloc_resource(device_t dev, device_t child, int type,
+ int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
+{
+ struct generic_pcie_fdt_softc *sc;
+ struct thunder_pcie_ofw_devinfo *di;
+ struct resource_list_entry *rle;
+ int i;
+
+ /*
+ * For PCIe devices that do not have FDT nodes pass
+ * the request to the core driver.
+ */
+ if ((int)ofw_bus_get_node(child) <= 0)
+ return (thunder_pcie_alloc_resource(dev, child, type,
+ rid, start, end, count, flags));
+
+ /* For other devices use OFW method */
+ sc = device_get_softc(dev);
+
+ if (RMAN_IS_DEFAULT_RANGE(start, end)) {
+ if ((di = device_get_ivars(child)) == NULL)
+ return (NULL);
+ if (type == SYS_RES_IOPORT)
+ type = SYS_RES_MEMORY;
+
+ /* Find defaults for this rid */
+ rle = resource_list_find(&di->di_rl, type, *rid);
+ if (rle == NULL)
+ return (NULL);
+
+ start = rle->start;
+ end = rle->end;
+ count = rle->count;
+ }
+
+ if (type == SYS_RES_MEMORY) {
+ /* Remap through ranges property */
+ for (i = 0; i < MAX_RANGES_TUPLES; i++) {
+ if (start >= sc->base.ranges[i].phys_base &&
+ end < (sc->base.ranges[i].pci_base +
+ sc->base.ranges[i].size)) {
+ start -= sc->base.ranges[i].phys_base;
+ start += sc->base.ranges[i].pci_base;
+ end -= sc->base.ranges[i].phys_base;
+ end += sc->base.ranges[i].pci_base;
+ break;
+ }
+ }
+
+ if (i == MAX_RANGES_TUPLES) {
+ device_printf(dev, "Could not map resource "
+ "%#jx-%#jx\n", start, end);
+ return (NULL);
+ }
+ }
+
+ return (bus_generic_alloc_resource(dev, child, type, rid, start,
+ end, count, flags));
+}
+
+static int
+thunder_pcie_fdt_release_resource(device_t dev, device_t child, int type,
+ int rid, struct resource *res)
{
- if ((int)ofw_bus_get_node(child) > 0)
- return (pci_host_generic_alloc_resource(dev, child,
- type, rid, start, end, count, flags));
+ if ((int)ofw_bus_get_node(child) <= 0)
+ return (pci_host_generic_core_release_resource(dev, child, type,
+ rid, res));
- return (thunder_pcie_alloc_resource(dev, child,
- type, rid, start, end, count, flags));
+ return (bus_generic_release_resource(dev, child, type, rid, res));
}
#endif
diff --git a/sys/dev/pci/pci_host_generic_fdt.c b/sys/dev/pci/pci_host_generic_fdt.c
index 48e032ad4389..26047135164c 100644
--- a/sys/dev/pci/pci_host_generic_fdt.c
+++ b/sys/dev/pci/pci_host_generic_fdt.c
@@ -71,34 +71,10 @@ __FBSDID("$FreeBSD$");
#define PROPS_CELL_SIZE 1
#define PCI_ADDR_CELL_SIZE 2
-/* OFW bus interface */
-struct generic_pcie_ofw_devinfo {
- struct ofw_bus_devinfo di_dinfo;
- struct resource_list di_rl;
-};
-
/* Forward prototypes */
static int generic_pcie_fdt_probe(device_t dev);
static int parse_pci_mem_ranges(device_t, struct generic_pcie_core_softc *);
-static int generic_pcie_fdt_release_resource(device_t dev, device_t child,
- int type, int rid, struct resource *res);
-static int generic_pcie_ofw_bus_attach(device_t);
-static const struct ofw_bus_devinfo *generic_pcie_ofw_get_devinfo(device_t,
- device_t);
-
-static __inline void
-get_addr_size_cells(phandle_t node, pcell_t *addr_cells, pcell_t *size_cells)
-{
-
- *addr_cells = 2;
- /* Find address cells if present */
- OF_getencprop(node, "#address-cells", addr_cells, sizeof(*addr_cells));
-
- *size_cells = 2;
- /* Find size cells if present */
- OF_getencprop(node, "#size-cells", size_cells, sizeof(*size_cells));
-}
static int
generic_pcie_fdt_probe(device_t dev)
@@ -134,10 +110,6 @@ pci_host_generic_setup_fdt(device_t dev)
if (parse_pci_mem_ranges(dev, &sc->base))
return (ENXIO);
- /* Attach OFW bus */
- if (generic_pcie_ofw_bus_attach(dev) != 0)
- return (ENXIO);
-
node = ofw_bus_get_node(dev);
if (sc->base.coherent == 0) {
sc->base.coherent = OF_hasprop(node, "dma-coherent");
@@ -285,93 +257,6 @@ generic_pcie_fdt_route_interrupt(device_t bus, device_t dev, int pin)
}
static int
-generic_pcie_fdt_release_resource(device_t dev, device_t child, int type,
- int rid, struct resource *res)
-{
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
- if (type == PCI_RES_BUS) {
- return (pci_host_generic_core_release_resource(dev, child, type,
- rid, res));
- }
-#endif
-
- /* For PCIe devices that do not have FDT nodes, use PCIB method */
- if ((int)ofw_bus_get_node(child) <= 0) {
- return (pci_host_generic_core_release_resource(dev, child, type,
- rid, res));
- }
-
- /* For other devices use OFW method */
- return (bus_generic_release_resource(dev, child, type, rid, res));
-}
-
-struct resource *
-pci_host_generic_alloc_resource(device_t dev, device_t child, int type,
- int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
-{
- struct generic_pcie_fdt_softc *sc;
- struct generic_pcie_ofw_devinfo *di;
- struct resource_list_entry *rle;
- int i;
-
-#if defined(NEW_PCIB) && defined(PCI_RES_BUS)
- if (type == PCI_RES_BUS) {
- return (pci_host_generic_core_alloc_resource(dev, child, type, rid,
- start, end, count, flags));
- }
-#endif
-
- /* For PCIe devices that do not have FDT nodes, use PCIB method */
- if ((int)ofw_bus_get_node(child) <= 0)
- return (pci_host_generic_core_alloc_resource(dev, child, type,
- rid, start, end, count, flags));
-
- /* For other devices use OFW method */
- sc = device_get_softc(dev);
-
- if (RMAN_IS_DEFAULT_RANGE(start, end)) {
- if ((di = device_get_ivars(child)) == NULL)
- return (NULL);
- if (type == SYS_RES_IOPORT)
- type = SYS_RES_MEMORY;
-
- /* Find defaults for this rid */
- rle = resource_list_find(&di->di_rl, type, *rid);
- if (rle == NULL)
- return (NULL);
-
- start = rle->start;
- end = rle->end;
- count = rle->count;
- }
-
- if (type == SYS_RES_MEMORY) {
- /* Remap through ranges property */
- for (i = 0; i < MAX_RANGES_TUPLES; i++) {
- if (start >= sc->base.ranges[i].phys_base &&
- end < (sc->base.ranges[i].pci_base +
- sc->base.ranges[i].size)) {
- start -= sc->base.ranges[i].phys_base;
- start += sc->base.ranges[i].pci_base;
- end -= sc->base.ranges[i].phys_base;
- end += sc->base.ranges[i].pci_base;
- break;
- }
- }
-
- if (i == MAX_RANGES_TUPLES) {
- device_printf(dev, "Could not map resource "
- "%#jx-%#jx\n", start, end);
- return (NULL);
- }
- }
-
- return (bus_generic_alloc_resource(dev, child, type, rid, start,
- end, count, flags));
-}
-
-static int
generic_pcie_fdt_alloc_msi(device_t pci, device_t child, int count,
int maxcount, int *irqs)
{
@@ -482,64 +367,13 @@ generic_pcie_get_id(device_t pci, device_t child, enum pci_id_type type,
return (0);
}
-static const struct ofw_bus_devinfo *
-generic_pcie_ofw_get_devinfo(device_t bus __unused, device_t child)
-{
- struct generic_pcie_ofw_devinfo *di;
-
- di = device_get_ivars(child);
- return (&di->di_dinfo);
-}
-
/* Helper functions */
-static int
-generic_pcie_ofw_bus_attach(device_t dev)
-{
- struct generic_pcie_ofw_devinfo *di;
- device_t child;
- phandle_t parent, node;
- pcell_t addr_cells, size_cells;
-
- parent = ofw_bus_get_node(dev);
- if (parent > 0) {
- get_addr_size_cells(parent, &addr_cells, &size_cells);
- /* Iterate through all bus subordinates */
- for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
- /* Allocate and populate devinfo. */
- di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
- if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
- free(di, M_DEVBUF);
- continue;
- }
-
- /* Initialize and populate resource list. */
- resource_list_init(&di->di_rl);
- ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
- &di->di_rl);
- ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
-
- /* Add newbus device for this FDT node */
- child = device_add_child(dev, NULL, -1);
- if (child == NULL) {
- resource_list_free(&di->di_rl);
- ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
- free(di, M_DEVBUF);
- continue;
- }
-
- device_set_ivars(child, di);
- }
- }
-
- return (0);
-}
-
static device_method_t generic_pcie_fdt_methods[] = {
DEVMETHOD(device_probe, generic_pcie_fdt_probe),
DEVMETHOD(device_attach, pci_host_generic_attach),
- DEVMETHOD(bus_alloc_resource, pci_host_generic_alloc_resource),
- DEVMETHOD(bus_release_resource, generic_pcie_fdt_release_resource),
+ DEVMETHOD(bus_alloc_resource, pci_host_generic_core_alloc_resource),
+ DEVMETHOD(bus_release_resource, pci_host_generic_core_release_resource),
/* pcib interface */
DEVMETHOD(pcib_route_interrupt, generic_pcie_fdt_route_interrupt),
@@ -551,14 +385,6 @@ static device_method_t generic_pcie_fdt_methods[] = {
DEVMETHOD(pcib_get_id, generic_pcie_get_id),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
- /* ofw_bus interface */
- DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
- DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
- DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
- DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
- DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
- DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
-
DEVMETHOD_END
};