2025-10-10 16:07:00 +08:00

173 lines
4.9 KiB
C

// Copyright 2020-2021 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "wdt_hal.h"
#include "wdt_ll.h"
#include "aon_pmu_driver.h"
#include "reset_reason.h"
static inline void wdt_hal_close_unused(wdt_unit_t id);
bk_err_t wdt_hal_init(wdt_hal_t *hal)
{
#if (CONFIG_SOC_BK7256XX)
#if CONFIG_DEBUG_FIRMWARE || CONFIG_NMI_WDT_EN
hal->id = NMI_WDT_ID; //debug version use nmi_wdt to dump
#else
if (aon_pmu_hal_is_chipid_later_than_version_C())
hal->id = AON_WDT_ID; //chip version C -> aon_wdt
else
hal->id = NMI_WDT_ID; //chip version A -> nmi_wdt
#endif
#endif
#if (CONFIG_SOC_BK7236XX)
#if CONFIG_DEBUG_FIRMWARE || CONFIG_NMI_WDT_EN
hal->id = NMI_WDT_ID; //debug version use nmi_wdt to dump
#else
hal->id = AON_WDT_ID; //debug version use aon_wdt
#endif
#endif
wdt_hal_close_unused(hal->id);
hal->hw = (wdt_hw_t *)WDT_LL_REG_BASE(hal->id);
wdt_ll_init(hal->hw);
return BK_OK;
}
__IRAM_SEC bk_err_t wdt_hal_init_wdt(wdt_hal_t *hal, uint32_t timeout)
{
wdt_ll_set_period(hal->hw, timeout);
return BK_OK;
}
#if (CONFIG_SOC_BK7256XX)
void wdt_hal_close(void)
{
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA50000);
REG_WRITE(SOC_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_WDT_REG_BASE, 0xA50000);
}
void wdt_hal_force_feed(void)
{
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5AFFFC);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA5FFFC);
REG_WRITE(SOC_WDT_REG_BASE, 0x5AFFF0);
REG_WRITE(SOC_WDT_REG_BASE, 0xA5FFF0);
}
static inline void wdt_hal_close_unused(wdt_unit_t id)
{
if (id == AON_WDT_ID) {
// use aon_wdt, close nmi_wdt
REG_WRITE(SOC_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_WDT_REG_BASE, 0xA50000);
} else {
// use nmi_wdt, close aon_wdt
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA50000);
}
}
static inline void wdt_hal_nmi_reboot() {
set_reboot_tag(REBOOT_TAG_REQ);
set_nmi_vector();
aon_pmu_drv_wdt_change_not_rosc_clk();
aon_pmu_drv_wdt_rst_dev_enable();
REG_WRITE(SOC_WDT_REG_BASE, 0x5A000A);
REG_WRITE(SOC_WDT_REG_BASE, 0xA5000A);
}
void wdt_hal_force_reboot(void)
{
#if CONFIG_DEBUG_FIRMWARE || CONFIG_NMI_WDT_EN
wdt_hal_nmi_reboot();
#else
if (aon_pmu_hal_is_chipid_later_than_version_C())
{
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A000A);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA5000A);
} else {
wdt_hal_nmi_reboot();
}
#endif //#if CONFIG_DEBUG_FIRMWARE
}
#endif
#if (CONFIG_SOC_BK7236XX) || (CONFIG_SOC_BK7239XX) || (CONFIG_SOC_BK7286XX)
__attribute__((section(".itcm_sec_code"))) void wdt_hal_close(void)
{
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA50000);
REG_SET(SOC_WDT_REG_BASE + 4 * 2, 1, 1, 1);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0x5A0000);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0xA50000);
}
void wdt_hal_force_feed(void)
{
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5AFFFC);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA5FFFC);
REG_SET(SOC_WDT_REG_BASE + 4 * 2, 1, 1, 1);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0x5AFFF0);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0xA5FFF0);
}
static inline void wdt_hal_close_unused(wdt_unit_t id)
{
if (id == AON_WDT_ID) {
// use aon_wdt, close nmi_wdt
REG_SET(SOC_WDT_REG_BASE + 4 * 2, 1, 1, 1);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0x5A0000);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0xA50000);
} else {
// use nmi_wdt, close aon_wdt
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A0000);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA50000);
}
}
static inline void wdt_hal_nmi_reboot() {
set_reboot_tag(REBOOT_TAG_REQ);
aon_pmu_drv_wdt_change_not_rosc_clk();
aon_pmu_drv_wdt_rst_dev_enable();
REG_SET(SOC_WDT_REG_BASE + 4 * 2, 1, 1, 1);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0x5A000A);
REG_WRITE(SOC_WDT_REG_BASE + 4 * 4, 0xA5000A);
}
void wdt_hal_force_reboot(void)
{
//disable AON WDT as the ROSC 32K need to be disabled
#if CONFIG_DEBUG_FIRMWARE || CONFIG_NMI_WDT_EN
wdt_hal_nmi_reboot();
#else
REG_WRITE(SOC_AON_WDT_REG_BASE, 0x5A000A);
REG_WRITE(SOC_AON_WDT_REG_BASE, 0xA5000A);
#endif
}
#endif