All of lore.kernel.org
 help / color / mirror / Atom feed
From: Patrick Rudolph <patrick.rudolph@9elements.com>
To: u-boot@lists.denx.de,
	Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>,
	Tom Rini <trini@konsulko.com>,
	Matthias Brugger <mbrugger@suse.com>,
	Peter Robinson <pbrobinson@gmail.com>
Cc: Patrick Rudolph <patrick.rudolph@9elements.com>
Subject: [PATCH v4 32/35] arm: mach-bcm283x: Add ARMV8_MULTIENTRY support
Date: Wed, 18 Sep 2024 17:20:36 +0200	[thread overview]
Message-ID: <20240918152136.3395170-33-patrick.rudolph@9elements.com> (raw)
In-Reply-To: <20240918152136.3395170-1-patrick.rudolph@9elements.com>

When ACPI is enabled over FDT the APs cannot be brought out of reset
by the OS using the "FDT spin-table" mechanism, as no FDT is provided
to the OS. The APs must be released out of reset in u-boot and then
brought up in an ACPI compliant fashion.

When ARMV8_MULTIENTRY is specified, the APs are released from reset
and will enter U-Boot after it has been relocated as well.

By default ARMV8_MULTIENTRY is not selected, keeping existing behaviour.

TEST: All APs enter U-Boot when run on qemu-system-aarch64 and on
      real hardware.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Cc: Matthias Brugger <mbrugger@suse.com>
Cc: Peter Robinson <pbrobinson@gmail.com>
Cc: Tom Rini <trini@konsulko.com>
---
Changelog v2:
- Drop CPU code from board
- Add CPU driver to release APs from reset
Changelog v4:
- Use the generic armv8 CPU driver
- Probe all CPUs
- Release secondary CPUs in the probe function
- Use of_to_plat() to parse DT
- Drop udelay()
- Select the GICv2 driver
---
 arch/arm/Kconfig              |   1 +
 arch/arm/mach-bcm283x/Kconfig |   7 +-
 arch/arm/mach-bcm283x/init.c  |  10 ++
 drivers/cpu/Makefile          |   2 +-
 drivers/cpu/bcm283x_cpu.c     | 218 ++++++++++++++++++++++++++++++++++
 5 files changed, 236 insertions(+), 2 deletions(-)
 create mode 100644 drivers/cpu/bcm283x_cpu.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e85a7131d3..72702cd99c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -651,6 +651,7 @@ config ARCH_ORION5X
 
 config ARCH_BCM283X
 	bool "Broadcom BCM283X family"
+	select CPU
 	select DM
 	select DM_GPIO
 	select DM_SERIAL
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index b3287ce8bc..fad900d965 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -12,6 +12,7 @@ config BCM2836
 config BCM2837
 	bool "Broadcom BCM2837 SoC support"
 	depends on ARCH_BCM283X
+	select ARCH_EARLY_INIT_R
 
 config BCM2837_32B
 	bool "Broadcom BCM2837 SoC 32-bit support"
@@ -24,11 +25,14 @@ config BCM2837_64B
 	bool "Broadcom BCM2837 SoC 64-bit support"
 	depends on ARCH_BCM283X
 	select BCM2837
+	select DRIVER_GICV2
 	select ARM64
+	select CPU_ARMV8
 
 config BCM2711
 	bool "Broadcom BCM2711 SoC support"
 	depends on ARCH_BCM283X
+	select ARCH_EARLY_INIT_R
 
 config BCM2711_32B
 	bool "Broadcom BCM2711 SoC 32-bit support"
@@ -42,11 +46,12 @@ config BCM2711_64B
 	bool "Broadcom BCM2711 SoC 64-bit support"
 	depends on ARCH_BCM283X
 	select BCM2711
+	select DRIVER_GICV2
 	select ARM64
+	select CPU_ARMV8
 
 menu "Broadcom BCM283X family"
 	depends on ARCH_BCM283X
-
 choice
 	prompt "Broadcom BCM283X board select"
 	optional
diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c
index 7a1de22e0a..c59e557432 100644
--- a/arch/arm/mach-bcm283x/init.c
+++ b/arch/arm/mach-bcm283x/init.c
@@ -9,6 +9,7 @@
 #include <cpu_func.h>
 #include <init.h>
 #include <dm/device.h>
+#include <dm/uclass.h>
 #include <fdt_support.h>
 #include <asm/global_data.h>
 
@@ -199,6 +200,15 @@ int mach_cpu_init(void)
 					       "brcm,bcm2712-pm");
 	if (offset > soc)
 		rpi_wdog_base = fdt_get_base_address(gd->fdt_blob, offset);
+	return 0;
+}
+
+int arch_early_init_r(void)
+{
+	/* The older RPis do not have a CPU driver yet,
+	 * thus do not check for errors here...
+	 */
+	uclass_probe_all(UCLASS_CPU);
 
 	return 0;
 }
diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile
index 773395693a..eaf494706e 100644
--- a/drivers/cpu/Makefile
+++ b/drivers/cpu/Makefile
@@ -6,7 +6,7 @@
 
 obj-$(CONFIG_CPU) += cpu-uclass.o
 
-
+obj-$(CONFIG_ARCH_BCM283X) += bcm283x_cpu.o
 obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o
 obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o
 obj-$(CONFIG_ARCH_AT91) += at91_cpu.o
diff --git a/drivers/cpu/bcm283x_cpu.c b/drivers/cpu/bcm283x_cpu.c
new file mode 100644
index 0000000000..5ed75b3754
--- /dev/null
+++ b/drivers/cpu/bcm283x_cpu.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2024 9elements GmbH
+ */
+
+#include <acpi/acpigen.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/global_data.h>
+#include <asm/system.h>
+#include <asm/armv8/cpu.h>
+#include <asm-generic/sections.h>
+#include <cpu.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include "armv8_cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct bcm_plat {
+	u64 release_addr;
+};
+
+static int cpu_bcm_get_desc(const struct udevice *dev, char *buf, int size)
+{
+	struct cpu_plat *plat = dev_get_parent_plat(dev);
+	const char *name;
+	int ret;
+
+	if (size < 32)
+		return -ENOSPC;
+
+	if (device_is_compatible(dev, "arm,cortex-a53"))
+		name = "A53";
+	else if (device_is_compatible(dev, "arm,cortex-a72"))
+		name = "A72";
+	else
+		name = "?";
+
+	ret = snprintf(buf, size, "Broadcom Cortex-%s at %u MHz\n",
+		       name, plat->timebase_freq);
+
+	return 0;
+}
+
+static int cpu_bcm_get_info(const struct udevice *dev, struct cpu_info *info)
+{
+	struct cpu_plat *plat = dev_get_parent_plat(dev);
+
+	info->cpu_freq = plat->timebase_freq * 1000;
+	info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
+
+	return 0;
+}
+
+static int cpu_bcm_get_count(const struct udevice *dev)
+{
+	return uclass_id_count(UCLASS_CPU);
+}
+
+static int cpu_bcm_get_vendor(const struct udevice *dev,  char *buf, int size)
+{
+	snprintf(buf, size, "Broadcom");
+
+	return 0;
+}
+
+static int cpu_bcm_is_current(struct udevice *dev)
+{
+#ifdef CONFIG_ARM64
+	struct cpu_plat *plat = dev_get_parent_plat(dev);
+
+	if (plat->cpu_id == (read_mpidr() & 0xffff))
+		return 1;
+#endif
+
+	return 0;
+}
+
+/**
+ * bcm_cpu_on - Releases the secondary CPU from it's spintable
+ *
+ * Write the CPU's spintable mailbox and let the CPU enter U-Boot.
+ *
+ * @dev: Device to start
+ * @return: zero on success or error code on failure.
+ */
+static int bcm_cpu_on(struct udevice *dev)
+{
+	struct bcm_plat *plat = dev_get_plat(dev);
+	ulong *start_address;
+
+	if (!plat || plat->release_addr == ~0ULL)
+		return -ENODATA;
+
+	start_address = map_physmem(plat->release_addr, sizeof(uintptr_t), MAP_NOCACHE);
+
+	/* Point secondary CPU to U-Boot entry */
+	*start_address = (uintptr_t)_start;
+
+	/* Make sure the other CPUs see the written start address */
+	if (!CONFIG_IS_ENABLED(SYS_DCACHE_OFF))
+		flush_dcache_all();
+
+	/* Send an event to wake up the secondary CPU. */
+	asm("dsb	ishst\n"
+	    "sev");
+
+	unmap_physmem(start_address, MAP_NOCACHE);
+
+	return 0;
+}
+
+static const struct cpu_ops cpu_bcm_ops = {
+	.get_desc	= cpu_bcm_get_desc,
+	.get_info	= cpu_bcm_get_info,
+	.get_count	= cpu_bcm_get_count,
+	.get_vendor	= cpu_bcm_get_vendor,
+	.is_current	= cpu_bcm_is_current,
+};
+
+static const struct udevice_id cpu_bcm_ids[] = {
+	{ .compatible = "arm,cortex-a53" },	/* RPi 3 */
+	{ .compatible = "arm,cortex-a72" },	/* RPi 4 */
+	{ }
+};
+
+static int bcm_cpu_bind(struct udevice *dev)
+{
+	struct cpu_plat *plat = dev_get_parent_plat(dev);
+
+	plat->cpu_id = dev_read_addr(dev);
+
+	return 0;
+}
+
+/**
+ * bcm_cpu_of_to_plat - Gather spin-table release address
+ *
+ * Read the spin-table release address to allow all seconary CPUs to enter
+ * U-Boot when necessary.
+ *
+ * @dev: Device to start
+ */
+static int bcm_cpu_of_to_plat(struct udevice *dev)
+{
+	struct bcm_plat *plat = dev_get_plat(dev);
+	const char *prop;
+
+	if (CONFIG_IS_ENABLED(ARMV8_MULTIENTRY)) {
+		plat->release_addr = ~0ULL;
+
+		prop = dev_read_string(dev, "enable-method");
+		if (!prop || strcmp(prop, "spin-table"))
+			return -ENODEV;
+
+		plat->release_addr = dev_read_u64_default(dev, "cpu-release-addr", ~0ULL);
+
+		if (plat->release_addr == ~0ULL)
+			return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int bcm_cpu_probe(struct udevice *dev)
+{
+	struct cpu_plat *plat = dev_get_parent_plat(dev);
+	struct clk clk;
+	int ret;
+
+	/* Get a clock if it exists */
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (!ret) {
+		ret = clk_enable(&clk);
+		if (ret && (ret != -ENOSYS || ret != -EOPNOTSUPP))
+			return ret;
+		ret = clk_get_rate(&clk);
+		if (IS_ERR_VALUE(ret))
+			return ret;
+		plat->timebase_freq = ret;
+	}
+
+	/*
+	 * The armstub holds the secondary CPUs in a spinloop. When
+	 * ARMV8_MULTIENTRY is enabled release the secondary CPUs and
+	 * let them enter U-Boot as well.
+	 */
+	if (CONFIG_IS_ENABLED(ARMV8_MULTIENTRY)) {
+		ret = bcm_cpu_on(dev);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+struct acpi_ops bcm283x_cpu_acpi_ops = {
+	.fill_ssdt	= armv8_cpu_fill_ssdt,
+	.fill_madt	= armv8_cpu_fill_madt,
+};
+
+U_BOOT_DRIVER(cpu_bcm_drv) = {
+	.name		= "bcm283x_cpu",
+	.id		= UCLASS_CPU,
+	.of_match	= cpu_bcm_ids,
+	.ops		= &cpu_bcm_ops,
+	.probe		= bcm_cpu_probe,
+	.bind		= bcm_cpu_bind,
+	.of_to_plat	= bcm_cpu_of_to_plat,
+	.plat_auto	= sizeof(struct bcm_plat),
+	.flags		= 0,
+	ACPI_OPS_PTR(&bcm283x_cpu_acpi_ops)
+};
-- 
2.46.0


  parent reply	other threads:[~2024-09-18 15:27 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-18 15:20 [PATCH v4 00/35] Implement ACPI on aarch64 Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 01/35] acpi: x86: Move SPCR and DBG2 into common code Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 02/35] acpi: x86: Write FADT in " Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 03/35] acpi: x86: Move MADT to " Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 04/35] acpi: Fix typo Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 05/35] serial: serial_pl01x: Implement .getinfo() for PL01 Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 06/35] acpi: Add define for GTDT Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 07/35] arm: acpi: Add generic ACPI methods Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 08/35] acpi: Add fill_madt to acpi_ops Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 09/35] acpi: acpi_table: Bump revisions Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 10/35] acpi: Add ACPITAB for PPTT and GTDT Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 11/35] acpi: acpi_table: Add IORT support Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 12/35] acpi: Move function prototype Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 13/35] acpi_table: Support platforms with unusable RSDT Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 14/35] efi_loader: Allocate and write ACPI tables Patrick Rudolph
2024-09-18 16:01   ` Ilias Apalodimas
2024-09-19 14:10   ` Simon Glass
2024-09-19 14:39     ` Ilias Apalodimas
2024-09-19 15:00       ` Simon Glass
2024-09-19 15:19         ` Ilias Apalodimas
2024-09-19 15:30           ` Ilias Apalodimas
2024-09-19 15:36           ` Simon Glass
2024-09-20  6:36             ` Ilias Apalodimas
2024-09-20 16:01               ` Simon Glass
2024-09-26  8:01                 ` Patrick Rudolph
2024-09-26 11:04                   ` Simon Glass
2024-09-26 11:18                     ` Ilias Apalodimas
2024-09-27 10:53                       ` Simon Glass
2024-09-27 11:30                         ` Ilias Apalodimas
2024-09-27 12:35                           ` Simon Glass
2024-09-27 13:14                             ` Ilias Apalodimas
2024-09-27 13:38                               ` Ilias Apalodimas
2024-09-27 14:10                               ` Tom Rini
2024-09-27 16:52                               ` Simon Glass
2024-09-26 11:25                 ` Ilias Apalodimas
2024-09-27 10:51                   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 15/35] acpi: Add processor device Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 16/35] drivers: usb: Add generic XHCI Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 17/35] drivers: ata: Rename ahci_mvebu Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 18/35] drivers/cpu: Add generic armv8 cpu driver Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 19/35] arm: gic-v3-its: Rename objects Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 20/35] arm: gic-v3-its: Implement of_xlate Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 21/35] arm: lib: Add GICV2 driver Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 22/35] drivers: misc: irq-uclass: Update irq_get_by_index Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-20  7:56     ` Patrick Rudolph
2024-09-20 15:57       ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 23/35] drivers/arm: Implement acpi_fill_madt Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-23  5:48     ` Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 24/35] common: Enable BLOBLIST_TABLES on arm Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 25/35] board: emulation: Add QEMU sbsa support Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 26/35] arm: mach-bcm283x: Map the ARM local MMIO as well Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-19 17:36   ` Matthias Brugger
2024-09-18 15:20 ` [PATCH v4 27/35] arm: mach-bcm283x: Bring in some header files from tianocore Patrick Rudolph
2024-09-19 17:37   ` Matthias Brugger
2024-09-18 15:20 ` [PATCH v4 28/35] arm: bcm283x: Generate ACPI tables Patrick Rudolph
2024-09-19 14:11   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 29/35] board: raspberrypi: Add ASL files from tianocore Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 30/35] arm: cpu: Add ACPI parking protocol support Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-23  6:29     ` Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 31/35] armv8: cpu: Enable ACPI parking protocol Patrick Rudolph
2024-09-19 14:09   ` Simon Glass
2024-09-18 15:20 ` Patrick Rudolph [this message]
2024-09-19 14:09   ` [PATCH v4 32/35] arm: mach-bcm283x: Add ARMV8_MULTIENTRY support Simon Glass
2024-09-23  5:57     ` Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 33/35] arm: mach-bcm283x: Enable ARMV8_MULTIENTRY Patrick Rudolph
2024-09-18 15:20 ` [PATCH v4 34/35] bloblist: Fix use of uninitialized variable Patrick Rudolph
2024-09-19 14:10   ` Simon Glass
2024-09-18 15:20 ` [PATCH v4 35/35] configs: Add RPI4 ACPI defconfig Patrick Rudolph
2024-09-19 14:09   ` Simon Glass

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=20240918152136.3395170-33-patrick.rudolph@9elements.com \
    --to=patrick.rudolph@9elements.com \
    --cc=mbrugger@suse.com \
    --cc=pbrobinson@gmail.com \
    --cc=rayagonda.kokatanur@broadcom.com \
    --cc=trini@konsulko.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.