u-boot/arch/arm/mach-socfpga/reset_manager.c
Marek Vasut 1115cd2de7 arm: socfpga: reset: Start reworking the SoCFPGA reset manager
Implement macro SOCFPGA_RESET(name), which produces an abstract
reset number. Implement macros which allow extracting the reset
offset in permodrstN register and which permodrstN register the
reset is located in from this abstract reset number. Use these
macros throughout the reset manager.

Signed-off-by: Marek Vasut <marex@denx.de>
2015-08-08 14:14:06 +02:00

139 lines
3.4 KiB
C

/*
* Copyright (C) 2013 Altera Corporation <www.altera.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/fpga_manager.h>
DECLARE_GLOBAL_DATA_PTR;
static const struct socfpga_reset_manager *reset_manager_base =
(void *)SOCFPGA_RSTMGR_ADDRESS;
/* Toggle reset signal to watchdog (WDT is disabled after this operation!) */
void socfpga_watchdog_reset(void)
{
/* assert reset for watchdog */
setbits_le32(&reset_manager_base->per_mod_reset,
1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)));
/* deassert watchdog from reset (watchdog in not running state) */
clrbits_le32(&reset_manager_base->per_mod_reset,
1 << RSTMGR_RESET(SOCFPGA_RESET(L4WD0)));
}
/*
* Write the reset manager register to cause reset
*/
void reset_cpu(ulong addr)
{
/* request a warm reset */
writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB),
&reset_manager_base->ctrl);
/*
* infinite loop here as watchdog will trigger and reset
* the processor
*/
while (1)
;
}
/*
* Release peripherals from reset based on handoff
*/
void reset_deassert_peripherals_handoff(void)
{
writel(0, &reset_manager_base->per_mod_reset);
}
#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
void socfpga_bridges_reset(int enable)
{
/* For SoCFPGA-VT, this is NOP. */
}
#else
#define L3REGS_REMAP_LWHPS2FPGA_MASK 0x10
#define L3REGS_REMAP_HPS2FPGA_MASK 0x08
#define L3REGS_REMAP_OCRAM_MASK 0x01
void socfpga_bridges_reset(int enable)
{
const uint32_t l3mask = L3REGS_REMAP_LWHPS2FPGA_MASK |
L3REGS_REMAP_HPS2FPGA_MASK |
L3REGS_REMAP_OCRAM_MASK;
if (enable) {
/* brdmodrst */
writel(0xffffffff, &reset_manager_base->brg_mod_reset);
} else {
/* Check signal from FPGA. */
if (fpgamgr_poll_fpga_ready()) {
/* FPGA not ready. Wait for watchdog timeout. */
printf("%s: fpga not ready, hanging.\n", __func__);
hang();
}
/* brdmodrst */
writel(0, &reset_manager_base->brg_mod_reset);
/* Remap the bridges into memory map */
writel(l3mask, SOCFPGA_L3REGS_ADDRESS);
}
}
#endif
/* Change the reset state for EMAC 0 and EMAC 1 */
void socfpga_emac_reset(int enable)
{
const void *reset = &reset_manager_base->per_mod_reset;
if (enable) {
setbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(EMAC0)));
setbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(EMAC1)));
} else {
#if (CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS)
clrbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(EMAC0)));
#elif (CONFIG_EMAC_BASE == SOCFPGA_EMAC1_ADDRESS)
clrbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(EMAC1)));
#endif
}
}
/* SPI Master enable (its held in reset by the preloader) */
void socfpga_spim_enable(void)
{
const void *reset = &reset_manager_base->per_mod_reset;
clrbits_le32(reset, (1 << RSTMGR_RESET(SOCFPGA_RESET(SPIM0))) |
(1 << RSTMGR_RESET(SOCFPGA_RESET(SPIM1))));
}
/* Bring UART0 out of reset. */
void socfpga_uart0_enable(void)
{
const void *reset = &reset_manager_base->per_mod_reset;
clrbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(UART0)));
}
/* Bring SDRAM controller out of reset. */
void socfpga_sdram_enable(void)
{
const void *reset = &reset_manager_base->per_mod_reset;
clrbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(SDR)));
}
/* Bring OSC1 timer out of reset. */
void socfpga_osc1timer_enable(void)
{
const void *reset = &reset_manager_base->per_mod_reset;
clrbits_le32(reset, 1 << RSTMGR_RESET(SOCFPGA_RESET(OSC1TIMER0)));
}