aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/include/npu.h
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/include/npu.h')
-rw-r--r--roms/skiboot/include/npu.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/roms/skiboot/include/npu.h b/roms/skiboot/include/npu.h
new file mode 100644
index 000000000..50cc9c9fc
--- /dev/null
+++ b/roms/skiboot/include/npu.h
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2013-2017 IBM Corp. */
+
+#ifndef __NPU_H
+#define __NPU_H
+
+#include <io.h>
+
+/* Number of PEs supported */
+#define NPU_NUM_OF_PES 4
+
+/* Each brick has 2 MMIO BARs at the maximum. BAR0 is always used to
+ * map the 128KB TL/DL registers. BAR1 is used to map either the PL or
+ * the AT registers which are not exposed to the OS.
+ */
+#define NPU_BRICK_NUM_OF_BARS 2
+#define NPU_BRICK_TL_BAR_SIZE 0x20000
+#define NPU_BRICK_PL_BAR_SIZE 0x200000
+
+/* Bytes of the emulated NPU PCI device config space. We are
+ * emulating PCI express device, not legacy one
+ */
+#define NPU_DEV_CFG_SIZE 0x100
+
+/* Interrupt mapping
+ *
+ * NPU PHB doesn't support MSI interrupts. It only supports
+ * 8 LSI interrupts: [0, 3] for bricks' DL blocks. [4, 5]
+ * for reporting errors from DL blocks. [6, 7] for reporting
+ * errors from TL blocks, NPCQs and AT.
+ */
+#define NPU_LSI_IRQ_COUNT 8
+#define NPU_LSI_INT_DL0 0
+#define NPU_LSI_INT_DL1 1
+#define NPU_LSI_INT_DL2 2
+#define NPU_LSI_INT_DL3 3
+#define NPU_LSI_IRQ_MIN 0x7F0
+#define NPU_LSI_IRQ_MAX (NPU_LSI_IRQ_MIN + NPU_LSI_IRQ_COUNT - 1)
+#define NPU_LSI_IRQ_BASE(chip, phb) (P8_CHIP_IRQ_PHB_BASE(chip, phb) | NPU_LSI_IRQ_MIN)
+#define NPU_IRQ_NUM(irq) (irq & 0x7FF)
+
+/* NPU device capability descriptor. All PCI capabilities is
+ * organized as linked list. Each PCI capability has specific
+ * hook to populate when initializing NPU device.
+ */
+struct npu_dev;
+struct npu_dev_cap {
+ uint16_t id;
+ uint16_t start;
+ uint16_t end;
+ struct npu_dev *dev;
+ void (*populate)(struct npu_dev_cap *cap);
+ struct list_node link;
+};
+
+struct npu_dev_bar {
+ uint32_t flags;
+ uint32_t xscom;
+ uint64_t base;
+ uint64_t size;
+ uint32_t bar_sz;
+ bool trapped;
+};
+
+/* Each device contains 2 links. The device will be exposed as
+ * standard PCIE device and the config space is emulated by skiboot.
+ */
+struct npu_dev {
+ uint32_t flags;
+ uint32_t index;
+ uint64_t xscom;
+ void *pl_base;
+ uint64_t pl_xscom_base;
+ struct npu_dev_bar bar;
+ struct phb *phb;
+
+ /* The link@x node */
+ struct dt_node *dt_node;
+
+ /* PCI virtual device and the associated GPU device */
+ struct pci_virt_device *pvd;
+ struct pci_device *pd;
+ struct npu *npu;
+ struct list_head capabilities;
+
+ /* Which PHY lanes this device is associated with */
+ uint16_t lane_mask;
+
+ /* Used to store the currently running procedure number for
+ * this device. */
+ uint16_t procedure_number;
+
+ /* Used to store the step within a procedure that we are up
+ * to. */
+ uint16_t procedure_step;
+
+ /* Arbitrary data used by each procedure to track status. */
+ uint64_t procedure_data;
+
+ /* Used to timeout long running procedures. */
+ unsigned long procedure_tb;
+
+ uint32_t procedure_status;
+
+ uint64_t pe_number;
+
+ /* Used to associate the NPU device with GPU PCI devices */
+ const char *slot_label;
+};
+
+/* NPU PHB descriptor */
+struct npu {
+ uint32_t flags;
+ uint32_t index;
+ uint32_t chip_id;
+ uint64_t xscom_base;
+ uint64_t at_xscom;
+ void *at_regs;
+ uint32_t base_lsi;
+ uint64_t mm_base;
+ uint64_t mm_size;
+ uint32_t total_devices;
+ struct npu_dev *devices;
+
+ /* IODA cache */
+ uint64_t lxive_cache[8];
+ uint64_t pce_cache[6];
+ uint64_t tve_cache[NPU_NUM_OF_PES];
+
+ bool tx_zcal_complete[2];
+ bool fenced;
+
+ struct phb phb;
+};
+
+static inline struct npu *phb_to_npu(struct phb *phb)
+{
+ return container_of(phb, struct npu, phb);
+}
+
+static inline void npu_ioda_sel(struct npu *p, uint32_t table,
+ uint32_t addr, bool autoinc)
+{
+ out_be64(p->at_regs + NPU_IODA_ADDR,
+ (autoinc ? NPU_IODA_AD_AUTOINC : 0) |
+ SETFIELD(NPU_IODA_AD_TSEL, 0ul, table) |
+ SETFIELD(NPU_IODA_AD_TADR, 0ul, addr));
+}
+
+void npu_scom_init(struct npu_dev *dev);
+
+int64_t npu_dev_procedure(void *dev, struct pci_cfg_reg_filter *pcrf,
+ uint32_t offset, uint32_t len, uint32_t *data,
+ bool write);
+
+void npu_set_fence_state(struct npu *p, bool fence);
+void npu_dev_procedure_reset(struct npu_dev *dev);
+
+#define NPUDBG(p, fmt, a...) prlog(PR_DEBUG, "NPU%d: " fmt, \
+ (p)->phb.opal_id, ##a)
+#define NPUINF(p, fmt, a...) prlog(PR_INFO, "NPU%d: " fmt, \
+ (p)->phb.opal_id, ##a)
+
+#define NPUDEVDBG(p, fmt, a...) NPUDBG((p)->npu, fmt, ##a)
+#define NPUDEVINF(p, fmt, a...) NPUINF((p)->npu, fmt, ##a)
+
+#endif /* __NPU_H */