summaryrefslogtreecommitdiffstats
path: root/sys/arm64
diff options
context:
space:
mode:
authorwma <wma@FreeBSD.org>2016-02-26 12:16:11 +0000
committerwma <wma@FreeBSD.org>2016-02-26 12:16:11 +0000
commitac0c41dc12dbe4f4bfbab46621fb4fa119241aae (patch)
tree5b1e8c1e775ceb401e6046e0e9a5c467b5796f12 /sys/arm64
parent15f8acc5edf006b1923212d3a62cf21b853de03d (diff)
downloadFreeBSD-src-ac0c41dc12dbe4f4bfbab46621fb4fa119241aae.zip
FreeBSD-src-ac0c41dc12dbe4f4bfbab46621fb4fa119241aae.tar.gz
Restore ThunderX Pass1.1 PCI changes removed by r295962
If Enhanced Allocation is not used, we can't allocate any random range. All internal devices have hardcoded place where they can be located within PCI address space. Fortunately, we can read this value from BAR. Obtained from: Semihalf Sponsored by: Cavium Approved by: cognet (mentor) Reviewed by: zbb Differential revision: https://reviews.freebsd.org/D5455
Diffstat (limited to 'sys/arm64')
-rw-r--r--sys/arm64/cavium/thunder_pcie_common.c43
-rw-r--r--sys/arm64/cavium/thunder_pcie_common.h4
-rw-r--r--sys/arm64/cavium/thunder_pcie_fdt.c21
3 files changed, 67 insertions, 1 deletions
diff --git a/sys/arm64/cavium/thunder_pcie_common.c b/sys/arm64/cavium/thunder_pcie_common.c
index bb0e922..2068070 100644
--- a/sys/arm64/cavium/thunder_pcie_common.c
+++ b/sys/arm64/cavium/thunder_pcie_common.c
@@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_pci.h>
#endif
-#include <dev/pci/pcivar.h>
+#include <sys/pciio.h>
#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pci_private.h>
#include <dev/pci/pcib_private.h>
#include <dev/pci/pci_host_generic.h>
@@ -142,3 +144,42 @@ thunder_pcie_identify_ecam(device_t dev, int *ecam)
return (0);
}
+
+#ifdef THUNDERX_PASS_1_1_ERRATA
+struct resource *
+thunder_pcie_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)
+{
+ pci_addr_t map, testval;
+
+ /*
+ * If Enhanced Allocation is not used, we can't allocate any random
+ * range. All internal devices have hardcoded place where they can
+ * be located within PCI address space. Fortunately, we can read
+ * this value from BAR.
+ */
+ if (((type == SYS_RES_IOPORT) || (type == SYS_RES_MEMORY)) &&
+ RMAN_IS_DEFAULT_RANGE(start, end)) {
+
+ /* Read BAR manually to get resource address and size */
+ pci_read_bar(child, *rid, &map, &testval, NULL);
+
+ /* Mask the information bits */
+ if (PCI_BAR_MEM(map))
+ map &= PCIM_BAR_MEM_BASE;
+ else
+ map &= PCIM_BAR_IO_BASE;
+
+ if (PCI_BAR_MEM(testval))
+ testval &= PCIM_BAR_MEM_BASE;
+ else
+ testval &= PCIM_BAR_IO_BASE;
+
+ start = map;
+ end = start + count - 1;
+ }
+
+ return (pci_host_generic_alloc_resource(dev, child, type, rid, start,
+ end, count, flags));
+}
+#endif
diff --git a/sys/arm64/cavium/thunder_pcie_common.h b/sys/arm64/cavium/thunder_pcie_common.h
index fc8fa13..b0df621 100644
--- a/sys/arm64/cavium/thunder_pcie_common.h
+++ b/sys/arm64/cavium/thunder_pcie_common.h
@@ -39,5 +39,9 @@ uint32_t range_addr_is_phys(struct pcie_range *, uint64_t, uint64_t);
uint64_t range_addr_pci_to_phys(struct pcie_range *, uint64_t);
int thunder_pcie_identify_ecam(device_t, int *);
+#ifdef THUNDERX_PASS_1_1_ERRATA
+struct resource *thunder_pcie_alloc_resource(device_t,
+ device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
+#endif
#endif /* _CAVIUM_THUNDER_PCIE_COMMON_H_ */
diff --git a/sys/arm64/cavium/thunder_pcie_fdt.c b/sys/arm64/cavium/thunder_pcie_fdt.c
index f0cad72..b786eef 100644
--- a/sys/arm64/cavium/thunder_pcie_fdt.c
+++ b/sys/arm64/cavium/thunder_pcie_fdt.c
@@ -49,6 +49,10 @@ __FBSDID("$FreeBSD$");
#include "thunder_pcie_common.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);
@@ -56,6 +60,9 @@ 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),
+#endif
/* End */
DEVMETHOD_END
@@ -105,3 +112,17 @@ thunder_pcie_fdt_attach(device_t dev)
return (pci_host_generic_attach(dev));
}
+#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)
+{
+
+ if ((int)ofw_bus_get_node(child) > 0)
+ return (pci_host_generic_alloc_resource(dev, child,
+ type, rid, start, end, count, flags));
+
+ return (thunder_pcie_alloc_resource(dev, child,
+ type, rid, start, end, count, flags));
+}
+#endif
OpenPOWER on IntegriCloud