2016-10-20 23:08:26 +02:00
|
|
|
From 5103e7d2bf4b144f2e706f1d642f88cf0b610d68 Mon Sep 17 00:00:00 2001
|
2016-07-01 10:00:13 +02:00
|
|
|
From: Alexander Graf <agraf@suse.de>
|
|
|
|
Date: Sun, 5 Jun 2016 13:07:44 +0200
|
|
|
|
Subject: [PATCH] ARM: bcm283x: Implement EFI RTS reset_system
|
|
|
|
|
|
|
|
The rpi has a pretty simple way of resetting the whole system. All it takes
|
|
|
|
is to poke a few registers at a well defined location in MMIO space.
|
|
|
|
|
|
|
|
This patch adds support for the EFI loader implementation to allow an OS to
|
|
|
|
reset and power off the system when we're outside of boot time.
|
|
|
|
|
|
|
|
Signed-off-by: Alexander Graf <agraf@suse.de>
|
|
|
|
---
|
|
|
|
arch/arm/mach-bcm283x/include/mach/wdog.h | 2 +-
|
|
|
|
arch/arm/mach-bcm283x/reset.c | 59 +++++++++++++++++++++++++++----
|
|
|
|
2 files changed, 54 insertions(+), 7 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h
|
|
|
|
index 7741d7b..b4caca1 100644
|
|
|
|
--- a/arch/arm/mach-bcm283x/include/mach/wdog.h
|
|
|
|
+++ b/arch/arm/mach-bcm283x/include/mach/wdog.h
|
|
|
|
@@ -16,7 +16,7 @@
|
|
|
|
struct bcm2835_wdog_regs {
|
|
|
|
u32 unknown0[7];
|
|
|
|
u32 rstc;
|
|
|
|
- u32 unknown1;
|
|
|
|
+ u32 rsts;
|
|
|
|
u32 wdog;
|
|
|
|
};
|
|
|
|
|
|
|
|
diff --git a/arch/arm/mach-bcm283x/reset.c b/arch/arm/mach-bcm283x/reset.c
|
|
|
|
index 72cdc31..e87241d 100644
|
|
|
|
--- a/arch/arm/mach-bcm283x/reset.c
|
|
|
|
+++ b/arch/arm/mach-bcm283x/reset.c
|
|
|
|
@@ -10,19 +10,66 @@
|
|
|
|
#include <common.h>
|
|
|
|
#include <asm/io.h>
|
|
|
|
#include <asm/arch/wdog.h>
|
|
|
|
+#include <efi_loader.h>
|
|
|
|
|
|
|
|
#define RESET_TIMEOUT 10
|
|
|
|
|
|
|
|
-void reset_cpu(ulong addr)
|
|
|
|
+/*
|
|
|
|
+ * The Raspberry Pi firmware uses the RSTS register to know which partiton
|
|
|
|
+ * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10.
|
|
|
|
+ * Partiton 63 is a special partition used by the firmware to indicate halt.
|
|
|
|
+ */
|
|
|
|
+#define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT 0x555
|
|
|
|
+
|
|
|
|
+EFI_RUNTIME_DATA struct bcm2835_wdog_regs *wdog_regs =
|
|
|
|
+ (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
|
|
|
|
+
|
|
|
|
+void EFI_RUNTIME_TEXT reset_cpu(ulong addr)
|
|
|
|
{
|
|
|
|
- struct bcm2835_wdog_regs *regs =
|
|
|
|
- (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR;
|
|
|
|
uint32_t rstc;
|
|
|
|
|
|
|
|
- rstc = readl(®s->rstc);
|
|
|
|
+ rstc = readl(&wdog_regs->rstc);
|
|
|
|
rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK;
|
|
|
|
rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET;
|
|
|
|
|
|
|
|
- writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, ®s->wdog);
|
|
|
|
- writel(BCM2835_WDOG_PASSWORD | rstc, ®s->rstc);
|
|
|
|
+ writel(BCM2835_WDOG_PASSWORD | RESET_TIMEOUT, &wdog_regs->wdog);
|
|
|
|
+ writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_EFI_LOADER
|
|
|
|
+
|
|
|
|
+void EFI_RUNTIME_TEXT EFIAPI efi_reset_system(
|
|
|
|
+ enum efi_reset_type reset_type,
|
|
|
|
+ efi_status_t reset_status,
|
|
|
|
+ unsigned long data_size, void *reset_data)
|
|
|
|
+{
|
|
|
|
+ u32 val;
|
|
|
|
+
|
|
|
|
+ switch (reset_type) {
|
|
|
|
+ case EFI_RESET_COLD:
|
|
|
|
+ case EFI_RESET_WARM:
|
|
|
|
+ reset_cpu(0);
|
|
|
|
+ break;
|
|
|
|
+ case EFI_RESET_SHUTDOWN:
|
|
|
|
+ /*
|
|
|
|
+ * We set the watchdog hard reset bit here to distinguish this reset
|
|
|
|
+ * from the normal (full) reset. bootcode.bin will not reboot after a
|
|
|
|
+ * hard reset.
|
|
|
|
+ */
|
|
|
|
+ val = readl(&wdog_regs->rsts);
|
|
|
|
+ val |= BCM2835_WDOG_PASSWORD;
|
|
|
|
+ val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT;
|
|
|
|
+ writel(val, &wdog_regs->rsts);
|
|
|
|
+ reset_cpu(0);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ while (1) { }
|
|
|
|
}
|
|
|
|
+
|
|
|
|
+void efi_reset_system_init(void)
|
|
|
|
+{
|
|
|
|
+ efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#endif
|