88 lines
1.9 KiB
C
88 lines
1.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (C) 2019 Pepperl+Fuchs
|
|
* Copyright (C) 2025 Altera Corporation <www.altera.com>
|
|
* Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
|
|
*/
|
|
|
|
#include <command.h>
|
|
#include <cpu_func.h>
|
|
#include <dm.h>
|
|
#include <errno.h>
|
|
#include <sysreset.h>
|
|
#include <asm/arch/mailbox_s10.h>
|
|
#include <asm/arch/reset_manager.h>
|
|
#include <asm/secure.h>
|
|
|
|
#define GICD_CTRL_ADDRESS 0xfffc1000
|
|
|
|
static __always_inline void __l2_reset_cpu(void)
|
|
{
|
|
asm volatile(/* Disable GIC distributor (IRQs). */
|
|
"str wzr, [%3]\n"
|
|
/* Set Magic Number */
|
|
"str %0, [%1]\n"
|
|
/* Increase timeout in rstmgr.hdsktimeout */
|
|
"ldr x2, =0xFFFFFF\n"
|
|
"str w2, [%2, #0x64]\n"
|
|
"ldr w2, [%2, #0x10]\n"
|
|
/*
|
|
* Set l2flushen = 1, etrstallen = 1,
|
|
* fpgahsen = 1 and sdrselfrefen = 1
|
|
* in rstmgr.hdsken to perform handshake
|
|
* in certain peripherals before trigger
|
|
* L2 reset.
|
|
*/
|
|
"ldr x3, =0x10D\n"
|
|
"orr x2, x2, x3\n"
|
|
"str w2, [%2, #0x10]\n"
|
|
/* Trigger L2 reset in rstmgr.coldmodrst */
|
|
"ldr w2, [%2, #0x34]\n"
|
|
"orr x2, x2, #0x100\n"
|
|
"isb\n"
|
|
"dsb sy\n"
|
|
"str w2, [%2, #0x34]\n"
|
|
/* Put all cores into WFI mode */
|
|
"1:\n"
|
|
" wfi\n"
|
|
" b 1b\n"
|
|
: : "r" (L2_RESET_DONE_STATUS),
|
|
"r" (L2_RESET_DONE_REG),
|
|
"r" (SOCFPGA_RSTMGR_ADDRESS),
|
|
"r" (GICD_CTRL_ADDRESS)
|
|
: "x1", "x2", "x3");
|
|
}
|
|
|
|
static void l2_reset_cpu(void)
|
|
{
|
|
__l2_reset_cpu();
|
|
}
|
|
|
|
static int socfpga_sysreset_request(struct udevice *dev,
|
|
enum sysreset_t type)
|
|
{
|
|
if (type == SYSRESET_WARM) {
|
|
/* flush dcache */
|
|
flush_dcache_all();
|
|
|
|
/* request a warm reset */
|
|
puts("Do warm reset now...\n");
|
|
l2_reset_cpu();
|
|
} else {
|
|
puts("Mailbox: Issuing mailbox cmd REBOOT_HPS\n");
|
|
mbox_reset_cold();
|
|
}
|
|
|
|
return -EINPROGRESS;
|
|
}
|
|
|
|
static struct sysreset_ops socfpga_sysreset = {
|
|
.request = socfpga_sysreset_request,
|
|
};
|
|
|
|
U_BOOT_DRIVER(sysreset_socfpga_soc64) = {
|
|
.id = UCLASS_SYSRESET,
|
|
.name = "socfpga_sysreset",
|
|
.ops = &socfpga_sysreset,
|
|
};
|