aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/cavium
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2016-05-16 09:31:44 +0000
committerAndrew Turner <andrew@FreeBSD.org>2016-05-16 09:31:44 +0000
commit1e43b18c4b5960382eb9a0df487360dba4bbd349 (patch)
treeea7ade04a96f7a75a4549743125c268538974c99 /sys/arm64/cavium
parent88fa0d734c49464b2d0db0d6210f02b9fa0b950b (diff)
Notes
Diffstat (limited to 'sys/arm64/cavium')
-rw-r--r--sys/arm64/cavium/thunder_pcie_fdt.c31
-rw-r--r--sys/arm64/cavium/thunder_pcie_pem.c38
-rw-r--r--sys/arm64/cavium/thunder_pcie_pem_fdt.c23
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);
+}