All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
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	[thread overview]
Message-ID: <20191205051402.12284-1-vladimir.olovyannikov@broadcom.com> (raw)

From: Bharat Kumar Reddy Gooty <bharat.gooty@broadcom.com>

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 <bharat.gooty@broadcom.com>
Signed-off-by: Vladimir Olovyannikov <vladimir.olovyannikov@broadcom.com>
---
 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 <common.h>
+#include <asm/gic.h>
+#include <asm/gic-v3.h>
+#include <asm/io.h>
+
+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;
+}
+
-- 
2.17.1

             reply	other threads:[~2019-12-05  5:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-05  5:14 Vladimir Olovyannikov [this message]
2019-12-06 19:02 ` [PATCH 1/1] arch: arm: Program GIC LPI configuration table Tom Rini
2019-12-06 22:18   ` Vladimir Olovyannikov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191205051402.12284-1-vladimir.olovyannikov@broadcom.com \
    --to=vladimir.olovyannikov@broadcom.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.