From d336e093dd9ec917ce69484eae8914d98efa328d Mon Sep 17 00:00:00 2001 From: Edward-JW Yang Date: Mon, 28 Jun 2021 11:08:10 +0800 Subject: [PATCH] feat(plat/mediatek/mt8195): support MCUSYS off when system suspend Add drivers to support MCUSYS off when system suspend. Signed-off-by: Edward-JW Yang Change-Id: I388fd2318f471083158992464ecdf2181fc7d87a --- .../mediatek/mt8195/aarch64/platform_common.c | 2 + plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c | 31 +++++++- .../mt8195/drivers/mcdi/mt_lp_irqremain.c | 70 +++++++++++++++++++ .../mt8195/drivers/mcdi/mt_lp_irqremain.h | 14 ++++ plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c | 5 +- plat/mediatek/mt8195/include/plat_mtk_lpm.h | 4 +- plat/mediatek/mt8195/include/platform_def.h | 9 +++ plat/mediatek/mt8195/plat_pm.c | 8 +-- plat/mediatek/mt8195/platform.mk | 5 ++ 9 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c create mode 100644 plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.h diff --git a/plat/mediatek/mt8195/aarch64/platform_common.c b/plat/mediatek/mt8195/aarch64/platform_common.c index 4bf6e087d..479274699 100644 --- a/plat/mediatek/mt8195/aarch64/platform_common.c +++ b/plat/mediatek/mt8195/aarch64/platform_common.c @@ -15,6 +15,8 @@ const mmap_region_t plat_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(MTK_DEV_RNG2_BASE, MTK_DEV_RNG2_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(MTK_MCDI_SRAM_BASE, MTK_MCDI_SRAM_MAP_SIZE, + MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(DP_SEC_BASE, DP_SEC_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(eDP_SEC_BASE, eDP_SEC_SIZE, diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c index d6d4af742..5a80d95d5 100644 --- a/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c +++ b/plat/mediatek/mt8195/drivers/mcdi/mt_cpu_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * Copyright (c) 2021, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -73,25 +75,48 @@ static int pwr_mcusys_pwron(unsigned int cpu, const psci_power_state_t *state) static int pwr_mcusys_pwron_finished(unsigned int cpu, const psci_power_state_t *state) { + int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS]; + if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) { return -1; } + mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, cpu, state_id); + mt_lp_irqremain_release(); + return 0; } static int pwr_mcusys_pwrdwn(unsigned int cpu, const psci_power_state_t *state) { + int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS]; + if (!IS_MCUSYS_OFF_STATE(state)) { goto mt_pwr_mcusysoff_break; } - if (mcdi_try_init() != 0) { /* not ready to process mcusys-off */ + if (mcdi_try_init() != 0) { goto mt_pwr_mcusysoff_break; } + if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) { + goto mt_pwr_mcusysoff_break; + } + + plat_mt_lp_cpu_rc = + mt_lp_rm_find_and_run_constraint(0, cpu, state_id, NULL); + + if (plat_mt_lp_cpu_rc < 0) { + goto mt_pwr_mcusysoff_reflect; + } + + mt_lp_irqremain_aquire(); + return 0; +mt_pwr_mcusysoff_reflect: + mtk_cpc_mcusys_off_reflect(); + mt_pwr_mcusysoff_break: plat_mt_lp_cpu_rc = -1; @@ -119,5 +144,7 @@ const struct mt_lpm_tz *mt_plat_cpu_pm_init(void) INFO("MCDI init done.\n"); } + mt_lp_irqremain_init(); + return &plat_pm; } diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c new file mode 100644 index 000000000..4147184f2 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + + +#define KEYPAD_IRQ_ID U(138) + +#define KEYPAD_WAKESRC 0x4 + +static struct mt_irqremain remain_irqs; + +int mt_lp_irqremain_submit(void) +{ + if (remain_irqs.count == 0) { + return -1; + } + + set_wakeup_sources(remain_irqs.irqs, remain_irqs.count); + mt_lp_rm_do_update(-1, PLAT_RC_UPDATE_REMAIN_IRQS, &remain_irqs); + + return 0; +} + +int mt_lp_irqremain_aquire(void) +{ + if (remain_irqs.count == 0) { + return -1; + } + + mt_cirq_sw_reset(); + mt_cirq_clone_gic(); + mt_cirq_enable(); + + return 0; +} + +int mt_lp_irqremain_release(void) +{ + if (remain_irqs.count == 0) { + return -1; + } + + mt_cirq_flush(); + mt_cirq_disable(); + + return 0; +} + +void mt_lp_irqremain_init(void) +{ + uint32_t idx; + + remain_irqs.count = 0; + + /*edge keypad*/ + idx = remain_irqs.count; + remain_irqs.irqs[idx] = KEYPAD_IRQ_ID; + remain_irqs.wakeupsrc_cat[idx] = 0; + remain_irqs.wakeupsrc[idx] = KEYPAD_WAKESRC; + remain_irqs.count++; + + mt_lp_irqremain_submit(); +} diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.h b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.h new file mode 100644 index 000000000..b86e17e24 --- /dev/null +++ b/plat/mediatek/mt8195/drivers/mcdi/mt_lp_irqremain.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_LP_IRQREMAIN_H +#define MT_LP_IRQREMAIN_H + +extern int mt_lp_irqremain_submit(void); +extern int mt_lp_irqremain_aquire(void); +extern int mt_lp_irqremain_release(void); +extern void mt_lp_irqremain_init(void); +#endif /* MT_LP_IRQREMAIN_H */ diff --git a/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c b/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c index df741221d..c14e83b64 100644 --- a/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c +++ b/plat/mediatek/mt8195/drivers/mcdi/mt_mcdi.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * Copyright (c) 2021, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include +#include #include #include @@ -144,5 +145,7 @@ int mcdi_try_init(void) mcdi_init_status = MCDI_INIT_DONE; } + INFO("mcdi ready for mcusys-off-idle and system suspend\n"); + return (mcdi_init_status == MCDI_INIT_DONE) ? 0 : mcdi_init_status; } diff --git a/plat/mediatek/mt8195/include/plat_mtk_lpm.h b/plat/mediatek/mt8195/include/plat_mtk_lpm.h index 8ba8b93a8..347f35855 100644 --- a/plat/mediatek/mt8195/include/plat_mtk_lpm.h +++ b/plat/mediatek/mt8195/include/plat_mtk_lpm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, MediaTek Inc. All rights reserved. + * Copyright (c) 2021, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,7 @@ #include #include -#define MT_IRQ_REMAIN_MAX U(8) +#define MT_IRQ_REMAIN_MAX U(32) #define MT_IRQ_REMAIN_CAT_LOG BIT(31) struct mt_irqremain { diff --git a/plat/mediatek/mt8195/include/platform_def.h b/plat/mediatek/mt8195/include/platform_def.h index a59d54a3a..b84e73f6a 100644 --- a/plat/mediatek/mt8195/include/platform_def.h +++ b/plat/mediatek/mt8195/include/platform_def.h @@ -21,7 +21,16 @@ #define MTK_MCDI_SRAM_BASE 0x11B000 #define MTK_MCDI_SRAM_MAP_SIZE 0x1000 +#define TOPCKGEN_BASE (IO_PHYS + 0x00000000) +#define INFRACFG_AO_BASE (IO_PHYS + 0x00001000) #define SPM_BASE (IO_PHYS + 0x00006000) +#define APMIXEDSYS (IO_PHYS + 0x0000C000) +#define SSPM_MBOX_BASE (IO_PHYS + 0x00480000) +#define PERICFG_AO_BASE (IO_PHYS + 0x01003000) +#define VPPSYS0_BASE (IO_PHYS + 0x04000000) +#define VPPSYS1_BASE (IO_PHYS + 0x04f00000) +#define VDOSYS0_BASE (IO_PHYS + 0x0C01A000) +#define VDOSYS1_BASE (IO_PHYS + 0x0C100000) /******************************************************************************* * DP/eDP related constants diff --git a/plat/mediatek/mt8195/plat_pm.c b/plat/mediatek/mt8195/plat_pm.c index 631bba92e..2beeb0267 100644 --- a/plat/mediatek/mt8195/plat_pm.c +++ b/plat/mediatek/mt8195/plat_pm.c @@ -88,11 +88,6 @@ static void plat_cpu_pwron_common(unsigned int cpu, /* PTP3 config */ ptp3_core_init(cpu); - /* Enable the GIC CPU interface */ - gicv3_rdistif_on(cpu); - gicv3_cpuif_enable(cpu); - mt_gic_rdistif_init(); - /* * If mcusys does power down before then restore * all CPUs' GIC Redistributors @@ -100,6 +95,9 @@ static void plat_cpu_pwron_common(unsigned int cpu, if (IS_MCUSYS_OFF_STATE(state)) { mt_gic_rdistif_restore_all(); } else { + gicv3_rdistif_on(cpu); + gicv3_cpuif_enable(cpu); + mt_gic_rdistif_init(); mt_gic_rdistif_restore(); } } diff --git a/plat/mediatek/mt8195/platform.mk b/plat/mediatek/mt8195/platform.mk index de797c7fc..aa9a28493 100644 --- a/plat/mediatek/mt8195/platform.mk +++ b/plat/mediatek/mt8195/platform.mk @@ -12,6 +12,8 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT}/common/drivers/gpio/ \ -I${MTK_PLAT}/common/drivers/rtc/ \ -I${MTK_PLAT}/common/drivers/timer/ \ + -I${MTK_PLAT}/common/drivers/uart/ \ + -I${MTK_PLAT}/common/lpm/ \ -I${MTK_PLAT_SOC}/drivers/dp/ \ -I${MTK_PLAT_SOC}/drivers/gpio/ \ -I${MTK_PLAT_SOC}/drivers/mcdi/ \ @@ -45,6 +47,8 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \ ${MTK_PLAT}/common/drivers/rtc/rtc_mt6359p.c \ ${MTK_PLAT}/common/drivers/timer/mt_timer.c \ + ${MTK_PLAT}/common/drivers/uart/uart.c \ + ${MTK_PLAT}/common/lpm/mt_lp_rm.c \ ${MTK_PLAT}/common/mtk_cirq.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/mtk_sip_svc.c \ @@ -57,6 +61,7 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm_cpc.c \ ${MTK_PLAT_SOC}/drivers/mcdi/mt_mcdi.c \ + ${MTK_PLAT_SOC}/drivers/mcdi/mt_lp_irqremain.c \ ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \ ${MTK_PLAT_SOC}/drivers/ptp3/mtk_ptp3_main.c \