summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Barrat <fbarrat@linux.ibm.com>2019-04-05 16:32:59 +0200
committerStewart Smith <stewart@linux.ibm.com>2019-04-09 10:50:55 +1000
commitd3af5072cb55c5586e7c393596940346c36488c3 (patch)
treeca97a874a168fad19e2b8ae5b95d908abe3d0fa5
parentb3bc840c1d85f49cfec27d1d612460d12c2360a8 (diff)
downloadtalos-skiboot-d3af5072cb55c5586e7c393596940346c36488c3.tar.gz
talos-skiboot-d3af5072cb55c5586e7c393596940346c36488c3.zip
hw/npu2: Move npu2 irq setup code to common area
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@linux.ibm.com> Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
-rw-r--r--hw/npu2-common.c102
-rw-r--r--hw/npu2.c100
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;
@@ -277,6 +376,9 @@ static void setup_devices(struct npu2 *npu)
}
if (nvlink_detected)
+ setup_irqs(npu);
+
+ if (nvlink_detected)
npu2_nvlink_init_npu(npu);
else if (ocapi_detected)
npu2_opencapi_init_npu(npu);
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);
OpenPOWER on IntegriCloud