Signed-off-by: Tim Harvey <thar...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to