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 switch (reset_type) { 63 case EFI_RESET_COLD: 64 case EFI_RESET_WARM: 65 case EFI_RESET_PLATFORM_SPECIFIC: 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) { } 83 } 84 85 efi_status_t efi_reset_system_init(void) 86 { 87 return efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs)); 88 } 89 90 #endif 91