Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83928?usp=email )
Change subject: soc/mediatek/mt8196: Fix timer reset in BL31 ......................................................................
soc/mediatek/mt8196: Fix timer reset in BL31
After reboot, the system does not need to serve pending IRQ from systimer. Therefore, clear systimer IRQ pending bits in init_timer(). For that to work, the systimer compensation version 2.0 needs to be enabled.
TEST=Build pass and timestamp is not reset in ATF and payload BUG=b:343881008
Change-Id: I520986b81ca153ec3ce56558a80619448cfc0c59 Signed-off-by: Zhanzhan Ge zhanzhan.ge@mediatek.corp-partner.google.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/83928 Reviewed-by: Yidi Lin yidilin@google.com Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Yu-Ping Wu yupingso@google.com --- M src/soc/mediatek/mt8196/Makefile.mk M src/soc/mediatek/mt8196/include/soc/timer.h M src/soc/mediatek/mt8196/timer.c A src/soc/mediatek/mt8196/timer_prepare.c 4 files changed, 72 insertions(+), 3 deletions(-)
Approvals: build bot (Jenkins): Verified Yidi Lin: Looks good to me, approved Yu-Ping Wu: Looks good to me, approved
diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index b11778f..388dad1 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -6,7 +6,7 @@ all-y += ../common/gpio.c ../common/gpio_op.c gpio.c gpio_eint.c all-y += ../common/i2c.c i2c.c all-$(CONFIG_SPI_FLASH) += spi.c -all-y += timer.c +all-y += timer.c timer_prepare.c all-y += ../common/uart.c
bootblock-y += bootblock.c diff --git a/src/soc/mediatek/mt8196/include/soc/timer.h b/src/soc/mediatek/mt8196/include/soc/timer.h index d6422c5..f6841fc 100644 --- a/src/soc/mediatek/mt8196/include/soc/timer.h +++ b/src/soc/mediatek/mt8196/include/soc/timer.h @@ -2,12 +2,44 @@
/* * This file is created based on MT8196 Functional Specification - * Chapter number: 5.13 + * Chapter number: 1.2 2.2 */
#ifndef SOC_MEDIATEK_MT8196_TIMER_H #define SOC_MEDIATEK_MT8196_TIMER_H
#include <soc/timer_v2.h> +#include <stdint.h> + +DEFINE_BITFIELD(COMP_FEATURE, 12, 10) +DEFINE_BITFIELD(COMP_FEATURE_TIE, 4, 3) +DEFINE_BITFIELD(REV_SET, 18, 17) +DEFINE_BITFIELD(SYST_CON, 4, 0) + +#define SYST_CON_EN BIT(0) +#define SYST_CON_IRQ_CLR BIT(4) +#define REV_CLR_EN 0x3 +#define COMP_FEATURE_20_EN 0x2 +#define COMP_FEATURE_TIE_EN 0x1 +#define COMP_FEATURE_CLR 0 +#define COMP_FEATURE_TIE_CLR 0 +#define SYSTIMER_CNT 8 +#define SYST_CON_CLR 0 + +struct systimer { + u32 cntcr; + u32 reserved; + u32 cntcv_l; + u32 cntcv_h; + u32 reserved1[0x30]; + struct { + u32 con; + u32 val; + } cnttval[SYSTIMER_CNT]; +}; + +check_member(systimer, cntcr, 0x0); +check_member(systimer, cntcv_l, 0x0008); +check_member(systimer, cntcv_h, 0x000c);
#endif diff --git a/src/soc/mediatek/mt8196/timer.c b/src/soc/mediatek/mt8196/timer.c index 9d8dd7a..bf3f3ce 100644 --- a/src/soc/mediatek/mt8196/timer.c +++ b/src/soc/mediatek/mt8196/timer.c @@ -3,8 +3,11 @@ #include <arch/lib_helpers.h> #include <commonlib/helpers.h> #include <delay.h> +#include <soc/timer.h>
void init_timer(void) { - raw_write_cntfrq_el0(13 * MHz); + timer_prepare(); + + raw_write_cntfrq_el0(GPT_MHZ * MHz); } diff --git a/src/soc/mediatek/mt8196/timer_prepare.c b/src/soc/mediatek/mt8196/timer_prepare.c new file mode 100644 index 0000000..08496e8 --- /dev/null +++ b/src/soc/mediatek/mt8196/timer_prepare.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is created based on MT8196 Functional Specification + * Chapter number: 1.2 2.2 + */ + +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/timer.h> + +static void clear_systimer(struct systimer *const mtk_systimer) +{ + unsigned int id = 0; + + for (id = 0; id < SYSTIMER_CNT; id++) { + u32 *cnttval_con = &mtk_systimer->cnttval[id].con; + WRITE32_BITFIELDS(cnttval_con, SYST_CON, SYST_CON_EN); + SET32_BITFIELDS(cnttval_con, SYST_CON, SYST_CON_IRQ_CLR); + WRITE32_BITFIELDS(cnttval_con, SYST_CON, SYST_CON_CLR); + } + + SET32_BITFIELDS(&mtk_systimer->cntcr, REV_SET, REV_CLR_EN); +} + +void timer_prepare(void) +{ + struct systimer *mtk_systimer = (void *)SYSTIMER_BASE; + + SET32_BITFIELDS(&mtk_systimer->cntcr, + COMP_FEATURE, COMP_FEATURE_CLR | COMP_FEATURE_20_EN, + COMP_FEATURE_TIE, COMP_FEATURE_TIE_CLR | COMP_FEATURE_TIE_EN); + clear_systimer(mtk_systimer); +}