Commit 353a5ae0 authored by Karl Palsson's avatar Karl Palsson
Browse files

Provide a wrapper for reset via watchdog



The watchdog register isn't in the same place, nor uses the same values
to trigger a reset.
Signed-off-by: default avatarKarl Palsson <karlp@tweak.net.au>
parent 42ffc5f7
...@@ -1055,6 +1055,20 @@ void aw_rmr_request(feldev_handle *dev, uint32_t entry_point, bool aarch64) ...@@ -1055,6 +1055,20 @@ void aw_rmr_request(feldev_handle *dev, uint32_t entry_point, bool aarch64)
pr_info(" done.\n"); pr_info(" done.\n");
} }
/* Use the watchdog to simply reboot. Useful to get out of fel without
* power cycling or plugging.
*/
void aw_wd_reset(feldev_handle *dev)
{
const watchdog_info *wd = dev->soc_info->watchdog;
if (!wd) {
pr_error("No watchdog information available (yet) for soc: %s\n", dev->soc_info->name);
return;
}
fel_writel(dev, wd->reg_mode, wd->reg_mode_value);
pr_info("Requested watchdog reset\n");
}
/* check buffer for magic "#=uEnv", indicating uEnv.txt compatible format */ /* check buffer for magic "#=uEnv", indicating uEnv.txt compatible format */
static bool is_uEnv(void *buffer, size_t size) static bool is_uEnv(void *buffer, size_t size)
{ {
...@@ -1164,6 +1178,7 @@ void usage(const char *cmd) { ...@@ -1164,6 +1178,7 @@ void usage(const char *cmd) {
" dump address length Binary memory dump\n" " dump address length Binary memory dump\n"
" exe[cute] address Call function address\n" " exe[cute] address Call function address\n"
" reset64 address RMR request for AArch64 warm boot\n" " reset64 address RMR request for AArch64 warm boot\n"
" wdreset Reboot via watchdog\n"
" memmove dest source size Copy <size> bytes within device memory\n" " memmove dest source size Copy <size> bytes within device memory\n"
" readl address Read 32-bit value from device memory\n" " readl address Read 32-bit value from device memory\n"
" writel address value Write 32-bit value to device memory\n" " writel address value Write 32-bit value to device memory\n"
...@@ -1296,6 +1311,8 @@ int main(int argc, char **argv) ...@@ -1296,6 +1311,8 @@ int main(int argc, char **argv)
/* Cancel U-Boot autostart, and stop processing args */ /* Cancel U-Boot autostart, and stop processing args */
uboot_autostart = false; uboot_autostart = false;
break; break;
} else if (strcmp(argv[1], "wdreset") == 0) {
aw_wd_reset(handle);
} else if (strncmp(argv[1], "ver", 3) == 0) { } else if (strncmp(argv[1], "ver", 3) == 0) {
aw_fel_print_version(handle); aw_fel_print_version(handle);
} else if (strcmp(argv[1], "sid") == 0) { } else if (strcmp(argv[1], "sid") == 0) {
......
...@@ -110,6 +110,16 @@ sram_swap_buffers h6_sram_swap_buffers[] = { ...@@ -110,6 +110,16 @@ sram_swap_buffers h6_sram_swap_buffers[] = {
{ .size = 0 } /* End of the table */ { .size = 0 } /* End of the table */
}; };
const watchdog_info wd_a10_compat = {
.reg_mode = 0x01C20C94,
.reg_mode_value = 3,
};
const watchdog_info wd_h3_compat = {
.reg_mode = 0x01C20Cb8,
.reg_mode_value = 1,
};
soc_info_t soc_info_table[] = { soc_info_t soc_info_table[] = {
{ {
.soc_id = 0x1623, /* Allwinner A10 */ .soc_id = 0x1623, /* Allwinner A10 */
...@@ -119,6 +129,7 @@ soc_info_t soc_info_table[] = { ...@@ -119,6 +129,7 @@ soc_info_t soc_info_table[] = {
.swap_buffers = a10_a13_a20_sram_swap_buffers, .swap_buffers = a10_a13_a20_sram_swap_buffers,
.needs_l2en = true, .needs_l2en = true,
.sid_base = 0x01C23800, .sid_base = 0x01C23800,
.watchdog = &wd_a10_compat,
},{ },{
.soc_id = 0x1625, /* Allwinner A10s, A13, R8 */ .soc_id = 0x1625, /* Allwinner A10s, A13, R8 */
.name = "A13", .name = "A13",
...@@ -195,6 +206,7 @@ soc_info_t soc_info_table[] = { ...@@ -195,6 +206,7 @@ soc_info_t soc_info_table[] = {
.sid_fix = true, .sid_fix = true,
/* Check L.NOP in the OpenRISC reset vector */ /* Check L.NOP in the OpenRISC reset vector */
.needs_smc_workaround_if_zero_word_at_addr = 0x40004, .needs_smc_workaround_if_zero_word_at_addr = 0x40004,
.watchdog = &wd_h3_compat,
},{ },{
.soc_id = 0x1681, /* Allwinner V3s */ .soc_id = 0x1681, /* Allwinner V3s */
.name = "V3s", .name = "V3s",
...@@ -215,6 +227,7 @@ soc_info_t soc_info_table[] = { ...@@ -215,6 +227,7 @@ soc_info_t soc_info_table[] = {
.rvbar_reg = 0x017000A0, .rvbar_reg = 0x017000A0,
/* Check L.NOP in the OpenRISC reset vector */ /* Check L.NOP in the OpenRISC reset vector */
.needs_smc_workaround_if_zero_word_at_addr = 0x40004, .needs_smc_workaround_if_zero_word_at_addr = 0x40004,
.watchdog = &wd_h3_compat,
},{ },{
.soc_id = 0x1701, /* Allwinner R40 */ .soc_id = 0x1701, /* Allwinner R40 */
.name = "R40", .name = "R40",
......
...@@ -51,6 +51,16 @@ typedef struct { ...@@ -51,6 +51,16 @@ typedef struct {
uint32_t size; /* buffer size */ uint32_t size; /* buffer size */
} sram_swap_buffers; } sram_swap_buffers;
/*
* Contains information on the watchdog peripheral, to enable reset
*/
typedef struct {
/* Register that needs to be written to */
uint32_t reg_mode;
/* Value to write to trigger a reset */
uint32_t reg_mode_value;
} watchdog_info;
/* /*
* Each SoC variant may have its own list of memory buffers to be exchanged * Each SoC variant may have its own list of memory buffers to be exchanged
* and the information about the placement of the thunk code, which handles * and the information about the placement of the thunk code, which handles
...@@ -101,6 +111,7 @@ typedef struct { ...@@ -101,6 +111,7 @@ typedef struct {
uint32_t sid_base; /* base address for SID registers */ uint32_t sid_base; /* base address for SID registers */
uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */ uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */
uint32_t rvbar_reg; /* MMIO address of RVBARADDR0_L register */ uint32_t rvbar_reg; /* MMIO address of RVBARADDR0_L register */
const watchdog_info *watchdog; /* Used for reset */
bool sid_fix; /* Use SID workaround (read via register) */ bool sid_fix; /* Use SID workaround (read via register) */
/* Use SMC workaround (enter secure mode) if can't read from this address */ /* Use SMC workaround (enter secure mode) if can't read from this address */
uint32_t needs_smc_workaround_if_zero_word_at_addr; uint32_t needs_smc_workaround_if_zero_word_at_addr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment