Skip to content

Commit a22acbb

Browse files
jamin-aspeedlegoater
authored andcommitted
aspeed/wdt: Support software reset mode for AST2600
On the AST2400 and AST2500 platforms, the system can only be reset by enabling the WDT (Watchdog Timer) and waiting for the WDT timeout. However, starting from the AST2600 platform, the reset event can be triggered directly and intentionally by software, without relying on the WDT timeout. This mechanism, referred to as "software restart", is implemented in hardware. When using the software restart mechanism, the WDT counter is not enabled. To trigger a reset generation in software mode, write 0xAEEDF123 to register 0x24 and software mode reset only support SOC reset mode. A new function, "aspeed_wdt_is_soc_reset_mode", is introduced to determine whether the SoC reset mode is active. Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Link: https://lore.kernel.org/qemu-devel/20250124030249.1706996-3-jamin_lin@aspeedtech.com Signed-off-by: Cédric Le Goater <clg@redhat.com>
1 parent 668f29e commit a22acbb

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

hw/watchdog/wdt_aspeed.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,20 @@
5151
#define WDT_TIMEOUT_CLEAR (0x14 / 4)
5252

5353
#define WDT_RESTART_MAGIC 0x4755
54+
#define WDT_SW_RESET_ENABLE 0xAEEDF123
5455

5556
#define AST2600_SCU_RESET_CONTROL1 (0x40 / 4)
5657
#define SCU_RESET_CONTROL1 (0x04 / 4)
5758
#define SCU_RESET_SDRAM BIT(0)
5859

60+
static bool aspeed_wdt_is_soc_reset_mode(const AspeedWDTState *s)
61+
{
62+
uint32_t mode;
63+
64+
mode = extract32(s->regs[WDT_CTRL], 5, 2);
65+
return (mode == WDT_CTRL_RESET_MODE_SOC);
66+
}
67+
5968
static bool aspeed_wdt_is_enabled(const AspeedWDTState *s)
6069
{
6170
return s->regs[WDT_CTRL] & WDT_CTRL_ENABLE;
@@ -199,13 +208,18 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
199208
case WDT_TIMEOUT_STATUS:
200209
case WDT_TIMEOUT_CLEAR:
201210
case WDT_RESET_MASK2:
202-
case WDT_SW_RESET_CTRL:
203211
case WDT_SW_RESET_MASK1:
204212
case WDT_SW_RESET_MASK2:
205213
qemu_log_mask(LOG_UNIMP,
206214
"%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
207215
__func__, offset);
208216
break;
217+
case WDT_SW_RESET_CTRL:
218+
if (aspeed_wdt_is_soc_reset_mode(s) &&
219+
(data == WDT_SW_RESET_ENABLE)) {
220+
watchdog_perform_action();
221+
}
222+
break;
209223
default:
210224
qemu_log_mask(LOG_GUEST_ERROR,
211225
"%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",

0 commit comments

Comments
 (0)