diff options
| author | Andrew Turner <andrew@FreeBSD.org> | 2016-05-16 09:31:44 +0000 |
|---|---|---|
| committer | Andrew Turner <andrew@FreeBSD.org> | 2016-05-16 09:31:44 +0000 |
| commit | 1e43b18c4b5960382eb9a0df487360dba4bbd349 (patch) | |
| tree | ea7ade04a96f7a75a4549743125c268538974c99 /sys/arm64/cavium | |
| parent | 88fa0d734c49464b2d0db0d6210f02b9fa0b950b (diff) | |
Notes
Diffstat (limited to 'sys/arm64/cavium')
| -rw-r--r-- | sys/arm64/cavium/thunder_pcie_fdt.c | 31 | ||||
| -rw-r--r-- | sys/arm64/cavium/thunder_pcie_pem.c | 38 | ||||
| -rw-r--r-- | sys/arm64/cavium/thunder_pcie_pem_fdt.c | 23 |
3 files changed, 92 insertions, 0 deletions
diff --git a/sys/arm64/cavium/thunder_pcie_fdt.c b/sys/arm64/cavium/thunder_pcie_fdt.c index b786eef72bfd..e25d4a83973e 100644 --- a/sys/arm64/cavium/thunder_pcie_fdt.c +++ b/sys/arm64/cavium/thunder_pcie_fdt.c @@ -45,16 +45,24 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/openfirm.h> #include <dev/ofw/ofw_bus.h> #include <dev/ofw/ofw_bus_subr.h> + +#include <dev/pci/pcireg.h> +#include <dev/pci/pcivar.h> #include <dev/pci/pci_host_generic.h> +#include <dev/pci/pcib_private.h> #include "thunder_pcie_common.h" +#include "pcib_if.h" + #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); #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 device_method_t thunder_pcie_fdt_methods[] = { /* Device interface */ @@ -64,6 +72,9 @@ static device_method_t thunder_pcie_fdt_methods[] = { DEVMETHOD(bus_alloc_resource, thunder_pcie_fdt_alloc_resource), #endif + /* pcib interface */ + DEVMETHOD(pcib_get_id, thunder_pcie_fdt_get_id), + /* End */ DEVMETHOD_END }; @@ -112,6 +123,26 @@ thunder_pcie_fdt_attach(device_t dev) return (pci_host_generic_attach(dev)); } +static int +thunder_pcie_fdt_get_id(device_t pci, device_t child, enum pci_id_type type, + uintptr_t *id) +{ + phandle_t node; + int bsf; + + if (type != PCI_ID_MSI) + return (pcib_get_id(pci, child, type, id)); + + node = ofw_bus_get_node(pci); + if (OF_hasprop(node, "msi-map")) + return (generic_pcie_get_id(pci, child, type, id)); + + bsf = pci_get_rid(child); + *id = (pci_get_domain(child) << PCI_RID_DOMAIN_SHIFT) | bsf; + + return (0); +} + #ifdef THUNDERX_PASS_1_1_ERRATA static struct resource * thunder_pcie_fdt_alloc_resource(device_t dev, device_t child, int type, int *rid, diff --git a/sys/arm64/cavium/thunder_pcie_pem.c b/sys/arm64/cavium/thunder_pcie_pem.c index 78514b9b3e2c..7b4394f3f034 100644 --- a/sys/arm64/cavium/thunder_pcie_pem.c +++ b/sys/arm64/cavium/thunder_pcie_pem.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcivar.h> #include <dev/pci/pcireg.h> #include <dev/pci/pci_host_generic.h> +#include <dev/pci/pcib_private.h> #include <machine/bus.h> #include <machine/resource.h> @@ -131,6 +132,8 @@ static int thunder_pem_release_msi(device_t, device_t, int, int *); static int thunder_pem_alloc_msix(device_t, device_t, int *); static int thunder_pem_release_msix(device_t, device_t, int); static int thunder_pem_map_msi(device_t, device_t, int, uint64_t *, uint32_t *); +static int thunder_pem_get_id(device_t, device_t, enum pci_id_type, + uintptr_t *); static int thunder_pem_attach(device_t); static int thunder_pem_deactivate_resource(device_t, device_t, int, int, struct resource *); @@ -182,6 +185,7 @@ static device_method_t thunder_pem_methods[] = { DEVMETHOD(pcib_alloc_msi, thunder_pem_alloc_msi), DEVMETHOD(pcib_release_msi, thunder_pem_release_msi), DEVMETHOD(pcib_map_msi, thunder_pem_map_msi), + DEVMETHOD(pcib_get_id, thunder_pem_get_id), DEVMETHOD_END }; @@ -372,6 +376,40 @@ thunder_pem_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, } static int +thunder_pem_get_id(device_t pci, device_t child, enum pci_id_type type, + uintptr_t *id) +{ + int bsf; + int pem; + + if (type != PCI_ID_MSI) + return (pcib_get_id(pci, child, type, id)); + + bsf = pci_get_rid(child); + + /* PEM (PCIe MAC/root complex) number is equal to domain */ + pem = pci_get_domain(child); + + /* + * Set appropriate device ID (passed by the HW along with + * the transaction to memory) for different root complex + * numbers using hard-coded domain portion for each group. + */ + if (pem < 3) + *id = (0x1 << PCI_RID_DOMAIN_SHIFT) | bsf; + else if (pem < 6) + *id = (0x3 << PCI_RID_DOMAIN_SHIFT) | bsf; + else if (pem < 9) + *id = (0x9 << PCI_RID_DOMAIN_SHIFT) | bsf; + else if (pem < 12) + *id = (0xB << PCI_RID_DOMAIN_SHIFT) | bsf; + else + return (ENXIO); + + return (0); +} + +static int thunder_pem_identify(device_t dev) { struct thunder_pem_softc *sc; diff --git a/sys/arm64/cavium/thunder_pcie_pem_fdt.c b/sys/arm64/cavium/thunder_pcie_pem_fdt.c index 7c3a43647355..9e4770b302e5 100644 --- a/sys/arm64/cavium/thunder_pcie_pem_fdt.c +++ b/sys/arm64/cavium/thunder_pcie_pem_fdt.c @@ -65,6 +65,8 @@ static int thunder_pem_fdt_alloc_msi(device_t, device_t, int, int, int *); static int thunder_pem_fdt_release_msi(device_t, device_t, int, int *); static int thunder_pem_fdt_map_msi(device_t, device_t, int, uint64_t *, uint32_t *); +static int thunder_pem_fdt_get_id(device_t, device_t, enum pci_id_type, + uintptr_t *); static device_method_t thunder_pem_fdt_methods[] = { /* Device interface */ @@ -76,6 +78,7 @@ static device_method_t thunder_pem_fdt_methods[] = { DEVMETHOD(pcib_alloc_msi, thunder_pem_fdt_alloc_msi), DEVMETHOD(pcib_release_msi, thunder_pem_fdt_release_msi), DEVMETHOD(pcib_map_msi, thunder_pem_fdt_map_msi), + DEVMETHOD(pcib_get_id, thunder_pem_fdt_get_id), /* End */ DEVMETHOD_END @@ -142,3 +145,23 @@ thunder_pem_fdt_map_msi(device_t pci, device_t child, int irq, uint64_t *addr, return (arm_map_msi(pci, child, irq, addr, data)); } + +static int +thunder_pem_fdt_get_id(device_t dev, device_t child, enum pci_id_type type, + uintptr_t *id) +{ + phandle_t node; + uint32_t rid; + uint16_t pci_rid; + + if (type != PCI_ID_MSI) + return (pcib_get_id(dev, child, type, id)); + + node = ofw_bus_get_node(dev); + pci_rid = pci_get_rid(child); + + ofw_bus_msimap(node, pci_rid, NULL, &rid); + *id = rid; + + return (0); +} |
