[Skiboot] [PATCH 2/7] hw/npu2: Move npu2 irq setup code to common area

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


The NPU IRQ setup code is currently duplicated between NVLink and
OpenCAPI, yet it's almost identical. This patch moves the NVLink version of the
code to the common file. A later patch will make use of it for OpenCAPI.

Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
---
 hw/npu2-common.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/npu2.c        | 100 ----------------------------------------------
 2 files changed, 102 insertions(+), 100 deletions(-)

diff --git a/hw/npu2-common.c b/hw/npu2-common.c
index 3d0b6366..b0d55f5d 100644
--- a/hw/npu2-common.c
+++ b/hw/npu2-common.c
@@ -22,6 +22,12 @@
 #include <bitutils.h>
 #include <nvram.h>
 #include <i2c.h>
+#include <interrupts.h>
+#include <xive.h>
+
+#define NPU2_IRQ_BASE_SHIFT 13
+#define NPU2_N_DL_IRQS 23
+#define NPU2_N_DL_IRQS_ALIGN 64
 
 /*
  * We use the indirect method because it uses the same addresses as
@@ -97,6 +103,99 @@ void npu2_write_mask_4b(struct npu2 *p, uint64_t reg, uint32_t val, uint32_t mas
 			(uint64_t)new_val << 32);
 }
 
+static uint64_t npu2_ipi_attributes(struct irq_source *is __unused, uint32_t isn __unused)
+{
+	struct npu2 *p = is->data;
+	uint32_t idx = isn - p->base_lsi;
+
+	if (idx == 18)
+		/* TCE Interrupt - used to detect a frozen PE */
+		return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_RARE | IRQ_ATTR_TYPE_MSI;
+	else
+		return IRQ_ATTR_TARGET_LINUX;
+}
+
+static char *npu2_ipi_name(struct irq_source *is, uint32_t isn)
+{
+	struct npu2 *p = is->data;
+	uint32_t idx = isn - p->base_lsi;
+	const char *name;
+
+	switch (idx) {
+	case 0: name = "NDL 0 Stall Event (brick 0)"; break;
+	case 1: name = "NDL 0 No-Stall Event (brick 0)"; break;
+	case 2: name = "NDL 1 Stall Event (brick 1)"; break;
+	case 3: name = "NDL 1 No-Stall Event (brick 1)"; break;
+	case 4: name = "NDL 2 Stall Event (brick 2)"; break;
+	case 5: name = "NDL 2 No-Stall Event (brick 2)"; break;
+	case 6: name = "NDL 5 Stall Event (brick 3)"; break;
+	case 7: name = "NDL 5 No-Stall Event (brick 3)"; break;
+	case 8: name = "NDL 4 Stall Event (brick 4)"; break;
+	case 9: name = "NDL 4 No-Stall Event (brick 4)"; break;
+	case 10: name = "NDL 3 Stall Event (brick 5)"; break;
+	case 11: name = "NDL 3 No-Stall Event (brick 5)"; break;
+	case 12: name = "NTL 0 Event"; break;
+	case 13: name = "NTL 1 Event"; break;
+	case 14: name = "NTL 2 Event"; break;
+	case 15: name = "NTL 3 Event"; break;
+	case 16: name = "NTL 4 Event"; break;
+	case 17: name = "NTL 5 Event"; break;
+	case 18: name = "TCE Event"; break;
+	case 19: name = "ATS Event"; break;
+	case 20: name = "CQ Event"; break;
+	case 21: name = "MISC Event"; break;
+	case 22: name = "NMMU Local Xstop"; break;
+	default: name = "Unknown";
+	}
+	return strdup(name);
+}
+
+static void npu2_err_interrupt(struct irq_source *is, uint32_t isn)
+{
+	struct npu2 *p = is->data;
+	uint32_t idx = isn - p->base_lsi;
+
+	if (idx != 18) {
+		prerror("OPAL received unknown NPU2 interrupt %d\n", idx);
+		return;
+	}
+
+	opal_update_pending_evt(OPAL_EVENT_PCI_ERROR,
+				OPAL_EVENT_PCI_ERROR);
+}
+
+static const struct irq_source_ops npu2_ipi_ops = {
+	.interrupt	= npu2_err_interrupt,
+	.attributes	= npu2_ipi_attributes,
+	.name = npu2_ipi_name,
+};
+
+static void setup_irqs(struct npu2 *p)
+{
+	uint64_t reg, val;
+	void *tp;
+
+	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");
+		return;
+	}
+	xive_register_ipi_source(p->base_lsi, NPU2_N_DL_IRQS, p, &npu2_ipi_ops);
+
+	/* Set IPI configuration */
+	reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_CFG);
+	val = npu2_read(p, reg);
+	val = SETFIELD(NPU2_MISC_CFG_IPI_PS, val, NPU2_MISC_CFG_IPI_PS_64K);
+	val = SETFIELD(NPU2_MISC_CFG_IPI_OS, val, NPU2_MISC_CFG_IPI_OS_AIX);
+	npu2_write(p, reg, val);
+
+	/* Set IRQ base */
+	reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_IRQ_BASE);
+	tp = xive_get_trigger_port(p->base_lsi);
+	val = ((uint64_t)tp) << NPU2_IRQ_BASE_SHIFT;
+	npu2_write(p, reg, val);
+}
+
 static bool _i2c_presence_detect(struct npu2_dev *dev)
 {
 	uint8_t state, data;
@@ -276,6 +375,9 @@ static void setup_devices(struct npu2 *npu)
 		return;
 	}
 
+	if (nvlink_detected)
+		setup_irqs(npu);
+
 	if (nvlink_detected)
 		npu2_nvlink_init_npu(npu);
 	else if (ocapi_detected)
diff --git a/hw/npu2.c b/hw/npu2.c
index 4ecc9135..d532c4da 100644
--- a/hw/npu2.c
+++ b/hw/npu2.c
@@ -20,7 +20,6 @@
 #include <pci.h>
 #include <pci-slot.h>
 #include <pci-virt.h>
-#include <interrupts.h>
 #include <opal.h>
 #include <opal-api.h>
 #include <cpu.h>
@@ -35,14 +34,9 @@
 #include <chip.h>
 #include <phys-map.h>
 #include <nvram.h>
-#include <xive.h>
 #include <xscom-p9-regs.h>
 #include <phb4.h>
 
-#define NPU2_IRQ_BASE_SHIFT 13
-#define NPU2_N_DL_IRQS 23
-#define NPU2_N_DL_IRQS_ALIGN 64
-
 #define VENDOR_CAP_START    0x80
 #define VENDOR_CAP_END      0x90
 #define VENDOR_CAP_LEN      0x10
@@ -1922,99 +1916,6 @@ static void npu2_add_phb_properties(struct npu2 *p)
 			      hi32(mm_size), lo32(mm_size));
 }
 
-static uint64_t npu2_ipi_attributes(struct irq_source *is __unused, uint32_t isn __unused)
-{
-	struct npu2 *p = is->data;
-	uint32_t idx = isn - p->base_lsi;
-
-	if (idx == 18)
-		/* TCE Interrupt - used to detect a frozen PE */
-		return IRQ_ATTR_TARGET_OPAL | IRQ_ATTR_TARGET_RARE | IRQ_ATTR_TYPE_MSI;
-	else
-		return IRQ_ATTR_TARGET_LINUX;
-}
-
-static char *npu2_ipi_name(struct irq_source *is, uint32_t isn)
-{
-	struct npu2 *p = is->data;
-	uint32_t idx = isn - p->base_lsi;
-	const char *name;
-
-	switch (idx) {
-	case 0: name = "NDL 0 Stall Event (brick 0)"; break;
-	case 1: name = "NDL 0 No-Stall Event (brick 0)"; break;
-	case 2: name = "NDL 1 Stall Event (brick 1)"; break;
-	case 3: name = "NDL 1 No-Stall Event (brick 1)"; break;
-	case 4: name = "NDL 2 Stall Event (brick 2)"; break;
-	case 5: name = "NDL 2 No-Stall Event (brick 2)"; break;
-	case 6: name = "NDL 5 Stall Event (brick 3)"; break;
-	case 7: name = "NDL 5 No-Stall Event (brick 3)"; break;
-	case 8: name = "NDL 4 Stall Event (brick 4)"; break;
-	case 9: name = "NDL 4 No-Stall Event (brick 4)"; break;
-	case 10: name = "NDL 3 Stall Event (brick 5)"; break;
-	case 11: name = "NDL 3 No-Stall Event (brick 5)"; break;
-	case 12: name = "NTL 0 Event"; break;
-	case 13: name = "NTL 1 Event"; break;
-	case 14: name = "NTL 2 Event"; break;
-	case 15: name = "NTL 3 Event"; break;
-	case 16: name = "NTL 4 Event"; break;
-	case 17: name = "NTL 5 Event"; break;
-	case 18: name = "TCE Event"; break;
-	case 19: name = "ATS Event"; break;
-	case 20: name = "CQ Event"; break;
-	case 21: name = "MISC Event"; break;
-	case 22: name = "NMMU Local Xstop"; break;
-	default: name = "Unknown";
-	}
-	return strdup(name);
-}
-
-static void npu2_err_interrupt(struct irq_source *is, uint32_t isn)
-{
-	struct npu2 *p = is->data;
-	uint32_t idx = isn - p->base_lsi;
-
-	if (idx != 18) {
-		prerror("OPAL received unknown NPU2 interrupt %d\n", idx);
-		return;
-	}
-
-	opal_update_pending_evt(OPAL_EVENT_PCI_ERROR,
-				OPAL_EVENT_PCI_ERROR);
-}
-
-static const struct irq_source_ops npu2_ipi_ops = {
-	.interrupt	= npu2_err_interrupt,
-	.attributes	= npu2_ipi_attributes,
-	.name = npu2_ipi_name,
-};
-
-static void npu2_setup_irqs(struct npu2 *p)
-{
-	uint64_t reg, val;
-	void *tp;
-
-	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");
-		return;
-	}
-	xive_register_ipi_source(p->base_lsi, NPU2_N_DL_IRQS, p, &npu2_ipi_ops );
-
-	/* Set IPI configuration */
-	reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_CFG);
-	val = npu2_read(p, reg);
-	val = SETFIELD(NPU2_MISC_CFG_IPI_PS, val, NPU2_MISC_CFG_IPI_PS_64K);
-	val = SETFIELD(NPU2_MISC_CFG_IPI_OS, val, NPU2_MISC_CFG_IPI_OS_AIX);
-	npu2_write(p, reg, val);
-
-	/* Set IRQ base */
-	reg = NPU2_REG_OFFSET(NPU2_STACK_MISC, NPU2_BLOCK_MISC, NPU2_MISC_IRQ_BASE);
-	tp = xive_get_trigger_port(p->base_lsi);
-	val = ((uint64_t)tp) << NPU2_IRQ_BASE_SHIFT;
-	npu2_write(p, reg, val);
-}
-
 void npu2_nvlink_create_phb(struct npu2 *npu, struct dt_node *dn)
 {
 	struct pci_slot *slot;
@@ -2028,7 +1929,6 @@ void npu2_nvlink_create_phb(struct npu2 *npu, struct dt_node *dn)
 	list_head_init(&npu->phb_nvlink.devices);
 	list_head_init(&npu->phb_nvlink.virt_devices);
 
-	npu2_setup_irqs(npu);
 	npu2_populate_devices(npu, dn);
 	npu2_add_interrupt_map(npu, dn);
 	npu2_add_phb_properties(npu);
-- 
2.19.1



More information about the Skiboot mailing list