1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) Copyright 2012 Stephen Warren 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 */ 8 9 #include <common.h> 10 #include <asm/io.h> 11 #include <asm/arch/wdog.h> 12 #include <efi_loader.h> 13 14 #define RESET_TIMEOUT 10 15 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 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 32 __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = 33 (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; 34 35 void __efi_runtime reset_cpu(ulong ticks) 36 { 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; 44 45 rstc = readl(&wdog_regs->rstc); 46 rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; 47 rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; 48 49 writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog); 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 if (reset_type == EFI_RESET_COLD || 63 reset_type == EFI_RESET_WARM || 64 reset_type == EFI_RESET_PLATFORM_SPECIFIC) { 65 reset_cpu(0); 66 } else if (reset_type == EFI_RESET_SHUTDOWN) { 67 /* 68 * We set the watchdog hard reset bit here to distinguish this reset 69 * from the normal (full) reset. bootcode.bin will not reboot after a 70 * hard reset. 71 */ 72 val = readl(&wdog_regs->rsts); 73 val |= BCM2835_WDOG_PASSWORD; 74 val |= BCM2835_WDOG_RSTS_RASPBERRYPI_HALT; 75 writel(val, &wdog_regs->rsts); 76 reset_cpu(0); 77 } 78 79 while (1) { } 80 } 81 82 efi_status_t efi_reset_system_init(void) 83 { 84 return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs)); 85 } 86 87 #endif 88