[Skiboot] [PATCH 3/7] hw/npu2: Use NVLink irq setup for OpenCAPI

Frederic Barrat fbarrat at linux.ibm.com
Thu Mar 21 05:35:18 AEDT 2019


Start using the irq setup code from NVLink for OpenCAPI, since the 2
versions are so close. There are only 2 differences:

- the NPU may trigger more interrupts for OpenCAPI, 35 vs. 23, though
  none are configured to be triggered for now.

- we need to enable the 4 translation faults interrupts for OpenCAPI.

Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
Signed-off-by: Andrew Donnellan <andrew.donnellan at au1.ibm.com>
---
 hw/npu2-common.c   | 19 ++++++++++++++----
 hw/npu2-opencapi.c | 50 ++++------------------------------------------
 include/npu2.h     |  1 -
 3 files changed, 19 insertions(+), 51 deletions(-)

diff --git a/hw/npu2-common.c b/hw/npu2-common.c
index b0d55f5d..0b46f68c 100644
--- a/hw/npu2-common.c
+++ b/hw/npu2-common.c
@@ -26,7 +26,7 @@
 #include <xive.h>
 
 #define NPU2_IRQ_BASE_SHIFT 13
-#define NPU2_N_DL_IRQS 23
+#define NPU2_N_DL_IRQS 35
 #define NPU2_N_DL_IRQS_ALIGN 64
 
 /*
@@ -145,6 +145,18 @@ static char *npu2_ipi_name(struct irq_source *is, uint32_t isn)
 	case 20: name = "CQ Event"; break;
 	case 21: name = "MISC Event"; break;
 	case 22: name = "NMMU Local Xstop"; break;
+	case 23: name = "Translate Fail (brick 2)"; break;
+	case 24: name = "Translate Fail (brick 3)"; break;
+	case 25: name = "Translate Fail (brick 4)"; break;
+	case 26: name = "Translate Fail (brick 5)"; break;
+	case 27: name = "OTL Event (brick 2)"; break;
+	case 28: name = "OTL Event (brick 3)"; break;
+	case 29: name = "OTL Event (brick 4)"; break;
+	case 30: name = "OTL Event (brick 5)"; break;
+	case 31: name = "XSL Event (brick 2)"; break;
+	case 32: name = "XSL Event (brick 3)"; break;
+	case 33: name = "XSL Event (brick 4)"; break;
+	case 34: name = "XSL Event (brick 5)"; break;
 	default: name = "Unknown";
 	}
 	return strdup(name);
@@ -177,7 +189,7 @@ static void setup_irqs(struct npu2 *p)
 
 	p->base_lsi = xive_alloc_ipi_irqs(p->chip_id, NPU2_N_DL_IRQS, NPU2_N_DL_IRQS_ALIGN);
 	if (p->base_lsi == XIVE_IRQ_ERROR) {
-		prlog(PR_ERR, "NPU: Failed to allocate interrupt sources, IRQs for NDL No-stall events will not be available.\n");
+		prlog(PR_ERR, "NPU: Failed to allocate interrupt sources\n");
 		return;
 	}
 	xive_register_ipi_source(p->base_lsi, NPU2_N_DL_IRQS, p, &npu2_ipi_ops);
@@ -375,8 +387,7 @@ static void setup_devices(struct npu2 *npu)
 		return;
 	}
 
-	if (nvlink_detected)
-		setup_irqs(npu);
+	setup_irqs(npu);
 
 	if (nvlink_detected)
 		npu2_nvlink_init_npu(npu);
diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
index 905314cc..d32aaa53 100644
--- a/hw/npu2-opencapi.c
+++ b/hw/npu2-opencapi.c
@@ -48,11 +48,9 @@
 #include <npu2.h>
 #include <npu2-regs.h>
 #include <phys-map.h>
-#include <xive.h>
 #include <i2c.h>
 #include <nvram.h>
 
-#define NPU_IRQ_LEVELS		35
 #define NPU_IRQ_LEVELS_XSL	23
 #define MAX_PE_HANDLE		((1 << 15) - 1)
 #define TL_MAX_TEMPLATE		63
@@ -1464,7 +1462,7 @@ static int npu2_add_mmio_regs(struct phb *phb, struct pci_device *pd,
 	 * Pass the hw irq number for the translation fault irq
 	 * irq levels 23 -> 26 are for translation faults, 1 per brick
 	 */
-	irq = dev->npu->irq_base + NPU_IRQ_LEVELS_XSL;
+	irq = dev->npu->base_lsi + NPU_IRQ_LEVELS_XSL;
 	if (stacku == NPU2_STACK_STCK_2U)
 		irq += 2;
 	if (block == NPU2_BLOCK_OTL1)
@@ -1537,43 +1535,9 @@ static void mask_nvlink_fir(struct npu2 *p)
 			NPU2_MISC_IRQ_ENABLE1, NPU2_MISC_DA_LEN_8B, reg);
 }
 
-static int setup_irq(struct npu2 *p)
+static int enable_xsl_irq(struct npu2 *p)
 {
-	uint64_t reg, mmio_addr;
-	uint32_t base;
-
-	base = xive_alloc_ipi_irqs(p->chip_id, NPU_IRQ_LEVELS, 64);
-	if (base == XIVE_IRQ_ERROR) {
-		/**
-		 * @fwts-label OCAPIIRQAllocationFailed
-		 * @fwts-advice OpenCAPI IRQ setup failed. This is probably
-		 * a firmware bug. OpenCAPI functionality will be broken.
-		 */
-		prlog(PR_ERR, "OCAPI: Couldn't allocate interrupts for NPU\n");
-		return -1;
-	}
-	p->irq_base = base;
-
-	xive_register_ipi_source(base, NPU_IRQ_LEVELS, NULL, NULL);
-	mmio_addr = (uint64_t ) xive_get_trigger_port(base);
-	prlog(PR_DEBUG, "OCAPI: NPU base irq %d @%llx\n", base, mmio_addr);
-	reg = (mmio_addr & NPU2_MISC_IRQ_BASE_MASK) << 13;
-	npu2_scom_write(p->chip_id, p->xscom_base, NPU2_MISC_IRQ_BASE,
-			NPU2_MISC_DA_LEN_8B, reg);
-	/*
-	 * setup page size = 64k
-	 *
-	 * OS type is set to AIX: opal also runs with 2 pages per interrupt,
-	 * so to cover the max offset for 35 levels of interrupt, we need
-	 * bits 41 to 46, which is what the AIX setting does. There's no
-	 * other meaning for that AIX setting.
-	 */
-	reg = npu2_scom_read(p->chip_id, p->xscom_base, NPU2_MISC_CFG,
-			NPU2_MISC_DA_LEN_8B);
-	reg |= NPU2_MISC_CFG_IPI_PS;
-	reg &= ~NPU2_MISC_CFG_IPI_OS;
-	npu2_scom_write(p->chip_id, p->xscom_base, NPU2_MISC_CFG,
-			NPU2_MISC_DA_LEN_8B, reg);
+	uint64_t reg;
 
 	/* enable translation interrupts for all bricks */
 	reg = npu2_scom_read(p->chip_id, p->xscom_base, NPU2_MISC_IRQ_ENABLE2,
@@ -1708,7 +1672,6 @@ int npu2_opencapi_init_npu(struct npu2 *npu)
 {
 	struct npu2_dev *dev;
 	uint64_t reg[2];
-	int rc;
 
 	assert(platform.ocapi);
 	read_nvram_training_state();
@@ -1741,10 +1704,7 @@ int npu2_opencapi_init_npu(struct npu2 *npu)
 		address_translation_config(npu->chip_id, npu->xscom_base, dev->brick_index);
 	}
 
-	/* Procedure 13.1.3.10 - Interrupt Configuration */
-	rc = setup_irq(npu);
-	if (rc)
-		goto failed;
+	enable_xsl_irq(npu);
 
 	for (int i = 0; i < npu->total_devices; i++) {
 		dev = &npu->devices[i];
@@ -1754,8 +1714,6 @@ int npu2_opencapi_init_npu(struct npu2 *npu)
 	}
 
 	return 0;
-failed:
-	return -1;
 }
 
 static const struct phb_ops npu2_opencapi_ops = {
diff --git a/include/npu2.h b/include/npu2.h
index 86a449eb..6c73679f 100644
--- a/include/npu2.h
+++ b/include/npu2.h
@@ -170,7 +170,6 @@ struct npu2 {
 	uint64_t	mm_base;
 	uint64_t	mm_size;
 	uint32_t	base_lsi;
-	uint32_t	irq_base;
 	uint32_t	total_devices;
 	struct npu2_dev	*devices;
 	enum phys_map_type gpu_map_type;
-- 
2.19.1



More information about the Skiboot mailing list