aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/include/npu3.h
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/include/npu3.h')
-rw-r--r--roms/skiboot/include/npu3.h192
1 files changed, 192 insertions, 0 deletions
diff --git a/roms/skiboot/include/npu3.h b/roms/skiboot/include/npu3.h
new file mode 100644
index 000000000..dda60ae1c
--- /dev/null
+++ b/roms/skiboot/include/npu3.h
@@ -0,0 +1,192 @@
+/* Copyright 2019 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 __NPU3_H
+#define __NPU3_H
+
+#include <phys-map.h>
+#include <pci.h>
+#include <npu3-regs.h>
+#include <phb4.h>
+
+enum npu3_dev_type {
+ NPU3_DEV_TYPE_UNKNOWN = 0,
+ NPU3_DEV_TYPE_NVLINK,
+ NPU3_DEV_TYPE_ANY = INT_MAX
+};
+
+/* Information about a currently running hw procedure */
+struct npu3_procedure {
+ uint16_t number;
+ uint16_t step;
+ uint32_t status;
+ unsigned long timeout;
+};
+
+/* Used to expose a hardware BAR (or logical slice of it) outside skiboot */
+struct npu3_bar {
+ bool enable;
+ uint64_t addr;
+ uint64_t size;
+ uint64_t trap;
+};
+
+struct npu3_dev_nvlink {
+ /*
+ * PCI virtual device. BDFN is allocated based on NPU association.
+ * Links connected to the same NPU will be exposed as different
+ * functions of the same bus/device.
+ */
+ struct pci_virt_device *pvd;
+
+ /* The PCI device created from pvd */
+ const char *loc_code;
+ struct pci_device *pd;
+
+ /* The associated GPU device */
+ struct pci_device *gpu;
+};
+
+struct npu3_dev {
+ enum npu3_dev_type type;
+ uint32_t index;
+ struct dt_node *dn;
+ struct npu3 *npu;
+ struct npu3_procedure proc;
+ uint64_t link_speed;
+
+ struct npu3_bar ntl_bar;
+ struct npu3_bar genid_bar;
+
+ /* Associated PHY information */
+ uint32_t ob_chiplet;
+ uint32_t phy_lane_mask;
+
+ /* For NPU3_DEV_TYPE_NVLINK */
+ struct npu3_dev_nvlink nvlink;
+};
+
+struct npu3_nvlink {
+ struct phb phb;
+ uint32_t ctx_ref[NPU3_XTS_BDF_MAP_MAX];
+};
+
+#define NPU3_LINKS_PER_NPU 4
+
+struct npu3 {
+ uint32_t index;
+ struct dt_node *dt_node;
+ uint32_t chip_id;
+ uint64_t xscom_base;
+
+ /* Global MMIO window (all NPU regs) */
+ uint64_t regs[2];
+
+ uint32_t irq_base;
+ struct lock lock;
+ bool tx_zcal_complete;
+
+ struct npu3_dev devices[NPU3_LINKS_PER_NPU];
+
+ /* Shared by any NPU3_DEV_TYPE_NVLINK devices */
+ struct npu3_nvlink nvlink;
+};
+
+static inline struct npu3 *npu3_phb_to_npu(struct phb *phb)
+{
+ assert(phb->phb_type == phb_type_npu_v3);
+ return container_of(phb, struct npu3, nvlink.phb);
+}
+
+/* Chip-scope index of the link */
+static inline uint32_t npu3_chip_dev_index(struct npu3_dev *dev)
+{
+ return dev->npu->index * NPU3_LINKS_PER_NPU + dev->index;
+}
+
+struct npu3_dev *npu3_next_dev(struct npu3 *npu, struct npu3_dev *dev,
+ enum npu3_dev_type type);
+
+#define npu3_for_each_dev_type(dev, npu, type) \
+ for (dev = NULL; (dev = npu3_next_dev(npu, dev, type));)
+
+#define npu3_for_each_nvlink_dev(dev, npu) \
+ npu3_for_each_dev_type(dev, npu, NPU3_DEV_TYPE_NVLINK)
+
+#define npu3_for_each_dev(dev, npu) \
+ npu3_for_each_dev_type(dev, npu, NPU3_DEV_TYPE_ANY)
+
+struct npu3 *npu3_next_nvlink_npu(struct npu3 *npu, uint32_t chip_id);
+
+#define npu3_for_each_chip_nvlink_npu(npu, chip_id) \
+ for (npu = NULL; (npu = npu3_next_nvlink_npu(npu, chip_id));)
+
+#define NPU3_ANY_CHIP INT_MAX
+#define npu3_for_each_nvlink_npu(npu) \
+ npu3_for_each_chip_nvlink_npu(npu, NPU3_ANY_CHIP)
+
+void npu3_init_nvlink(struct npu3 *npu);
+void npu3_dev_enable_bars(struct npu3_dev *dev, bool enable);
+int64_t npu3_dev_reset(struct npu3_dev *dev);
+
+uint32_t npu3_chip_possible_gpus(void);
+int32_t npu3_dev_gpu_index(struct npu3_dev *dev);
+
+/* NPU RING register access */
+void npu3_write(struct npu3 *npu, uint64_t reg, uint64_t val);
+uint64_t npu3_read(struct npu3 *npu, uint64_t reg);
+void npu3_write_4b(struct npu3 *npu, uint64_t reg, uint32_t val);
+uint32_t npu3_read_4b(struct npu3 *npu, uint64_t reg);
+
+/* Link flags */
+#define NPU3_DEV_PCI_LINKED 0x1
+#define NPU3_DEV_DL_RESET 0x2
+
+void npu3_pvd_flag_set(struct npu3_dev *dev, uint8_t flag);
+void npu3_pvd_flag_clear(struct npu3_dev *dev, uint8_t flag);
+
+/* PHY procedures */
+#define NPU3_PROC_STATUS_MASK 0xc000000f
+#define NPU3_PROC_INPROGRESS (1 << 31)
+#define NPU3_PROC_COMPLETE (1 << 30)
+#define NPU3_PROC_NEXT (1 << 29)
+#define NPU3_PROC_FAILED 2
+#define NPU3_PROC_ABORTED 3
+#define NPU3_PROC_UNSUPPORTED 4
+
+void npu3_dev_procedure_init(struct npu3_dev *dev, uint32_t pnum);
+uint32_t npu3_dev_procedure_status(struct npu3_dev *dev);
+
+/* OPAL entry points */
+int64_t npu3_init_context(struct phb *phb, uint64_t msr, uint64_t bdf);
+int64_t npu3_destroy_context(struct phb *phb, uint64_t bdf);
+int64_t npu3_map_lpar(struct phb *phb, uint64_t bdf, uint64_t lparid,
+ uint64_t lpcr);
+int64_t npu3_set_relaxed_order(struct phb *phb, uint32_t gcid, int pec,
+ bool enable);
+
+#define NPU3_PHB_INDEX_BASE 6 /* immediately after real PHBs */
+static inline int npu3_get_phb_index(unsigned int npu_index)
+{
+ return NPU3_PHB_INDEX_BASE + npu_index;
+}
+
+static inline int npu3_get_opal_id(unsigned int chip_id, unsigned int index)
+{
+ return phb4_get_opal_id(chip_id, index);
+}
+
+#endif /* __NPU3_H */