diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/npu2-common.c | 13 | ||||
-rw-r--r-- | hw/npu2-opencapi.c | 13 | ||||
-rw-r--r-- | hw/npu2.c | 20 |
3 files changed, 35 insertions, 11 deletions
diff --git a/hw/npu2-common.c b/hw/npu2-common.c index 71440f61..d076b490 100644 --- a/hw/npu2-common.c +++ b/hw/npu2-common.c @@ -21,6 +21,19 @@ #include <npu2-regs.h> #include <bitutils.h> +enum npu2_dev_type npu2_dt_link_dev_type(struct dt_node *link) +{ + const char *link_type = dt_prop_get(link, "ibm,npu-link-type") ?: + "unknown"; + if (streq(link_type, "nvlink")) { + return NPU2_DEV_TYPE_NVLINK; + } else if (streq(link_type, "opencapi")) { + return NPU2_DEV_TYPE_OPENCAPI; + } else { + return NPU2_DEV_TYPE_UNKNOWN; + } +} + /* * We use the indirect method because it uses the same addresses as * the MMIO offsets (NPU RING) diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c index d085cd15..f82e6562 100644 --- a/hw/npu2-opencapi.c +++ b/hw/npu2-opencapi.c @@ -1701,9 +1701,12 @@ static void npu2_opencapi_probe(struct dt_node *dn) /* Don't try to init when we have an NVLink link */ dt_for_each_compatible(dn, link, "ibm,npu-link") { - prlog(PR_DEBUG, "OCAPI: NPU%d: NVLink link found, skipping\n", - index); - return; + if (npu2_dt_link_dev_type(link) != NPU2_DEV_TYPE_OPENCAPI) { + prlog(PR_DEBUG, + "OCAPI: NPU%d: Non-OpenCAPI link found, skipping OpenCAPI init\n", + index); + return; + } } path = dt_get_path(dn); @@ -1728,7 +1731,7 @@ static void npu2_opencapi_probe(struct dt_node *dn) n->regs = (void *)reg[0]; n->dt_node = dn; - dt_for_each_compatible(dn, link, "ibm,npu-link-opencapi") { + dt_for_each_compatible(dn, link, "ibm,npu-link") { dev_index = dt_prop_get_u32(link, "ibm,npu-link-index"); prlog(PR_INFO, "OCAPI: Configuring link index %lld\n", dev_index); @@ -1748,7 +1751,7 @@ static void npu2_opencapi_probe(struct dt_node *dn) if (rc) goto failed; - dt_for_each_compatible(dn, link, "ibm,npu-link-opencapi") { + dt_for_each_compatible(dn, link, "ibm,npu-link") { npu2_opencapi_setup_device(link, n, &n->devices[i]); i++; } @@ -1345,17 +1345,25 @@ static void assign_mmio_bars(uint64_t gcid, uint32_t scom, uint64_t reg[2], uint static void npu2_probe_phb(struct dt_node *dn) { struct proc_chip *proc_chip; - struct dt_node *np; + struct dt_node *np, *link; + bool ocapi_detected = false, nvlink_detected = false; uint32_t gcid, scom, index, phb_index, links; uint64_t reg[2], mm_win[2], val; char *path; /* Abort if any OpenCAPI links detected */ - if (dt_find_compatible_node(dn, NULL, "ibm,npu-link-opencapi")) { - /* Die if there's also an NVLink link */ - assert(!dt_find_compatible_node(dn, NULL, "ibm,npu-link")); - prlog(PR_INFO, "NPU: OpenCAPI link configuration detected, " - "not initialising NVLink\n"); + dt_for_each_compatible(dn, link, "ibm,npu-link") { + if (npu2_dt_link_dev_type(link) == NPU2_DEV_TYPE_OPENCAPI) + ocapi_detected = true; + else + nvlink_detected = true; + } + + if (ocapi_detected && nvlink_detected) { + prlog(PR_ERR, "NPU: NVLink and OpenCAPI devices on same chip not supported\n"); + assert(false); + } else if (ocapi_detected) { + prlog(PR_INFO, "NPU: OpenCAPI link configuration detected, not initialising NVLink\n"); return; } |