1 /* 2 * (C) Copyright 2012 Stephen Warren 3 * 4 * See file CREDITS for list of people who contributed to this 5 * project. 6 * 7 * SPDX-License-Identifier: GPL-2.0 8 */ 9 10 #include <common.h> 11 #include <asm/io.h> 12 #include <asm/arch/wdog.h> 13 #include <efi_loader.h> 14 15 #define RESET_TIMEOUT 10 16 17 /* 18 * The Raspberry Pi firmware uses the RSTS register to know which partiton 19 * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10. 20 * Partiton 63 is a special partition used by the firmware to indicate halt. 21 */ 22 #define BCM2835_WDOG_RSTS_RASPBERRYPI_HALT 0x555 23 24 /* max ticks timeout */ 25 #define BCM2835_WDOG_MAX_TIMEOUT 0x000fffff 26 27 #ifdef CONFIG_BCM2835_WDT 28 extern void hw_watchdog_disable(void); 29 #else 30 void hw_watchdog_disable(void) {} 31 #endif 32 33 __efi_runtime_data struct bcm2835_wdog_regs *wdog_regs = 34 (struct bcm2835_wdog_regs *)BCM2835_WDOG_PHYSADDR; 35 36 void __efi_runtime reset_cpu(ulong ticks) 37 { 38 uint32_t rstc, timeout; 39 40 if (ticks == 0) { 41 hw_watchdog_disable(); 42 timeout = RESET_TIMEOUT; 43 } else 44 timeout = ticks & BCM2835_WDOG_MAX_TIMEOUT; 45 46 rstc = readl(&wdog_regs->rstc); 47 rstc &= ~BCM2835_WDOG_RSTC_WRCFG_MASK; 48 rstc |= BCM2835_WDOG_RSTC_WRCFG_FULL_RESET; 49 50 writel(BCM2835_WDOG_PASSWORD | timeout, &wdog_regs->wdog); 51 writel(BCM2835_WDOG_PASSWORD | rstc, &wdog_regs->rstc); 52 } 53 54 #ifdef CONFIG_EFI_LOADER 55 56 void __efi_runtime EFIAPI efi_reset_system( 57 enum efi_reset_type reset_type, 58 efi_status_t reset_status, 59 unsigned long data_size, void *reset_data) 60 { 61 u32 val; 62 63 switch (reset_type) { 64 case EFI_RESET_COLD: 65 case EFI_RESET_WARM: 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 void efi_reset_system_init(void) 86 { 87 efi_add_runtime_mmio(&wdog_regs, sizeof(*wdog_regs)); 88 } 89 90 #endif 91