soc/mediatek/mt8189: Check eFuse ECC in WDT init
When the number of eFuse reads exceeds a certain limit (with a maximum of 20 million), a bit flip from 1 to 0 may happen. When that happens, the bit flip will be automatically corrected by the eFuse hardware via ECC (Error Correction Code), and the EFUSE_ECC_ERR register bit will be set for the software to decide how to handle that. Therefore, this patch adds a check for the EFUSE_ECC_ERR register bit. If it's set due to a bit flip instead of a real error, we simply clear it to avoid triggering a WDT reset. BUG=b:379008996 BRANCH=none TEST=build passed and check the WDT status debug log. This log is added in local for test only. [INFO ] mtk_wdt_clear_efuse_ecc: wdt_sta = 0x0 Signed-off-by: Zexin Wang <ot_zexin.wang@mediatek.corp-partner.google.com> Change-Id: Idd2763688c7ab6992a7c185e9e52b60bda88c94c Reviewed-on: https://review.coreboot.org/c/coreboot/+/87744 Reviewed-by: Yu-Ping Wu <yupingso@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yidi Lin <yidilin@google.com>
This commit is contained in:
parent
a89406790a
commit
2bec5a9d9a
7 changed files with 33 additions and 1 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
12
src/soc/mediatek/mt8189/efuse.c
Normal file
12
src/soc/mediatek/mt8189/efuse.c
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
|
||||
|
||||
#include <device/mmio.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/efuse.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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__*/
|
||||
|
|
|
|||
|
|
@ -7,11 +7,21 @@
|
|||
|
||||
#include <device/mmio.h>
|
||||
#include <soc/addressmap.h>
|
||||
#include <soc/efuse.h>
|
||||
#include <soc/wdt.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue