Unverified Commit ce6897ea authored by Chen-Yu Tsai's avatar Chen-Yu Tsai Committed by GitHub
Browse files

Merge pull request #131 from karlp/wdreset

Provide a wrapper for reset via watchdog
Tested-By: Priit Laes plaes@plaes.org # On A20 with custom patch
parents 42ffc5f7 353a5ae0
......@@ -1055,6 +1055,20 @@ void aw_rmr_request(feldev_handle *dev, uint32_t entry_point, bool aarch64)
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 */
static bool is_uEnv(void *buffer, size_t size)
{
......@@ -1164,6 +1178,7 @@ void usage(const char *cmd) {
" dump address length Binary memory dump\n"
" exe[cute] address Call function address\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"
" readl address Read 32-bit value from device memory\n"
" writel address value Write 32-bit value to device memory\n"
......@@ -1296,6 +1311,8 @@ int main(int argc, char **argv)
/* Cancel U-Boot autostart, and stop processing args */
uboot_autostart = false;
break;
} else if (strcmp(argv[1], "wdreset") == 0) {
aw_wd_reset(handle);
} else if (strncmp(argv[1], "ver", 3) == 0) {
aw_fel_print_version(handle);
} else if (strcmp(argv[1], "sid") == 0) {
......
......@@ -110,6 +110,16 @@ sram_swap_buffers h6_sram_swap_buffers[] = {
{ .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_id = 0x1623, /* Allwinner A10 */
......@@ -119,6 +129,7 @@ soc_info_t soc_info_table[] = {
.swap_buffers = a10_a13_a20_sram_swap_buffers,
.needs_l2en = true,
.sid_base = 0x01C23800,
.watchdog = &wd_a10_compat,
},{
.soc_id = 0x1625, /* Allwinner A10s, A13, R8 */
.name = "A13",
......@@ -195,6 +206,7 @@ soc_info_t soc_info_table[] = {
.sid_fix = true,
/* Check L.NOP in the OpenRISC reset vector */
.needs_smc_workaround_if_zero_word_at_addr = 0x40004,
.watchdog = &wd_h3_compat,
},{
.soc_id = 0x1681, /* Allwinner V3s */
.name = "V3s",
......@@ -215,6 +227,7 @@ soc_info_t soc_info_table[] = {
.rvbar_reg = 0x017000A0,
/* Check L.NOP in the OpenRISC reset vector */
.needs_smc_workaround_if_zero_word_at_addr = 0x40004,
.watchdog = &wd_h3_compat,
},{
.soc_id = 0x1701, /* Allwinner R40 */
.name = "R40",
......
......@@ -51,6 +51,16 @@ typedef struct {
uint32_t size; /* buffer size */
} 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
* and the information about the placement of the thunk code, which handles
......@@ -101,6 +111,7 @@ typedef struct {
uint32_t sid_base; /* base address for SID registers */
uint32_t sid_offset; /* offset for SID_KEY[0-3], "root key" */
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) */
/* Use SMC workaround (enter secure mode) if can't read from this address */
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