diff options
Diffstat (limited to 'roms/skiboot/include/npu3.h')
-rw-r--r-- | roms/skiboot/include/npu3.h | 192 |
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 */ |