blob: d7f04387564bda4455962ce3be6046d0a75244a2 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#include "sw/device/silicon_creator/lib/drivers/watchdog.h"
#include "sw/device/silicon_creator/lib/base/abs_mmio.h"
#include "aon_timer_regs.h"
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
#include "pwrmgr_regs.h"
enum {
kBase = TOP_EARLGREY_AON_TIMER_AON_BASE_ADDR,
kPwrMgrBase = TOP_EARLGREY_PWRMGR_AON_BASE_ADDR,
// The AON domain is always clocked at 200 Hz.
// TODO(lowRISC/opentitan#7385): update this after the AON frequency is
// formally defined in the project.
kAonTimerRate = 200000,
};
void watchdog_init(uint32_t timeout_ms) {
// Tell pwrmgr we want watchdog reset events to reset the chip.
abs_mmio_write32(
kPwrMgrBase + PWRMGR_RESET_EN_REG_OFFSET,
bitfield_bit32_write(
0, kTopEarlgreyPowerManagerResetRequestsAonTimerAonAonTimerRstReq,
true));
abs_mmio_write32(kPwrMgrBase + PWRMGR_CFG_CDC_SYNC_REG_OFFSET, 1);
// Disable the watchdog before reconfiguring it.
abs_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, 0);
abs_mmio_write32(kBase + AON_TIMER_WKUP_CTRL_REG_OFFSET, 0);
// Configure the watchdog to bite at the requested timeout.
abs_mmio_write32(kBase + AON_TIMER_WKUP_COUNT_REG_OFFSET, 0);
abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
abs_mmio_write32(kBase + AON_TIMER_WKUP_THOLD_REG_OFFSET, UINT32_MAX);
abs_mmio_write32(kBase + AON_TIMER_WDOG_BARK_THOLD_REG_OFFSET, UINT32_MAX);
abs_mmio_write32(kBase + AON_TIMER_WDOG_BITE_THOLD_REG_OFFSET,
timeout_ms * (kAonTimerRate / 1000));
if (timeout_ms) {
abs_mmio_write32(kBase + AON_TIMER_WDOG_CTRL_REG_OFFSET, 1);
}
}
void watchdog_pet(void) {
abs_mmio_write32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET, 0);
}
uint32_t watchdog_get(void) {
return abs_mmio_read32(kBase + AON_TIMER_WDOG_COUNT_REG_OFFSET);
}