aboutsummaryrefslogtreecommitdiff
path: root/include/npu2.h
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-03-24 12:22:23 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-03-30 19:37:48 +1100
commitd8c880ecc2c8308395e51e28b12fb19a826dc0f6 (patch)
tree10f6627ea89d7200c1201d483e41e3c6d9f7313b /include/npu2.h
parent98509ad54e14fe524ef0833a1bde35547ba2785f (diff)
downloadskiboot-d8c880ecc2c8308395e51e28b12fb19a826dc0f6.zip
skiboot-d8c880ecc2c8308395e51e28b12fb19a826dc0f6.tar.gz
skiboot-d8c880ecc2c8308395e51e28b12fb19a826dc0f6.tar.bz2
Introduce NPU2 support
NVLink2 is a new feature introduced on POWER9 systems. It is an evolution of of the NVLink1 feature included in POWER8+ systems but adds several new features including support for GPU address translation using the Nest MMU and cache coherence. Similar to NVLink1 the functionality is exposed to the OS as a series of virtual PCIe devices. However the actual hardware interfaces are significantly different which limits the amount of common code that can be shared between implementations in the firmware. This patch adds basic hardware initialisation and exposure of the virtual NVLink2 PCIe devices to the running OS. Signed-off-by: Alistair Popple <alistair@popple.id.au> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'include/npu2.h')
-rw-r--r--include/npu2.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/include/npu2.h b/include/npu2.h
new file mode 100644
index 0000000..ec62ad2
--- /dev/null
+++ b/include/npu2.h
@@ -0,0 +1,152 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __NPU2_H
+#define __NPU2_H
+
+/* Debugging options */
+#define NPU2DBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \
+ (p)->phb.opal_id, ##a)
+#define NPU2INF(p, fmt, a...) prlog(PR_INFO, "NPU%d: " fmt, \
+ (p)->phb.opal_id, ##a)
+#define NPU2ERR(p, fmt, a...) prlog(PR_ERR, "NPU%d: " fmt, \
+ (p)->phb.opal_id, ##a)
+
+/* Number of PEs supported */
+#define NPU2_MAX_PE_NUM 16
+#define NPU2_RESERVED_PE_NUM 15
+
+/* Return the stack (0-2) of a device */
+#define NPU2DEV_STACK(ndev) ((ndev)->index / 2)
+
+/* Return the brick number (0-1) within a stack */
+#define NPU2DEV_BRICK(ndev) ((ndev)->index % 2)
+
+/* This represents the state of the actual hardware BARs not the
+ * emulated PCIe BARs. The is a subtle difference between the two as
+ * not all BARs are exposed outside of skiboot. */
+struct npu2_bar {
+#define NPU2_BAR_FLAG_ENABLED 0x0010
+
+/* Generation ID's are a single space in the hardware but we split
+ * them in two for the emulated PCIe devices so we need to keep track
+ * of which one has been enabled/disabled. */
+#define NPU2_BAR_FLAG_ENABLED0 0x0080
+#define NPU2_BAR_FLAG_ENABLED1 0x0100
+ uint32_t flags;
+
+#define NPU2_BAR_TYPE_GLOBAL 0
+#define NPU2_BAR_TYPE_PHY 1
+#define NPU2_BAR_TYPE_NTL 2
+#define NPU2_BAR_TYPE_GENID 3
+#define NPU2_BAR_TYPE_MAX 4
+ uint32_t type;
+ uint64_t reg;
+ uint64_t stack;
+ uint64_t base;
+ uint64_t size;
+};
+
+/* Rpresents a BAR that is exposed via the PCIe emulated
+ * devices */
+struct npu2_pcie_bar {
+#define NPU2_PCIE_BAR_FLAG_SIZE_HI 0x0020
+#define NPU2_PCIE_BAR_FLAG_TRAPPED 0x0040
+ uint32_t flags;
+ struct npu2_bar *npu2_bar;
+ uint64_t base;
+ uint64_t size;
+};
+
+struct npu2;
+struct npu2_dev {
+ uint32_t index;
+ uint32_t flags;
+ uint64_t xscom;
+ void *regs;
+ struct dt_node *dt_node;
+ struct npu2_pcie_bar bars[2];
+ struct npu2 *npu;
+
+ /* Device and function numbers are allocated based on GPU
+ * association. Links to connected to the same GPU will be
+ * exposed as different functions of the same bus/device. */
+ uint32_t bdfn;
+ uint32_t gpu_bdfn;
+
+ /* PCI virtual device and the associated GPU device */
+ struct pci_virt_device *pvd;
+ struct phb *phb;
+ struct pci_device *pd;
+
+ /* Vendor specific capability */
+ uint32_t vendor_cap;
+
+ /* Which PHY lanes this device is associated with */
+ uint16_t lane_mask;
+
+ /* Track currently running procedure and step number */
+ uint16_t procedure_number;
+ uint16_t procedure_step;
+ uint64_t procedure_data;
+ unsigned long procedure_tb;
+ uint32_t procedure_status;
+
+ /* Used to associate the NPU device with GPU PCI devices */
+ const char *slot_label;
+};
+
+struct npu2 {
+ uint32_t index;
+ uint32_t flags;
+ uint32_t chip_id;
+ uint64_t xscom_base;
+ uint64_t at_xscom;
+ void *regs;
+ uint64_t mm_base;
+ uint64_t mm_size;
+ uint32_t base_lsi;
+ uint32_t total_devices;
+ struct npu2_dev *devices;
+
+ /* IODA cache */
+ uint64_t lxive_cache[8];
+ uint64_t bdf2pe_cache[36];
+ uint64_t tve_cache[16];
+ bool tx_zcal_complete[2];
+
+ /* Used to protect global MMIO space, in particular the XTS
+ * tables. */
+ struct lock lock;
+
+ struct phb phb;
+};
+
+static inline struct npu2 *phb_to_npu2(struct phb *phb)
+{
+ return container_of(phb, struct npu2, phb);
+}
+
+void npu2_write_4b(struct npu2 *p, uint64_t reg, uint64_t val);
+uint64_t npu2_read_4b(struct npu2 *p, uint64_t reg);
+void npu2_write(struct npu2 *p, uint64_t reg, uint64_t val);
+uint64_t npu2_read(struct npu2 *p, uint64_t reg);
+void npu2_write_mask(struct npu2 *p, uint64_t reg, uint64_t val, uint64_t mask);
+int64_t npu2_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf,
+ uint32_t offset, uint32_t len, uint32_t *data,
+ bool write);
+
+#endif /* __NPU2_H */