[U-Boot] [RFC 08/22] pci: add thunderx pci/ecam driver
Tim Harvey
tharvey at gateworks.com
Fri Feb 22 18:03:05 UTC 2019
Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
board/cavium/thunderx/Kconfig | 4 +
board/cavium/thunderx/thunderx.c | 16 ++--
configs/thunderx_81xx_defconfig | 6 ++
configs/thunderx_88xx_defconfig | 6 ++
drivers/pci/Kconfig | 9 ++
drivers/pci/Makefile | 1 +
drivers/pci/pci_thunderx.c | 160 +++++++++++++++++++++++++++++++
include/pci_ids.h | 15 +++
8 files changed, 210 insertions(+), 7 deletions(-)
create mode 100644 drivers/pci/pci_thunderx.c
diff --git a/board/cavium/thunderx/Kconfig b/board/cavium/thunderx/Kconfig
index 16df1a9fc2..c840f9c1ed 100644
--- a/board/cavium/thunderx/Kconfig
+++ b/board/cavium/thunderx/Kconfig
@@ -1,5 +1,9 @@
if ARCH_THUNDERX
+config SYS_PCI_64BIT
+ bool
+ default y
+
config SYS_CPU
string
default "armv8"
diff --git a/board/cavium/thunderx/thunderx.c b/board/cavium/thunderx/thunderx.c
index 0cc03a463f..28cf2aee22 100644
--- a/board/cavium/thunderx/thunderx.c
+++ b/board/cavium/thunderx/thunderx.c
@@ -72,6 +72,15 @@ static struct mm_region thunderx_mem_map[] = {
struct mm_region *mem_map = thunderx_mem_map;
+#ifdef CONFIG_BOARD_EARLY_INIT_R
+int board_early_init_r(void)
+{
+ pci_init();
+
+ return 0;
+}
+#endif
+
int board_init(void)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)
@@ -127,10 +136,3 @@ int board_eth_init(bd_t *bis)
return rc;
}
-
-#ifdef CONFIG_PCI
-void pci_init_board(void)
-{
- printf("DEBUG: PCI Init TODO *****\n");
-}
-#endif
diff --git a/configs/thunderx_81xx_defconfig b/configs/thunderx_81xx_defconfig
index 4f6b4ad18c..3ec7d6cd4f 100644
--- a/configs/thunderx_81xx_defconfig
+++ b/configs/thunderx_81xx_defconfig
@@ -12,6 +12,7 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e028000000 debug maxcpus=4 rootwait rw root=/dev/mmcblk0p2 coherent_pool=16M"
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="ThunderX_81XX> "
# CONFIG_CMD_EXPORTENV is not set
@@ -20,10 +21,15 @@ CONFIG_SYS_PROMPT="ThunderX_81XX> "
# CONFIG_CMD_SAVEENV is not set
# CONFIG_CMD_ENV_EXISTS is not set
# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_PCI=y
# CONFIG_CMD_NET is not set
CONFIG_DEFAULT_DEVICE_TREE="thunderx-81xx"
CONFIG_DM=y
# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_THUNDERX=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_PL011=y
CONFIG_DEBUG_UART_SKIP_INIT=y
diff --git a/configs/thunderx_88xx_defconfig b/configs/thunderx_88xx_defconfig
index fe4643f52e..e30d549896 100644
--- a/configs/thunderx_88xx_defconfig
+++ b/configs/thunderx_88xx_defconfig
@@ -12,6 +12,7 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0,115200n8 earlycon=pl011,0x87e024000000 debug maxcpus=48 rootwait rw root=/dev/sda2 coherent_pool=16M"
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_HUSH_PARSER=y
# CONFIG_AUTO_COMPLETE is not set
CONFIG_SYS_PROMPT="ThunderX_88XX> "
@@ -21,10 +22,15 @@ CONFIG_SYS_PROMPT="ThunderX_88XX> "
# CONFIG_CMD_SAVEENV is not set
# CONFIG_CMD_ENV_EXISTS is not set
# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_PCI=y
# CONFIG_CMD_NET is not set
CONFIG_DEFAULT_DEVICE_TREE="thunderx-88xx"
CONFIG_DM=y
# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_THUNDERX=y
CONFIG_DM_SERIAL=y
CONFIG_DEBUG_UART_PL011=y
CONFIG_DEBUG_UART_SKIP_INIT=y
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index f59803dbd6..7be97addc4 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -90,6 +90,15 @@ config PCI_TEGRA
with a total of 5 lanes. Some boards require this for Ethernet
support to work (e.g. beaver, jetson-tk1).
+config PCI_THUNDERX
+ bool "ThunderX PCI support"
+ depends on ARCH_THUNDERX
+ select PCIE_ECAM_GENERIC
+ help
+ Enable support for the Cavium ThunderX SoC family PCI controllers.
+ These controllers provide PCI configuration access to all on-board
+ peripherals so it should only be disabled for testing purposes
+
config PCI_XILINX
bool "Xilinx AXI Bridge for PCI Express"
depends on DM_PCI
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 4923641895..0974e77789 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o
obj-$(CONFIG_PCI_AARDVARK) += pci-aardvark.o
obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o
obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o
+obj-$(CONFIG_PCI_THUNDERX) += pci_thunderx.o
obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o
obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o
obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o
diff --git a/drivers/pci/pci_thunderx.c b/drivers/pci/pci_thunderx.c
new file mode 100644
index 0000000000..f22141ca44
--- /dev/null
+++ b/drivers/pci/pci_thunderx.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Cavium Inc.
+ */
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+
+#include <asm/io.h>
+
+struct thunderx_pci {
+ unsigned int type;
+ struct fdt_resource cfg;
+ struct fdt_resource bus;
+};
+
+static int pci_thunderx_pem_read_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ struct thunderx_pci *pcie = (void *)dev_get_priv(bus);
+ struct pci_controller *hose = dev_get_uclass_priv(bus);
+ uintptr_t address;
+ u32 b, d, f;
+ u8 hdrtype;
+ u8 pri_bus = pcie->bus.start + 1 - hose->first_busno;
+ u32 bus_offs = (pri_bus << 16) | (pri_bus << 8) | (pri_bus << 0);
+
+ b = PCI_BUS(bdf) + 1 - hose->first_busno;
+ d = PCI_DEV(bdf);
+ f = PCI_FUNC(bdf);
+
+ address = (b << 24) | (d << 19) | (f << 16);
+
+ address += pcie->cfg.start;
+
+ *valuep = pci_conv_32_to_size(~0UL, offset, size);
+
+ if (b == 1 && d > 0)
+ return 0;
+
+ switch (size) {
+ case PCI_SIZE_8:
+ *valuep = readb(address + offset);
+ break;
+ case PCI_SIZE_16:
+ *valuep = readw(address + offset);
+ break;
+ case PCI_SIZE_32:
+ *valuep = readl(address + offset);
+ break;
+ default:
+ printf("Invalid size\n");
+ }
+
+ hdrtype = readb(address + PCI_HEADER_TYPE);
+
+ if ((hdrtype == PCI_HEADER_TYPE_BRIDGE) &&
+ (offset >= PCI_PRIMARY_BUS) &&
+ (offset <= PCI_SUBORDINATE_BUS) &&
+ *valuep != pci_conv_32_to_size(~0UL, offset, size)) {
+ *valuep -= pci_conv_32_to_size(bus_offs, offset, size);
+ }
+ return 0;
+}
+
+static int pci_thunderx_pem_write_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong value,
+ enum pci_size_t size)
+{
+ struct thunderx_pci *pcie = (void *)dev_get_priv(bus);
+ struct pci_controller *hose = dev_get_uclass_priv(bus);
+ uintptr_t address;
+ u32 b, d, f;
+ u8 hdrtype;
+ u8 pri_bus = pcie->bus.start + 1 - hose->first_busno;
+ u32 bus_offs = (pri_bus << 16) | (pri_bus << 8) | (pri_bus << 0);
+
+ b = PCI_BUS(bdf) + 1 - hose->first_busno;
+ d = PCI_DEV(bdf);
+ f = PCI_FUNC(bdf);
+
+ address = (b << 24) | (d << 19) | (f << 16);
+
+ address += pcie->cfg.start;
+
+ hdrtype = readb(address + PCI_HEADER_TYPE);
+
+ if ((hdrtype == PCI_HEADER_TYPE_BRIDGE) &&
+ (offset >= PCI_PRIMARY_BUS) &&
+ (offset <= PCI_SUBORDINATE_BUS) &&
+ (value != pci_conv_32_to_size(~0UL, offset, size))) {
+ value += pci_conv_32_to_size(bus_offs, offset, size);
+ }
+
+ if (b == 1 && d > 0)
+ return 0;
+
+ switch (size) {
+ case PCI_SIZE_8:
+ writeb(value, address + offset);
+ break;
+ case PCI_SIZE_16:
+ writew(value, address + offset);
+ break;
+ case PCI_SIZE_32:
+ writel(value, address + offset);
+ break;
+ default:
+ printf("Invalid size\n");
+ }
+ return 0;
+}
+
+static int pci_thunderx_ofdata_to_platdata(struct udevice *dev)
+{
+ return 0;
+}
+
+static int pci_thunderx_probe(struct udevice *dev)
+{
+ struct thunderx_pci *pcie = (void *)dev_get_priv(dev);
+ int err;
+
+ err = fdt_get_resource(gd->fdt_blob, dev->node.of_offset, "reg", 0,
+ &pcie->cfg);
+ if (err) {
+ printf("Error reading resource: %s\n", fdt_strerror(err));
+ return err;
+ }
+
+ err = fdtdec_get_pci_bus_range(gd->fdt_blob, dev->node.of_offset,
+ &pcie->bus);
+ if (err) {
+ printf("Error reading resource: %s\n", fdt_strerror(err));
+ return err;
+ }
+
+ return 0;
+}
+
+static const struct dm_pci_ops pci_thunderx_pem_ops = {
+ .read_config = pci_thunderx_pem_read_config,
+ .write_config = pci_thunderx_pem_write_config,
+};
+
+static const struct udevice_id pci_thunderx_pem_ids[] = {
+ { .compatible = "cavium,pci-host-thunder-pem" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_thunderx_pcie) = {
+ .name = "pci_thunderx_pem",
+ .id = UCLASS_PCI,
+ .of_match = pci_thunderx_pem_ids,
+ .ops = &pci_thunderx_pem_ops,
+ .ofdata_to_platdata = pci_thunderx_ofdata_to_platdata,
+ .probe = pci_thunderx_probe,
+ .priv_auto_alloc_size = sizeof(struct thunderx_pci),
+};
diff --git a/include/pci_ids.h b/include/pci_ids.h
index fdda679cc0..948771271e 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -3109,6 +3109,21 @@
#define PCI_VENDOR_ID_3COM_2 0xa727
+#define PCI_VENDOR_ID_CAVIUM 0x177d
+#define PCI_DEVICE_ID_THUNDERX_NIC_VF_1 0x0011
+#define PCI_DEVICE_ID_THUNDERX_GPIO 0xa00a
+#define PCI_DEVICE_ID_THUNDERX_SPI 0xa00b
+#define PCI_DEVICE_ID_THUNDERX_MMC 0xa010
+#define PCI_DEVICE_ID_THUNDERX_TWSI 0xa012
+#define PCI_DEVICE_ID_THUNDERX_AHCI 0xa01c
+#define PCI_DEVICE_ID_THUNDERX_NIC_PF 0xa01e
+#define PCI_DEVICE_ID_THUNDERX_SMI 0xa02b
+#define PCI_DEVICE_ID_THUNDERX_BGX 0xa026
+#define PCI_DEVICE_ID_THUNDERX_NIC_VF 0xa034
+#define PCI_DEVICE_ID_THUNDERX_RGX 0xa054
+#define PCI_DEVICE_ID_THUNDERX_XHCI 0xa055
+#define PCI_DEVICE_ID_THUNDERX_NIC_XCV 0xa056
+
#define PCI_VENDOR_ID_DIGIUM 0xd161
#define PCI_DEVICE_ID_DIGIUM_HFC4S 0xb410
--
2.17.1
More information about the U-Boot
mailing list