From 0307f52cd9a907fd15d70311abee3f79eb2bf5bc Mon Sep 17 00:00:00 2001 From: mtk17664 Date: Mon, 14 Apr 2025 09:10:32 +0800 Subject: [PATCH] soc/mediatek/mt8196: Move SPM loader functions to common part To promote code reuse and maintainability, move SPM loader functions to common/spm_v2.c. BUG=b:379008996 BRANCH=none TEST=build passed Signed-off-by: Kun Lu Change-Id: I20de8662d17e3dbedd84f267f2be7d5d62356ecd Reviewed-on: https://review.coreboot.org/c/coreboot/+/87340 Reviewed-by: Yidi Lin Reviewed-by: Yu-Ping Wu Tested-by: build bot (Jenkins) --- src/soc/mediatek/common/spm_v2.c | 86 +++++++++++++++++++++++++++++ src/soc/mediatek/mt8196/Makefile.mk | 2 +- src/soc/mediatek/mt8196/spm.c | 81 --------------------------- 3 files changed, 87 insertions(+), 82 deletions(-) create mode 100644 src/soc/mediatek/common/spm_v2.c diff --git a/src/soc/mediatek/common/spm_v2.c b/src/soc/mediatek/common/spm_v2.c new file mode 100644 index 0000000000..b101ab0b14 --- /dev/null +++ b/src/soc/mediatek/common/spm_v2.c @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#include +#include +#include + +void spm_reset_and_init_pcm(void) +{ + /* disable r0 and r7 to control power */ + write32(&mtk_spm->pcm_pwr_io_en, 0); + + /* disable pcm timer after leaving FW */ + clrsetbits32(&mtk_spm->pcm_con1, + REG_PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY); + + /* reset PCM */ + write32(&mtk_spm->pcm_con0, + SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB | PCM_SW_RESET_LSB); + write32(&mtk_spm->pcm_con0, SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); + + /* init PCM_CON1 (disable PCM timer but keep PCM WDT setting) */ + clrsetbits32(&mtk_spm->pcm_con1, ~REG_PCM_WDT_WAKE_LSB, + SPM_REGWR_CFG_KEY | REG_SPM_APB_INTERNAL_EN_LSB | + REG_SSPM_APB_P2P_EN_LSB); +} + +void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) +{ + u32 val, mask; + + /* toggle event counter clear */ + write32(&mtk_spm->spm_event_counter_clear, REG_SPM_EVENT_COUNTER_CLR_LSB); + /* toggle for reset SYS TIMER start point */ + setbits32(&mtk_spm->sys_timer_con, SYS_TIMER_START_EN_LSB); + + if (pwrctrl->timer_val_cust == 0) + val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_SUSPEND; + else + val = pwrctrl->timer_val_cust; + + write32(&mtk_spm->pcm_timer_val, val); + setbits32(&mtk_spm->pcm_con1, SPM_REGWR_CFG_KEY | REG_PCM_TIMER_EN_LSB); + + /* unmask AP wakeup source */ + if (pwrctrl->wake_src_cust == 0) + mask = pwrctrl->wake_src; + else + mask = pwrctrl->wake_src_cust; + + if (pwrctrl->reg_csyspwrup_ack_mask) + mask &= ~R12_CSYSPWREQ_B; + write32(&mtk_spm->spm_wakeup_event_mask, ~mask); + + /* unmask SPM ISR (keep TWAM setting) */ + setbits32(&mtk_spm->spm_irq_mask, ISRM_RET_IRQ_AUX); + + /* toggle event counter clear */ + write32(&mtk_spm->spm_event_counter_clear, 0); + /* toggle for reset SYS TIMER start point */ + clrbits32(&mtk_spm->sys_timer_con, SYS_TIMER_START_EN_LSB); +} + +void spm_init_pcm_register(void) +{ + write32(&mtk_spm->pcm_pwr_io_en, 0); +} + +void spm_kick_pcm_to_run(const struct pwr_ctrl *pwrctrl) +{ + /* Waiting for loading SPMFW done*/ + while (read32(&mtk_spm->md32pcm_dma0_rlct) != 0x0) + ; + + /* In the new SOC design, this part has been simplified */ + spm_set_pcm_flags(pwrctrl); + + /* Kick PCM to run (only toggle PCM_KICK) */ + setbits32(&mtk_spm->pcm_con0, SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); + + /* Reset md32pcm */ + SET32_BITFIELDS(&mtk_spm->md32pcm_cfgreg_sw_rstn, + MD32PCM_CFGREG_SW_RSTN_RESET, 1); + + /* Waiting for SPM init done */ + udelay(SPM_INIT_DONE_US); +} diff --git a/src/soc/mediatek/mt8196/Makefile.mk b/src/soc/mediatek/mt8196/Makefile.mk index 93be1b434b..4a2fdcc970 100644 --- a/src/soc/mediatek/mt8196/Makefile.mk +++ b/src/soc/mediatek/mt8196/Makefile.mk @@ -79,7 +79,7 @@ ramstage-y += mtcmos.c ramstage-y += ../common/mtk_fsp.c ramstage-y += pi_image.c ramstage-y += soc.c -ramstage-y += ../common/spm.c spm.c +ramstage-y += ../common/spm.c ../common/spm_v2.c spm.c ramstage-y += ../common/sspm.c sspm_sram.c ramstage-y += ../common/pmif_clk.c pmif_clk.c ramstage-y += ../common/pmif.c pmif_init.c diff --git a/src/soc/mediatek/mt8196/spm.c b/src/soc/mediatek/mt8196/spm.c index 66964fb866..f6319069b9 100644 --- a/src/soc/mediatek/mt8196/spm.c +++ b/src/soc/mediatek/mt8196/spm.c @@ -836,87 +836,6 @@ void spm_register_init(void) spm_set_power_control(&spm_init_ctrl); } -void spm_reset_and_init_pcm(void) -{ - /* disable r0 and r7 to control power */ - write32(&mtk_spm->pcm_pwr_io_en, 0); - - /* disable pcm timer after leaving FW */ - clrsetbits32(&mtk_spm->pcm_con1, - REG_PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY); - - /* reset PCM */ - write32(&mtk_spm->pcm_con0, - SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB | PCM_SW_RESET_LSB); - write32(&mtk_spm->pcm_con0, SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); - - /* init PCM_CON1 (disable PCM timer but keep PCM WDT setting) */ - clrsetbits32(&mtk_spm->pcm_con1, ~REG_PCM_WDT_WAKE_LSB, - SPM_REGWR_CFG_KEY | REG_SPM_APB_INTERNAL_EN_LSB | - REG_SSPM_APB_P2P_EN_LSB); -} - -void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) -{ - u32 val, mask; - - /* toggle event counter clear */ - write32(&mtk_spm->spm_event_counter_clear, REG_SPM_EVENT_COUNTER_CLR_LSB); - /* toggle for reset SYS TIMER start point */ - setbits32(&mtk_spm->sys_timer_con, SYS_TIMER_START_EN_LSB); - - if (pwrctrl->timer_val_cust == 0) - val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_SUSPEND; - else - val = pwrctrl->timer_val_cust; - - write32(&mtk_spm->pcm_timer_val, val); - setbits32(&mtk_spm->pcm_con1, SPM_REGWR_CFG_KEY | REG_PCM_TIMER_EN_LSB); - - /* unmask AP wakeup source */ - if (pwrctrl->wake_src_cust == 0) - mask = pwrctrl->wake_src; - else - mask = pwrctrl->wake_src_cust; - - if (pwrctrl->reg_csyspwrup_ack_mask) - mask &= ~R12_CSYSPWREQ_B; - write32(&mtk_spm->spm_wakeup_event_mask, ~mask); - - /* unmask SPM ISR (keep TWAM setting) */ - setbits32(&mtk_spm->spm_irq_mask, ISRM_RET_IRQ_AUX); - - /* toggle event counter clear */ - write32(&mtk_spm->spm_event_counter_clear, 0); - /* toggle for reset SYS TIMER start point */ - clrbits32(&mtk_spm->sys_timer_con, SYS_TIMER_START_EN_LSB); -} - -void spm_init_pcm_register(void) -{ - write32(&mtk_spm->pcm_pwr_io_en, 0); -} - -void spm_kick_pcm_to_run(const struct pwr_ctrl *pwrctrl) -{ - /* Waiting for loading SPMFW done*/ - while (read32(&mtk_spm->md32pcm_dma0_rlct) != 0x0) - ; - - /* In the new SOC design, this part has been simplified */ - spm_set_pcm_flags(pwrctrl); - - /* Kick PCM to run (only toggle PCM_KICK) */ - setbits32(&mtk_spm->pcm_con0, SPM_REGWR_CFG_KEY | PCM_CK_EN_LSB); - - /* Reset md32pcm */ - SET32_BITFIELDS(&mtk_spm->md32pcm_cfgreg_sw_rstn, - MD32PCM_CFGREG_SW_RSTN_RESET, 1); - - /* Waiting for SPM init done */ - udelay(SPM_INIT_DONE_US); -} - const struct pwr_ctrl *get_pwr_ctrl(void) { return &spm_init_ctrl;