[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 11/34] watchdog/aspeed: Fix AST2600 frequency behaviour
From: |
Peter Maydell |
Subject: |
[PULL 11/34] watchdog/aspeed: Fix AST2600 frequency behaviour |
Date: |
Mon, 16 Dec 2019 11:08:41 +0000 |
From: Joel Stanley <address@hidden>
The AST2600 control register sneakily changed the meaning of bit 4
without anyone noticing. It no longer controls the 1MHz vs APB clock
select, and instead always runs at 1MHz.
The AST2500 was always 1MHz too, but it retained bit 4, making it read
only. We can model both using the same fixed 1MHz calculation.
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
Reviewed-by: Cédric Le Goater <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
Signed-off-by: Joel Stanley <address@hidden>
Signed-off-by: Cédric Le Goater <address@hidden>
Message-id: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
---
include/hw/watchdog/wdt_aspeed.h | 1 +
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
index dfedd7662dd..819c22993a6 100644
--- a/include/hw/watchdog/wdt_aspeed.h
+++ b/include/hw/watchdog/wdt_aspeed.h
@@ -47,6 +47,7 @@ typedef struct AspeedWDTClass {
uint32_t ext_pulse_width_mask;
uint32_t reset_ctrl_reg;
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
+ void (*wdt_reload)(AspeedWDTState *s);
} AspeedWDTClass;
#endif /* WDT_ASPEED_H */
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index d283d07d654..122aa8daaad 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -93,11 +93,11 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr
offset, unsigned size)
}
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
+static void aspeed_wdt_reload(AspeedWDTState *s)
{
uint64_t reload;
- if (pclk) {
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
s->pclk_freq);
} else {
@@ -109,6 +109,16 @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
}
}
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
+{
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
+
+ if (aspeed_wdt_is_enabled(s)) {
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
+ }
+}
+
+
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size)
{
@@ -130,13 +140,13 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset,
uint64_t data,
case WDT_RESTART:
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
+ awc->wdt_reload(s);
}
break;
case WDT_CTRL:
if (enable && !aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
+ awc->wdt_reload(s);
} else if (!enable && aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
timer_del(s->timer);
@@ -283,6 +293,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass,
void *data)
awc->offset = 0x20;
awc->ext_pulse_width_mask = 0xff;
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
+ awc->wdt_reload = aspeed_wdt_reload;
}
static const TypeInfo aspeed_2400_wdt_info = {
@@ -317,6 +328,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass,
void *data)
awc->ext_pulse_width_mask = 0xfffff;
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
}
static const TypeInfo aspeed_2500_wdt_info = {
@@ -336,6 +348,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass,
void *data)
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
}
static const TypeInfo aspeed_2600_wdt_info = {
--
2.20.1
- [PULL 05/34] aspeed: Add a DRAM memory region at the SoC level, (continued)
- [PULL 05/34] aspeed: Add a DRAM memory region at the SoC level, Peter Maydell, 2019/12/16
- [PULL 02/34] exynos4210_gic: Suppress gcc9 format-truncation warnings, Peter Maydell, 2019/12/16
- [PULL 04/34] aspeed/i2c: Check SRAM enablement on AST2500, Peter Maydell, 2019/12/16
- [PULL 03/34] aspeed/i2c: Add support for pool buffer transfers, Peter Maydell, 2019/12/16
- [PULL 06/34] aspeed/i2c: Add support for DMA transfers, Peter Maydell, 2019/12/16
- [PULL 08/34] aspeed/sdmc: Make ast2600 default 1G, Peter Maydell, 2019/12/16
- [PULL 09/34] aspeed/scu: Fix W1C behavior, Peter Maydell, 2019/12/16
- [PULL 07/34] aspeed/i2c: Add trace events, Peter Maydell, 2019/12/16
- [PULL 12/34] aspeed/smc: Restore default AHB window mapping at reset, Peter Maydell, 2019/12/16
- [PULL 10/34] watchdog/aspeed: Improve watchdog timeout message, Peter Maydell, 2019/12/16
- [PULL 11/34] watchdog/aspeed: Fix AST2600 frequency behaviour,
Peter Maydell <=
- [PULL 13/34] aspeed/smc: Do not map disabled segment on the AST2600, Peter Maydell, 2019/12/16
- [PULL 14/34] aspeed/smc: Add AST2600 timings registers, Peter Maydell, 2019/12/16
- [PULL 16/34] aspeed: Add support for the tacoma-bmc board, Peter Maydell, 2019/12/16
- [PULL 15/34] aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass, Peter Maydell, 2019/12/16
- [PULL 17/34] gpio: fix memory leak in aspeed_gpio_init(), Peter Maydell, 2019/12/16
- [PULL 18/34] aspeed: Change the "scu" property definition, Peter Maydell, 2019/12/16
- [PULL 19/34] aspeed: Change the "nic" property definition, Peter Maydell, 2019/12/16
- [PULL 20/34] target/arm: Honor HCR_EL2.TID2 trapping requirements, Peter Maydell, 2019/12/16
- [PULL 21/34] target/arm: Honor HCR_EL2.TID1 trapping requirements, Peter Maydell, 2019/12/16
- [PULL 22/34] target/arm: Handle trapping to EL2 of AArch32 VMRS instructions, Peter Maydell, 2019/12/16