-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: utils/reset: Add a sunxi watchdog reset driver
One of the watchdogs in the D1 SoC provides a "soft reset" function, which allows software to immediately reset the entire SoC. Add a driver so it can implement the SBI system reset function. Signed-off-by: Samuel Holland <samuel@sholland.org> Reviewed-by: Anup Patel <anup.patel@wdc.com>
- Loading branch information
Showing
3 changed files
with
80 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
* | ||
* Copyright (c) 2021 Samuel Holland <samuel@sholland.org> | ||
*/ | ||
|
||
#include <libfdt.h> | ||
#include <sbi/riscv_io.h> | ||
#include <sbi/sbi_bitops.h> | ||
#include <sbi/sbi_error.h> | ||
#include <sbi/sbi_system.h> | ||
#include <sbi_utils/fdt/fdt_helper.h> | ||
#include <sbi_utils/reset/fdt_reset.h> | ||
|
||
#define WDT_KEY_VAL 0x16aa0000 | ||
|
||
#define WDT_SOFT_RST_REG 0x08 | ||
#define WDT_SOFT_RST_EN BIT(0) | ||
|
||
#define WDT_MODE_REG 0x18 | ||
|
||
static volatile void *sunxi_wdt_base; | ||
|
||
static int sunxi_wdt_system_reset_check(u32 type, u32 reason) | ||
{ | ||
switch (type) { | ||
case SBI_SRST_RESET_TYPE_COLD_REBOOT: | ||
case SBI_SRST_RESET_TYPE_WARM_REBOOT: | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void sunxi_wdt_system_reset(u32 type, u32 reason) | ||
{ | ||
/* Disable the watchdog. */ | ||
writel_relaxed(WDT_KEY_VAL, | ||
sunxi_wdt_base + WDT_MODE_REG); | ||
|
||
/* Trigger soft reset. */ | ||
writel_relaxed(WDT_KEY_VAL | WDT_SOFT_RST_EN, | ||
sunxi_wdt_base + WDT_SOFT_RST_REG); | ||
} | ||
|
||
static struct sbi_system_reset_device sunxi_wdt_reset = { | ||
.name = "sunxi-wdt-reset", | ||
.system_reset_check = sunxi_wdt_system_reset_check, | ||
.system_reset = sunxi_wdt_system_reset, | ||
}; | ||
|
||
static int sunxi_wdt_reset_init(void *fdt, int nodeoff, | ||
const struct fdt_match *match) | ||
{ | ||
uint64_t reg_addr; | ||
int rc; | ||
|
||
rc = fdt_get_node_addr_size(fdt, nodeoff, 0, ®_addr, NULL); | ||
if (rc < 0 || !reg_addr) | ||
return SBI_ENODEV; | ||
|
||
sunxi_wdt_base = (volatile void *)(unsigned long)reg_addr; | ||
|
||
sbi_system_reset_set_device(&sunxi_wdt_reset); | ||
|
||
return 0; | ||
} | ||
|
||
static const struct fdt_match sunxi_wdt_reset_match[] = { | ||
{ .compatible = "allwinner,sun20i-d1-wdt-reset" }, | ||
{ }, | ||
}; | ||
|
||
struct fdt_reset fdt_reset_sunxi_wdt = { | ||
.match_table = sunxi_wdt_reset_match, | ||
.init = sunxi_wdt_reset_init, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters