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