From patchwork Thu Dec 5 05:14:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Olovyannikov X-Patchwork-Id: 1204472 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=broadcom.com header.i=@broadcom.com header.b="BsnOQ9My"; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47T41F0SHdz9sP3 for ; Thu, 5 Dec 2019 16:25:21 +1100 (AEDT) Received: by phobos.denx.de (Postfix, from userid 109) id 59EA9816CE; Thu, 5 Dec 2019 06:24:48 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS, UPPERCASE_50_75, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from phobos.denx.de (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id B971F80928; Thu, 5 Dec 2019 06:15:08 +0100 (CET) Authentication-Results: mail.denx.de; dmarc=fail (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: mail.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: mail.denx.de; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=broadcom.com header.i=@broadcom.com header.b="BsnOQ9My"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3ACE881676; Thu, 5 Dec 2019 06:15:04 +0100 (CET) Received: from mail-wm1-f66.google.com (mail-wm1-f66.google.com [209.85.128.66]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A5D1981623 for ; Thu, 5 Dec 2019 06:14:58 +0100 (CET) Authentication-Results: mail.denx.de; dmarc=pass (p=quarantine dis=none) header.from=broadcom.com Authentication-Results: mail.denx.de; spf=pass smtp.mailfrom=vladimir.olovyannikov@broadcom.com Received: by mail-wm1-f66.google.com with SMTP id c20so729037wmb.0 for ; Wed, 04 Dec 2019 21:14:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=from:to:cc:subject:date:message-id; bh=UvzRSXZwV1yqahVtwA64q1m+7DkeFfy4TCEoYTIUlh0=; b=BsnOQ9My4SvUCeTA2bYXivBBnTI/eRPa8E+2lm9rWCbngQdZknsufRBd/AO44sZRi9 I2Xx5RBEZrnjCwQhXVz+slXFN5f0atNrGoxddftoeYV8BDdA3nL2J+gmli40PpTmpaFo wQvtff+GJl/+78Y/JJIT86hJn0MIbgLU4kIv4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=UvzRSXZwV1yqahVtwA64q1m+7DkeFfy4TCEoYTIUlh0=; b=levntvitr5Wq+aFbbaePpEWKNjTpbrx3ZY17MiTKbUbraK7Za1Q23oqrK+5Jq1K+nK L7Q17KzK8pxTqnQUMcKy9Zs7Uq8yZRFx06IPozMTmuBoqr6tTo9zETFC5I1ZLm6BcVyC S4ENt1aO7yP5tODKqH6BuVbH/BiSMBF8ivsSNaFB2jkxDDXwSWQepoIwrTNXeubTXHOC 9mZ9xLsjWAMtIY4qdA5ltOC1uTvsPQtd5b1pfCbjMTZSY+yZX0HZUJBdVtplSxMlOiaK JbLl/OlDMdZo0h7Uebnxkm5r4jZJ87h98CxfhtBkhkLzvfqWVxG3v9nw4oX99XOZFWpf FwKQ== X-Gm-Message-State: APjAAAX4VyFsXYoc6mXziWgEA3JsNf0zfJbxqQ7XI0nXYmGlc8Vqx4qc +Lpt8LYK76q/pF8l0Qi6poOZixU02YrObP/vaW2DcnMRFbNcv99Ey5YOmVhuihNagKN/wlYeM+3 OkBK56IlcH1w4/XFEC5bCdx/1r0bxJPBoimJpTmjpQgCEb3RHMS4+CJCHO+hVFaXsnoHS4xtEPB ZX8P2NVtDtIV4= X-Google-Smtp-Source: APXvYqynklEufZ+aUwNdfeEagj4c2ENSyoq7Vaf6s23liUAyVU4/hyQsojlOmu1U2ts3tmn2oGPw1g== X-Received: by 2002:a1c:6a05:: with SMTP id f5mr2916056wmc.2.1575522869445; Wed, 04 Dec 2019 21:14:29 -0800 (PST) Received: from LBRMN-LNXUB114.ric.broadcom.com ([192.19.228.250]) by smtp.gmail.com with ESMTPSA id j12sm84205wrt.55.2019.12.04.21.14.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Dec 2019 21:14:28 -0800 (PST) From: Vladimir Olovyannikov To: u-boot@lists.denx.de Subject: [PATCH 1/1] arch: arm: Program GIC LPI configuration table Date: Wed, 4 Dec 2019 21:14:02 -0800 Message-Id: <20191205051402.12284-1-vladimir.olovyannikov@broadcom.com> X-Mailer: git-send-email 2.17.1 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.26 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Albert Aribaud , Bharat Kumar Reddy Gooty Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.101.4 at mail.denx.de X-Virus-Status: Clean From: Bharat Kumar Reddy Gooty Programs the following: 1. Redistributor PROCBASER configuration table (which is common for all redistributors) 2. Redistributor pending table (PENDBASER), for all the available redistributors. Signed-off-by: Bharat Kumar Reddy Gooty Signed-off-by: Vladimir Olovyannikov --- arch/arm/Kconfig | 11 +++ arch/arm/include/asm/gic-v3.h | 134 ++++++++++++++++++++++++++++++++++ arch/arm/lib/Makefile | 3 + arch/arm/lib/gic-v3-its.c | 100 +++++++++++++++++++++++++ 4 files changed, 248 insertions(+) create mode 100644 arch/arm/include/asm/gic-v3.h create mode 100644 arch/arm/lib/gic-v3-its.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f96841c777..cf46aa867d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -61,6 +61,17 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE endif endif +config GIC_V3_ITS + bool "ARM GICV3 ITS" + default n + help + ARM GICV3 Interrupt translation service (ITS). + Basic support for programming locality specific peripheral + interrupts (LPI) configuration tables and enable LPI tables. + LPI configuration table can be used by u-boot or Linux. + ARM GICV3 has limitation, once the LPI table is enabled, LPI + configuration table can not be re-programmed, unless GICV3 reset. + config STATIC_RELA bool default y if ARM64 && !POSITION_INDEPENDENT diff --git a/arch/arm/include/asm/gic-v3.h b/arch/arm/include/asm/gic-v3.h new file mode 100644 index 0000000000..ac6c9e7013 --- /dev/null +++ b/arch/arm/include/asm/gic-v3.h @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 Broadcom. + */ + +#ifndef __GIC_V3_H__ +#define __GIC_V3_H__ + +#define GICR_CTLR_ENABLE_LPIS BIT(0) +#define GICR_CTLR_RWP BIT(3) + +#define GICR_TYPER_CPU_NUMBER(r) (((r) >> 8) & 0xffff) + +#define GICR_WAKER_PROCESSORSLEEP BIT(1) +#define GICR_WAKER_CHILDRENASLEEP BIT(2) + +#define GIC_BASER_CACHE_NCNB 0ULL +#define GIC_BASER_CACHE_SAMEASINNER 0ULL +#define GIC_BASER_CACHE_NC 1ULL +#define GIC_BASER_CACHE_RAWT 2ULL +#define GIC_BASER_CACHE_RAWB 3ULL +#define GIC_BASER_CACHE_WAWT 4ULL +#define GIC_BASER_CACHE_WAWB 5ULL +#define GIC_BASER_CACHE_RAWAWT 6ULL +#define GIC_BASER_CACHE_RAWAWB 7ULL +#define GIC_BASER_CACHE_MASK 7ULL +#define GIC_BASER_NONSHAREABLE 0ULL +#define GIC_BASER_INNERSHAREABLE 1ULL +#define GIC_BASER_OUTERSHAREABLE 2ULL +#define GIC_BASER_SHAREABILITY_MASK 3ULL + +#define GIC_BASER_CACHEABILITY(reg, inner_outer, type) \ + (GIC_BASER_CACHE_##type << reg##_##inner_outer##_CACHEABILITY_SHIFT) + +#define GIC_BASER_SHAREABILITY(reg, type) \ + (GIC_BASER_##type << reg##_SHAREABILITY_SHIFT) + +/* encode a size field of width @w containing @n - 1 units */ +#define GIC_ENCODE_SZ(n, w) (((unsigned long)(n) - 1) &\ + GENMASK_ULL(((w) - 1), 0)) + +#define GICR_PROPBASER_SHAREABILITY_SHIFT (10) +#define GICR_PROPBASER_INNER_CACHEABILITY_SHIFT (7) +#define GICR_PROPBASER_OUTER_CACHEABILITY_SHIFT (56) +#define GICR_PROPBASER_SHAREABILITY_MASK \ + GIC_BASER_SHAREABILITY(GICR_PROPBASER, SHAREABILITY_MASK) +#define GICR_PROPBASER_INNER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, MASK) +#define GICR_PROPBASER_OUTER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, OUTER, MASK) +#define GICR_PROPBASER_CACHEABILITY_MASK GICR_PROPBASER_INNER_CACHEABILITY_MASK + +#define GICR_PROPBASER_INNERSHAREABLE \ + GIC_BASER_SHAREABILITY(GICR_PROPBASER, INNERSHAREABLE) + +#define GICR_PROPBASER_NCNB \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, NCNB) +#define GICR_PROPBASER_NC \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, NC) +#define GICR_PROPBASER_RAWT \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RAWT) +#define GICR_PROPBASER_RAWB \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RAWB) +#define GICR_PROPBASER_WAWT \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WAWT) +#define GICR_PROPBASER_WAWB \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, WAWB) +#define GICR_PROPBASER_RAWAWT \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RAWAWT) +#define GICR_PROPBASER_RAWAWB \ + GIC_BASER_CACHEABILITY(GICR_PROPBASER, INNER, RAWAWB) + +#define GICR_PROPBASER_IDBITS_MASK (0x1f) +#define GICR_PROPBASER_ADDRESS(x) ((x) & GENMASK_ULL(51, 12)) +#define GICR_PENDBASER_ADDRESS(x) ((x) & GENMASK_ULL(51, 16)) + +#define GICR_PENDBASER_SHAREABILITY_SHIFT (10) +#define GICR_PENDBASER_INNER_CACHEABILITY_SHIFT (7) +#define GICR_PENDBASER_OUTER_CACHEABILITY_SHIFT (56) +#define GICR_PENDBASER_SHAREABILITY_MASK \ + GIC_BASER_SHAREABILITY(GICR_PENDBASER, SHAREABILITY_MASK) +#define GICR_PENDBASER_INNER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, MASK) +#define GICR_PENDBASER_OUTER_CACHEABILITY_MASK \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, OUTER, MASK) +#define GICR_PENDBASER_CACHEABILITY_MASK \ + GICR_PENDBASER_INNER_CACHEABILITY_MASK + +#define GICR_PENDBASER_INNERSHAREABLE \ + GIC_BASER_SHAREABILITY(GICR_PENDBASER, INNERSHAREABLE) + +#define GICR_PENDBASER_NCNB \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, NCNB) +#define GICR_PENDBASER_NC \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, NC) +#define GICR_PENDBASER_RAWT \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RAWT) +#define GICR_PENDBASER_RAWB \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RAWB) +#define GICR_PENDBASER_WAWT \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WAWT) +#define GICR_PENDBASER_WAWB \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, WAWB) +#define GICR_PENDBASER_RAWAWT \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RAWAWT) +#define GICR_PENDBASER_RAWAWB \ + GIC_BASER_CACHEABILITY(GICR_PENDBASER, INNER, RAWAWB) + +#define GICR_PENDBASER_PTZ BIT_ULL(62) + +#define ITS_MAX_LPI_NRBITS 16 /* 64K LPIs */ + +#define GICD_TYPER_ID_BITS(typer) ((((typer) >> 19) & 0x1f) + 1) +#define GICD_TYPER_NUM_LPIS(typer) ((((typer) >> 11) & 0x1f) + 1) +#define GICD_TYPER_IRQS(typer) ((((typer) & 0x1f) + 1) * 32) + +/* Message based interrupts support */ +#define GICD_TYPER_MBIS BIT(16) +/* LPI support */ +#define GICD_TYPER_LPIS BIT(17) +#define GICD_TYPER_RSS BIT(26) + +#define GIC_REDISTRIBUTOR_OFFSET 0x20000 + +#ifdef CONFIG_GIC_V3_ITS +int gic_lpi_tables_init(u64 base, u32 max_redist); +#else +int gic_lpi_tables_init(u64 base, u32 max_redist) +{ + return 0; +} +#endif /* CONFIG_GIC_V3_ITS */ + +#endif /* __GIC_V3_H__ */ diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 9de9a9acee..942ed1c73a 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -52,6 +52,9 @@ obj-$(CONFIG_FSL_LAYERSCAPE) += ccn504.o ifneq ($(CONFIG_GICV2)$(CONFIG_GICV3),) obj-y += gic_64.o endif +ifdef CONFIG_GIC_V3_ITS +obj-y += gic-v3-its.o +endif obj-y += interrupts_64.o else obj-y += interrupts.o diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c new file mode 100644 index 0000000000..e19ab01621 --- /dev/null +++ b/arch/arm/lib/gic-v3-its.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Broadcom. + */ +#include +#include +#include +#include + +static u32 lpi_id_bits; + +#define LPI_NRBITS lpi_id_bits +#define LPI_PROPBASE_SZ ALIGN(BIT(LPI_NRBITS), SZ_64K) +#define LPI_PENDBASE_SZ ALIGN(BIT(LPI_NRBITS) / 8, SZ_64K) + +/* + * Program the GIC LPI configuration tables for all + * the re-distributors and enable the LPI table + * base: Configuration table address + * num_redist: number of redistributors + */ +int gic_lpi_tables_init(u64 base, u32 num_redist) +{ + u32 gicd_typer; + u64 val; + u64 tmp; + int i; + u64 redist_lpi_base; + u64 pend_base = GICR_BASE + GICR_PENDBASER; + + gicd_typer = readl(GICD_BASE + GICD_TYPER); + + /* GIC support for Locality specific peripheral interrupts (LPI's) */ + if (!(gicd_typer & GICD_TYPER_LPIS)) { + pr_err("GIC implementation does not support LPI's\n"); + return -EINVAL; + } + + /* + * Check for LPI is disabled for all the redistributors. + * Once the LPI table is enabled, can not program the + * LPI configuration tables again, unless the GIC is reset. + */ + for (i = 0; i < num_redist; i++) { + u32 offset = i * GIC_REDISTRIBUTOR_OFFSET; + + if ((readl((uintptr_t)(GICR_BASE + offset))) & + GICR_CTLR_ENABLE_LPIS) { + pr_err("Re-Distributor %d LPI is already enabled\n", + i); + return -EINVAL; + } + } + + /* lpi_id_bits to get LPI_PENDBASE_SZ and LPi_PROPBASE_SZ */ + lpi_id_bits = min_t(u32, GICD_TYPER_ID_BITS(gicd_typer), + ITS_MAX_LPI_NRBITS); + + /* Set PropBase */ + val = (base | + GICR_PROPBASER_INNERSHAREABLE | + GICR_PROPBASER_RAWAWB | + ((LPI_NRBITS - 1) & GICR_PROPBASER_IDBITS_MASK)); + + writeq(val, (GICR_BASE + GICR_PROPBASER)); + tmp = readl(GICR_BASE + GICR_PROPBASER); + if ((tmp ^ val) & GICR_PROPBASER_SHAREABILITY_MASK) { + if (!(tmp & GICR_PROPBASER_SHAREABILITY_MASK)) { + val &= ~(GICR_PROPBASER_SHAREABILITY_MASK | + GICR_PROPBASER_CACHEABILITY_MASK); + val |= GICR_PROPBASER_NC; + writeq(val, (GICR_BASE + GICR_PROPBASER)); + } + } + + redist_lpi_base = base + LPI_PROPBASE_SZ; + + for (i = 0; i < num_redist; i++) { + u32 offset = i * GIC_REDISTRIBUTOR_OFFSET; + + val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) | + GICR_PENDBASER_INNERSHAREABLE | + GICR_PENDBASER_RAWAWB); + + writeq(val, (uintptr_t)(pend_base + offset)); + tmp = readq((uintptr_t)(pend_base + offset)); + if (!(tmp & GICR_PENDBASER_SHAREABILITY_MASK)) { + val &= ~(GICR_PENDBASER_SHAREABILITY_MASK | + GICR_PENDBASER_CACHEABILITY_MASK); + val |= GICR_PENDBASER_NC; + writeq(val, (uintptr_t)(pend_base + offset)); + } + + /* Enable LPI for the redistributor */ + writel(GICR_CTLR_ENABLE_LPIS, (uintptr_t)(GICR_BASE + offset)); + } + + return 0; +} +