]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0 |
efad6cf8 SW |
2 | /* |
3 | * (C) Copyright 2012 Stephen Warren | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
efad6cf8 SW |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
11 | #include <asm/arch/wdog.h> | |
6b0ee506 | 12 | #include <efi_loader.h> |
efad6cf8 SW |
13 | |
14 | #define RESET_TIMEOUT 10 | |
15 | ||
6b0ee506 AG |
16 | /* |
17 | * The Raspberry Pi firmware uses the RSTS register to know which partiton | |
18 | * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10. | |
19 | * Partiton 63 is a special partition used by the firmware to indicate halt. | |
20 | */ | |
21 | #define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT 0x555 | |
22 | ||
45a6d231 PP |
23 | /* max ticks timeout */ |
24 | #define BCM2835_WDOG_MAX_TIMEOUT 0x000fffff | |
25 | ||
26 | #ifdef CONFIG_BCM2835_WDT | |
27 | extern void hw_watchdog_disable(void); | |
28 | #else | |
29 | void hw_watchdog_disable(void) {} | |
30 | #endif | |
31 | ||
6b0ee506 AG |
32 | __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = |
33 | (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; | |
34 | ||
45a6d231 | 35 | void __efi_runtime reset_cpu(ulong ticks) |
efad6cf8 | 36 | { |
45a6d231 PP |
37 | uint32_t rstc, timeout; |
38 | ||
39 | if (ticks == 0) { | |
40 | hw_watchdog_disable(); | |
41 | timeout = RESET_TIMEOUT; | |
42 | } else | |
43 | timeout = ticks & BCM2835_WDOG_MAX_TIMEOUT; | |
efad6cf8 | 44 | |
6b0ee506 | 45 | rstc = readl(&wdog_regs->rstc); |
efad6cf8 SW |
46 | rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; |
47 | rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; | |
48 | ||
45a6d231 | 49 | writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog); |
6b0ee506 AG |
50 | writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc); |
51 | } | |
52 | ||
53 | #ifdef CONFIG_EFI_LOADER | |
54 | ||
55 | void __efi_runtime EFIAPI efi_reset_system( | |
56 | enum efi_reset_type reset_type, | |
57 | efi_status_t reset_status, | |
58 | unsigned long data_size, void *reset_data) | |
59 | { | |
60 | u32 val; | |
61 | ||
62 | switch (reset_type) { | |
63 | case EFI_RESET_COLD: | |
64 | case EFI_RESET_WARM: | |
482fc90c | 65 | case EFI_RESET_PLATFORM_SPECIFIC: |
6b0ee506 AG |
66 | reset_cpu(0); |
67 | break; | |
68 | case EFI_RESET_SHUTDOWN: | |
69 | /* | |
70 | * We set the watchdog hard reset bit here to distinguish this reset | |
71 | * from the normal (full) reset. bootcode.bin will not reboot after a | |
72 | * hard reset. | |
73 | */ | |
74 | val = readl(&wdog_regs->rsts); | |
75 | val |= BCM2835_WDOG_PASSWORD; | |
76 | val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT; | |
77 | writel(val, &wdog_regs->rsts); | |
78 | reset_cpu(0); | |
79 | break; | |
80 | } | |
81 | ||
82 | while (1) { } | |
efad6cf8 | 83 | } |
6b0ee506 | 84 | |
22c793e6 | 85 | efi_status_t efi_reset_system_init(void) |
6b0ee506 | 86 | { |
22c793e6 | 87 | return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs)); |
6b0ee506 AG |
88 | } |
89 | ||
90 | #endif |