From patchwork Fri Aug 14 13:18:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 7014951 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id EEF93C05AC for ; Fri, 14 Aug 2015 13:21:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F2B75207DD for ; Fri, 14 Aug 2015 13:21:56 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0ACC42035E for ; Fri, 14 Aug 2015 13:21:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZQEtJ-0001cQ-7W; Fri, 14 Aug 2015 13:19:25 +0000 Received: from mail-wi0-x234.google.com ([2a00:1450:400c:c05::234]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZQEt9-0001WZ-0h for linux-arm-kernel@lists.infradead.org; Fri, 14 Aug 2015 13:19:15 +0000 Received: by wicja10 with SMTP id ja10so20430654wic.1 for ; Fri, 14 Aug 2015 06:18:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=z9Cb/7KMd1tMfyzw8zkX/XaLBtk4TvBKNZ1Q7y6UGkM=; b=q7ivB3i6aZJGdoJRhFDiWrDvuhtJTRCP3tss7PExYakEs1zQ5L8hAjWepD8LAE0qnS zMU43wVyPYLvtfMasUKjhRNlTx/gQEFcPX2iw9/VDVFTo29T1SOfPgYvxDkmZA3V67gI sm7AfJPdlmEQyS1LpMmTIKAkSLBpctRHpNSvpuxvd7w68/Am97uosBMI553TS6K5GOnE vg64EldlXddNsLRDMfMKsnm9Rbe+AU1ECJcdO5JrXE6FkJMWNwV1/54KQIvEt6yTgMPP SyIa3lp/BYxN5AWBZhN0yUe8KAPVvUnwCF3qES0pxnYuinstwF8Y8JIflZZnZ0xekjwi d3SA== X-Received: by 10.180.107.67 with SMTP id ha3mr7067673wib.42.1439558336018; Fri, 14 Aug 2015 06:18:56 -0700 (PDT) Received: from rric.localdomain (x5ce0c315.dyn.telefonica.de. [92.224.195.21]) by smtp.gmail.com with ESMTPSA id lg8sm3072041wic.12.2015.08.14.06.18.54 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 14 Aug 2015 06:18:55 -0700 (PDT) From: Robert Richter To: Marc Zygnier , Thomas Gleixner , Jason Cooper Subject: [PATCH v3 2/6] irqchip, gicv3: Add HW revision detection and configuration Date: Fri, 14 Aug 2015 15:18:36 +0200 Message-Id: <1439558320-5777-3-git-send-email-rric@kernel.org> X-Mailer: git-send-email 2.1.1 In-Reply-To: <1439558320-5777-1-git-send-email-rric@kernel.org> References: <1439558320-5777-1-git-send-email-rric@kernel.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150814_061915_220848_7B0AF0B1 X-CRM114-Status: GOOD ( 15.53 ) X-Spam-Score: -2.4 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Robert Richter , Tirumalesh Chalamarla , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Robert Richter Some GIC revisions require an individual configuration to esp. add workarounds for HW bugs. This patch implements generic code to parse the hw revision provided by an IIDR register value and runs specific code if hw matches. There are functions that read the IIDR registers for GICV3 and ITS (GICD_IIDR/GITS_IIDR) and then go through a list of init functions to be called for specific versions. A MIDR register value may also be used, this is especially useful for hw detection from a guest. The patch is needed to implement workarounds for HW errata in Cavium's ThunderX GICV3. v3: * use arm64 errata framework for midr check v2: * adding MIDR check Signed-off-by: Robert Richter --- drivers/irqchip/irq-gic-common.c | 13 +++++++++++++ drivers/irqchip/irq-gic-common.h | 10 ++++++++++ drivers/irqchip/irq-gic-v3-its.c | 15 +++++++++++++++ drivers/irqchip/irq-gic-v3.c | 14 ++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 9448e391cb71..f5e901a62ea5 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -21,6 +21,19 @@ #include "irq-gic-common.h" +void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap, + void *data) +{ + for (; cap->desc; cap++) { + if (cap->cpu_cap && !cpus_have_cap(cap->cpu_cap)) + continue; + if (cap->iidr != (cap->mask & iidr)) + continue; + cap->init(data); + pr_info("%s\n", cap->desc); + } +} + int gic_configure_irq(unsigned int irq, unsigned int type, void __iomem *base, void (*sync_access)(void)) { diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h index 35a9884778bd..6d019a238f3b 100644 --- a/drivers/irqchip/irq-gic-common.h +++ b/drivers/irqchip/irq-gic-common.h @@ -20,10 +20,20 @@ #include #include +struct gic_capabilities { + const char *desc; + void (*init)(void *data); + u32 iidr; + u32 mask; + u16 cpu_cap; +}; + int gic_configure_irq(unsigned int irq, unsigned int type, void __iomem *base, void (*sync_access)(void)); void gic_dist_config(void __iomem *base, int gic_irqs, void (*sync_access)(void)); void gic_cpu_config(void __iomem *base, void (*sync_access)(void)); +void gic_check_capabilities(u32 iidr, const struct gic_capabilities *cap, + void *data); #endif /* _IRQ_GIC_COMMON_H */ diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 466edf8a7477..105674037618 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -36,6 +36,7 @@ #include #include +#include "irq-gic-common.h" #include "irqchip.h" #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1 << 0) @@ -1391,6 +1392,18 @@ static int its_force_quiescent(void __iomem *base) } } +static const struct gic_capabilities its_errata[] = { + { + } +}; + +static void its_check_capabilities(struct its_node *its) +{ + u32 iidr = readl_relaxed(its->base + GITS_IIDR); + + gic_check_capabilities(iidr, its_errata, its); +} + static int its_probe(struct device_node *node, struct irq_domain *parent) { struct resource res; @@ -1449,6 +1462,8 @@ static int its_probe(struct device_node *node, struct irq_domain *parent) } its->cmd_write = its->cmd_base; + its_check_capabilities(its); + err = its_alloc_tables(its); if (err) goto out_free_cmd; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c52f7ba205b4..1a91902be0b1 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -766,6 +766,18 @@ static const struct irq_domain_ops gic_irq_domain_ops = { .free = gic_irq_domain_free, }; +static const struct gic_capabilities gicv3_errata[] = { + { + } +}; + +static void gicv3_check_capabilities(void) +{ + u32 iidr = readl_relaxed(gic_data.dist_base + GICD_IIDR); + + gic_check_capabilities(iidr, gicv3_errata, NULL); +} + static int __init gic_of_init(struct device_node *node, struct device_node *parent) { void __iomem *dist_base; @@ -825,6 +837,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare gic_data.nr_redist_regions = nr_redist_regions; gic_data.redist_stride = redist_stride; + gicv3_check_capabilities(); + /* * Find out how many interrupts are supported. * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI)