diff --git a/src/soc/mediatek/common/include/soc/wdt_common.h b/src/soc/mediatek/common/include/soc/wdt_common.h index 6d6d2ba758..02574263ae 100644 --- a/src/soc/mediatek/common/include/soc/wdt_common.h +++ b/src/soc/mediatek/common/include/soc/wdt_common.h @@ -57,5 +57,6 @@ static struct mtk_wdt_regs *const mtk_wdt = (void *)RGU_BASE; int mtk_wdt_init(void); void mtk_wdt_clr_status(void); void mtk_wdt_set_req(void); +void mtk_wdt_clear_efuse_ecc(void); #endif /* SOC_MEDIATEK_WDT_COMMON_H */ diff --git a/src/soc/mediatek/common/wdt.c b/src/soc/mediatek/common/wdt.c index 663fc2fd30..e4038aae02 100644 --- a/src/soc/mediatek/common/wdt.c +++ b/src/soc/mediatek/common/wdt.c @@ -10,6 +10,7 @@ __weak void mtk_wdt_clr_status(void) { /* do nothing */ } __weak void mtk_wdt_set_req(void) { /* do nothing */ } +__weak void mtk_wdt_clear_efuse_ecc(void) { /* do nothing */ } static inline void mtk_wdt_swreset(void) { @@ -36,6 +37,7 @@ int mtk_wdt_init(void) { uint32_t wdt_sta; + mtk_wdt_clear_efuse_ecc(); mtk_wdt_set_req(); /* Writing mode register will clear status register */ diff --git a/src/soc/mediatek/mt8189/Makefile.mk b/src/soc/mediatek/mt8189/Makefile.mk index c870dec5c7..237cbaab0e 100644 --- a/src/soc/mediatek/mt8189/Makefile.mk +++ b/src/soc/mediatek/mt8189/Makefile.mk @@ -10,6 +10,7 @@ all-y += ../common/timer_prepare.c timer.c all-y += ../common/uart.c bootblock-y += bootblock.c +bootblock-y += efuse.c bootblock-y += ../common/mmu_operations.c bootblock-y += ../common/mtcmos.c mtcmos.c bootblock-y += ../common/pll.c pll.c diff --git a/src/soc/mediatek/mt8189/efuse.c b/src/soc/mediatek/mt8189/efuse.c new file mode 100644 index 0000000000..726b5474bf --- /dev/null +++ b/src/soc/mediatek/mt8189/efuse.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include + +#define MTK_EFUSE_ECC_ERROR_BIT BIT(7) + +bool mtk_efuse_ecc_has_error(void) +{ + return !!(read32(&mtk_efuse->ecc_status_reg) & MTK_EFUSE_ECC_ERROR_BIT); +} diff --git a/src/soc/mediatek/mt8189/include/soc/addressmap.h b/src/soc/mediatek/mt8189/include/soc/addressmap.h index 0f257cc543..3f6fe3e598 100644 --- a/src/soc/mediatek/mt8189/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8189/include/soc/addressmap.h @@ -91,6 +91,7 @@ enum { IMP_IIC_WRAP_S_BASE = IO_PHYS + 0x01D74000, IOCFG_LT0_BASE = IO_PHYS + 0x01E20000, IOCFG_LT1_BASE = IO_PHYS + 0x01E30000, + EFUSEC_BASE = IO_PHYS + 0x01F10000, IOCFG_RT_BASE = IO_PHYS + 0x01F20000, IMP_IIC_WRAP_EN_BASE = IO_PHYS + 0x01F32000, MFGCFG_BASE = IO_PHYS + 0x03FBF000, diff --git a/src/soc/mediatek/mt8189/include/soc/efuse.h b/src/soc/mediatek/mt8189/include/soc/efuse.h index 031dd5ef78..2d872d46b5 100644 --- a/src/soc/mediatek/mt8189/include/soc/efuse.h +++ b/src/soc/mediatek/mt8189/include/soc/efuse.h @@ -11,10 +11,15 @@ struct efuse_regs { u32 cpu_id_reg; u32 reserved2[15]; u32 cpu_seg_id_reg; + u32 reserved3[14908]; + u32 ecc_status_reg; }; check_member(efuse_regs, cpu_id_reg, 0x7A0); check_member(efuse_regs, cpu_seg_id_reg, 0x7E0); +check_member(efuse_regs, ecc_status_reg, 0xF0D4); static struct efuse_regs *const mtk_efuse = (void *)EFUSEC_BASE; +bool mtk_efuse_ecc_has_error(void); + #endif /*__SOC_MEDIATEK_MT8189_INCLUDE_SOC_EFUSE_H__*/ diff --git a/src/soc/mediatek/mt8189/wdt.c b/src/soc/mediatek/mt8189/wdt.c index ca6518bc2e..ba991d2e96 100644 --- a/src/soc/mediatek/mt8189/wdt.c +++ b/src/soc/mediatek/mt8189/wdt.c @@ -7,11 +7,21 @@ #include #include +#include #include -#define MTK_WDT_CLR_STATUS 0x230001FF +#define MTK_WDT_CLR_STATUS 0x230001FF +#define MTK_WDT_CLR_EFUSE_ECC_ERR 0x2300000A +#define MTK_WDT_STA_EFUSE_ECC_ERR BIT(23) void mtk_wdt_clr_status(void) { write32(&mtk_wdt->wdt_mode, MTK_WDT_CLR_STATUS); } + +void mtk_wdt_clear_efuse_ecc(void) +{ + if ((read32(&mtk_wdt->wdt_status) & MTK_WDT_STA_EFUSE_ECC_ERR) && + !mtk_efuse_ecc_has_error()) + write32(&mtk_wdt->wdt_mode, MTK_WDT_CLR_EFUSE_ECC_ERR); +}