From patchwork Wed Dec 12 06:58:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Donnellan X-Patchwork-Id: 1011604 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43F7745kHjz9s5c for ; Wed, 12 Dec 2018 18:02:56 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=au1.ibm.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43F7743WgyzDqvL for ; Wed, 12 Dec 2018 18:02:56 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=au1.ibm.com X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=au1.ibm.com (client-ip=148.163.156.1; helo=mx0a-001b2d01.pphosted.com; envelope-from=andrew.donnellan@au1.ibm.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=au1.ibm.com Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43F73F0bpXzDqnv for ; Wed, 12 Dec 2018 17:59:36 +1100 (AEDT) Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id wBC6wSOP022872 for ; Wed, 12 Dec 2018 01:59:35 -0500 Received: from e06smtp07.uk.ibm.com (e06smtp07.uk.ibm.com [195.75.94.103]) by mx0a-001b2d01.pphosted.com with ESMTP id 2pawgng3ac-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 12 Dec 2018 01:59:34 -0500 Received: from localhost by e06smtp07.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 12 Dec 2018 06:59:32 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (9.149.109.196) by e06smtp07.uk.ibm.com (192.168.101.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Wed, 12 Dec 2018 06:59:29 -0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id wBC6xSTn1114406 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 12 Dec 2018 06:59:28 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 67BABAE053; Wed, 12 Dec 2018 06:59:28 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C2166AE04D; Wed, 12 Dec 2018 06:59:27 +0000 (GMT) Received: from ozlabs.au.ibm.com (unknown [9.192.253.14]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 12 Dec 2018 06:59:27 +0000 (GMT) Received: from intelligence.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114]) (using TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.au.ibm.com (Postfix) with ESMTPSA id BD6FBA0389; Wed, 12 Dec 2018 17:59:24 +1100 (AEDT) From: Andrew Donnellan To: skiboot@lists.ozlabs.org Date: Wed, 12 Dec 2018 17:58:50 +1100 X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: X-TM-AS-GCONF: 00 x-cbid: 18121206-0028-0000-0000-000003294E37 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18121206-0029-0000-0000-000023E576C6 Message-Id: MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-12-12_01:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=999 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1812120061 Subject: [Skiboot] [PATCH 07/13] hw/npu2: Make IRQ setup code common X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, arbab@linux.ibm.com, fbarrat@linux.vnet.ibm.com Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" From: Frederic Barrat The NPU IRQ setup code is currently duplicated between NVLink and OpenCAPI. Apart from the NPU2_MISC_IRQ_ENABLE2 register, the setup of IRQs is basically identical between NVLink and OpenCAPI. Move the NVLink IRQ setup code into the common path and get rid of all the OpenCAPI IRQ setup apart from the enable mask. Signed-off-by: Frederic Barrat Signed-off-by: Andrew Donnellan --- Might need some testing --- hw/npu2-common.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++- hw/npu2-opencapi.c | 50 +-------------------- hw/npu2.c | 100 +----------------------------------------- include/npu2.h | 1 +- 4 files changed, 116 insertions(+), 147 deletions(-) diff --git a/hw/npu2-common.c b/hw/npu2-common.c index 6cbae9bffaf9..8edf761cf56b 100644 --- a/hw/npu2-common.c +++ b/hw/npu2-common.c @@ -24,6 +24,12 @@ #include #include #include +#include +#include + +#define NPU2_IRQ_BASE_SHIFT 13 +#define NPU2_N_DL_IRQS 35 +#define NPU2_N_DL_IRQS_ALIGN 64 /* * We use the indirect method because it uses the same addresses as @@ -244,6 +250,111 @@ static void assign_bars(struct npu2 *npu) npu->mm_size = last_bar.base + last_bar.size - npu->mm_base; } +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; + 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); +} + +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\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; @@ -421,6 +532,7 @@ static void setup_devices(struct npu2 *npu) } assign_bars(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 cc7c403351ce..dd40b24009f3 100644 --- a/hw/npu2-opencapi.c +++ b/hw/npu2-opencapi.c @@ -48,11 +48,9 @@ #include #include #include -#include #include #include -#define NPU_IRQ_LEVELS 35 #define NPU_IRQ_LEVELS_XSL 23 #define MAX_PE_HANDLE ((1 << 15) - 1) #define TL_MAX_TEMPLATE 63 @@ -1383,7 +1381,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) @@ -1456,43 +1454,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, @@ -1619,7 +1583,6 @@ static void read_nvram_training_state(void) int npu2_opencapi_init_npu(struct npu2 *npu) { struct npu2_dev *dev; - int rc; assert(platform.ocapi); read_nvram_training_state(); @@ -1645,10 +1608,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]; @@ -1658,8 +1618,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/hw/npu2.c b/hw/npu2.c index 9e2c7d5fdda4..8a4611424609 100644 --- a/hw/npu2.c +++ b/hw/npu2.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -36,14 +35,9 @@ #include #include #include -#include #include #include -#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 @@ -1780,99 +1774,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; @@ -1887,7 +1788,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_configure_devices(npu); npu2_add_interrupt_map(npu); npu2_add_phb_properties(npu); diff --git a/include/npu2.h b/include/npu2.h index 64be9f4eb9dd..9eb436db524a 100644 --- a/include/npu2.h +++ b/include/npu2.h @@ -155,7 +155,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;