From patchwork Tue Oct 4 11:27:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Dybcio X-Patchwork-Id: 12998167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3291C433FE for ; Tue, 4 Oct 2022 11:28:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=sPB7/gFjrybSqINSetTJxVlR0i+r50mEqqaBZWvvgko=; b=PFYq2IOva/Il2m 2eW+k1SZuKTXlw9tC80b8ojxxFHitx3F2b6VS+WOrlOWp0iAhUv64muIqz9XOQihP1a2+WjzUyWkK HccjSs0NlsxTIZEQVHDtTmOZd9EjrORhVG9ewPcOSr6DtF3Hen7/yIkLMyAhSzErpH0OZGi31tJvh jaa8VKJLcyAr1UsXm7axAoVzEl2EKqMdI5lfr7M4R+751u7QFxVNqtkE7DiBVAUGt973cMb75rOLJ sB9ddvCNINpzcLB1t9aLaDLu3KcsWtvJy5VrvEfeTh1mpFtoMcEMHjNU18UtFu5U7VdjVtkCc9Ocd kLw01PhXGYN7aJ+1uPsA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1ofg5b-009ViO-KR; Tue, 04 Oct 2022 11:27:55 +0000 Received: from relay02.th.seeweb.it ([2001:4b7a:2000:18::163]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1ofg5Q-009Vfk-98 for linux-arm-kernel@lists.infradead.org; Tue, 04 Oct 2022 11:27:46 +0000 Received: from localhost.localdomain (unknown [IPv6:2a00:f41:188c:1c74:dc7c:ae37:b483:8263]) (using TLSv1.3 with cipher TLS_CHACHA20_POLY1305_SHA256 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA512) (No client certificate requested) by m-r1.th.seeweb.it (Postfix) with ESMTPSA id CC8291FC01; Tue, 4 Oct 2022 13:27:34 +0200 (CEST) From: Konrad Dybcio To: asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org Cc: towinchenmi@gmail.com, Konrad Dybcio , Hector Martin , Sven Peter , Alyssa Rosenzweig , Thomas Gleixner , Marc Zyngier , Rob Herring , Krzysztof Kozlowski , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH v3 2/2] irqchip/apple-aic: Add support for A7-A11 SoCs Date: Tue, 4 Oct 2022 13:27:24 +0200 Message-Id: <20221004112724.31621-2-konrad.dybcio@somainline.org> X-Mailer: git-send-email 2.32.0 (Apple Git-132) In-Reply-To: <20221004112724.31621-1-konrad.dybcio@somainline.org> References: <20221004112724.31621-1-konrad.dybcio@somainline.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221004_042744_686052_0AE810B1 X-CRM114-Status: GOOD ( 23.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add support for A7-A11 SoCs by if-ing out some features only present on: * A11 & newer (implementation-defined IPI & UNCORE registers) * A11[1] & newer (fast IPI support). UNCORE/UNCORE2 and IPI registers conveniently both first appeared on A11, so introduce just one check for that. Knowing whether the SoC supports the latter is necessary, as they are written to, even if fast IPI is disabled. This in turn causes a crash on older platforms, as the implemention-defined registers either do something else or are not supposed to be touched - definitely not a NOP though. [1] A11 is supposed to use this feature, but it currently doesn't work for reasons unknown and hence remains disabled. It can easily be enabled on A11 only, as there is a SoC-specific compatible in the DT with a fallback to apple,aic. That said, it is not yet necessary, especially with only one core up, and it has worked a-ok so far. Signed-off-by: Konrad Dybcio --- Changes since v2: - has_uncore_regs now also reflects whether the soc has IPI regs (A11+) - apple,aic is now the default, lowest-common-denominator fallback compatible (Sven checked it still works on M1) - fixed an error where "Fast IPI fired. Acking." would be unreachable.. oops.. - what used to be apple,aic (yes UNCORE/IPI regs no fast IPI) is now used for the A11 compatible drivers/irqchip/irq-apple-aic.c | 60 ++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c index 1c2813ad8bbe..239115c64340 100644 --- a/drivers/irqchip/irq-apple-aic.c +++ b/drivers/irqchip/irq-apple-aic.c @@ -230,6 +230,9 @@ static DEFINE_STATIC_KEY_TRUE(use_fast_ipi); +/* True if UNCORE/UNCORE2 and Sn_... IPI registers are present (A11+) */ +static DEFINE_STATIC_KEY_TRUE(has_uncore_ipi_regs); + struct aic_info { int version; @@ -246,6 +249,7 @@ struct aic_info { /* Features */ bool fast_ipi; + bool uncore_ipi_regs; }; static const struct aic_info aic1_info = { @@ -261,18 +265,33 @@ static const struct aic_info aic1_fipi_info = { .event = AIC_EVENT, .target_cpu = AIC_TARGET_CPU, + .uncore_ipi_regs = true, .fast_ipi = true, }; +static const struct aic_info aic1_nofipi_info = { + .version = 1, + + .event = AIC_EVENT, + .target_cpu = AIC_TARGET_CPU, + + .uncore_ipi_regs = true, +}; + static const struct aic_info aic2_info = { .version = 2, .irq_cfg = AIC2_IRQ_CFG, + .uncore_ipi_regs = true, .fast_ipi = true, }; static const struct of_device_id aic_info_match[] = { + { + .compatible = "apple,t8015-aic", + .data = &aic1_nofipi_info, + }, { .compatible = "apple,t8103-aic", .data = &aic1_fipi_info, @@ -524,12 +543,14 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs) * we check for everything here, even things we don't support yet. */ - if (read_sysreg_s(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING) { - if (static_branch_likely(&use_fast_ipi)) { - aic_handle_ipi(regs); - } else { - pr_err_ratelimited("Fast IPI fired. Acking.\n"); - write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1); + if (static_branch_likely(&has_uncore_ipi_regs)) { + if (read_sysreg_s(SYS_IMP_APL_IPI_SR_EL1) & IPI_SR_PENDING) { + if (static_branch_likely(&use_fast_ipi)) { + aic_handle_ipi(regs); + } else { + pr_err_ratelimited("Fast IPI fired. Acking.\n"); + write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1); + } } } @@ -566,12 +587,14 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs) AIC_FIQ_HWIRQ(irq)); } - if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ && - (read_sysreg_s(SYS_IMP_APL_UPMSR_EL1) & UPMSR_IACT)) { - /* Same story with uncore PMCs */ - pr_err_ratelimited("Uncore PMC FIQ fired. Masking.\n"); - sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE, - FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF)); + if (static_branch_likely(&has_uncore_ipi_regs)) { + if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == + UPMCR0_IMODE_FIQ && (read_sysreg_s(SYS_IMP_APL_UPMSR_EL1) & UPMSR_IACT)) { + /* Same story with uncore PMCs */ + pr_err_ratelimited("Uncore PMC FIQ fired. Masking.\n"); + sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE, + FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF)); + } } } @@ -944,7 +967,8 @@ static int aic_init_cpu(unsigned int cpu) /* Mask all hard-wired per-CPU IRQ/FIQ sources */ /* Pending Fast IPI FIQs */ - write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1); + if (static_branch_likely(&use_fast_ipi)) + write_sysreg_s(IPI_SR_PENDING, SYS_IMP_APL_IPI_SR_EL1); /* Timer FIQs */ sysreg_clear_set(cntp_ctl_el0, 0, ARCH_TIMER_CTRL_IT_MASK); @@ -965,8 +989,9 @@ static int aic_init_cpu(unsigned int cpu) FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF)); /* Uncore PMC FIQ */ - sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE, - FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF)); + if (static_branch_likely(&has_uncore_ipi_regs)) + sysreg_clear_set_s(SYS_IMP_APL_UPMCR0_EL1, UPMCR0_IMODE, + FIELD_PREP(UPMCR0_IMODE, UPMCR0_IMODE_OFF)); /* Commit all of the above */ isb(); @@ -1125,6 +1150,11 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p else static_branch_disable(&use_fast_ipi); + if (irqc->info.uncore_ipi_regs) + static_branch_enable(&has_uncore_ipi_regs); + else + static_branch_disable(&has_uncore_ipi_regs); + irqc->info.die_stride = off - start_off; irqc->hw_domain = irq_domain_create_tree(of_node_to_fwnode(node),