1de310e1eSRex-BC Chen /*
2de310e1eSRex-BC Chen * Copyright (c) 2022, MediaTek Inc. All rights reserved.
3de310e1eSRex-BC Chen *
4de310e1eSRex-BC Chen * SPDX-License-Identifier: BSD-3-Clause
5de310e1eSRex-BC Chen */
6de310e1eSRex-BC Chen
76ca2046eSEdward-JW Yang #include <assert.h>
86ca2046eSEdward-JW Yang #include <plat/common/platform.h>
96ca2046eSEdward-JW Yang #include <lib/pm/mtk_pm.h>
10de310e1eSRex-BC Chen
116ca2046eSEdward-JW Yang #define MTK_PM_ST_SMP_READY BIT(0)
126ca2046eSEdward-JW Yang #define MTK_PM_ST_PWR_READY BIT(1)
136ca2046eSEdward-JW Yang #define MTK_PM_ST_RESET_READY BIT(2)
146ca2046eSEdward-JW Yang
156ca2046eSEdward-JW Yang static uintptr_t mtk_secure_entrypoint;
166ca2046eSEdward-JW Yang static plat_init_func mtk_plat_smp_init;
176ca2046eSEdward-JW Yang static plat_psci_ops_t mtk_pm_ops;
186ca2046eSEdward-JW Yang static unsigned int mtk_pm_status;
196ca2046eSEdward-JW Yang
plat_pm_get_warm_entry(void)206ca2046eSEdward-JW Yang uintptr_t plat_pm_get_warm_entry(void)
216ca2046eSEdward-JW Yang {
226ca2046eSEdward-JW Yang return mtk_secure_entrypoint;
236ca2046eSEdward-JW Yang }
246ca2046eSEdward-JW Yang
plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl * ops)256ca2046eSEdward-JW Yang int plat_pm_ops_setup_pwr(struct plat_pm_pwr_ctrl *ops)
266ca2046eSEdward-JW Yang {
276ca2046eSEdward-JW Yang if (!ops) {
286ca2046eSEdward-JW Yang return MTK_CPUPM_E_FAIL;
296ca2046eSEdward-JW Yang }
306ca2046eSEdward-JW Yang
316ca2046eSEdward-JW Yang #if CONFIG_MTK_CPU_SUSPEND_EN
326ca2046eSEdward-JW Yang if (!mtk_pm_ops.pwr_domain_suspend) {
336ca2046eSEdward-JW Yang mtk_pm_ops.pwr_domain_suspend = ops->pwr_domain_suspend;
346ca2046eSEdward-JW Yang }
356ca2046eSEdward-JW Yang
366ca2046eSEdward-JW Yang if (!mtk_pm_ops.pwr_domain_suspend_finish) {
376ca2046eSEdward-JW Yang mtk_pm_ops.pwr_domain_suspend_finish = ops->pwr_domain_suspend_finish;
386ca2046eSEdward-JW Yang }
396ca2046eSEdward-JW Yang
406ca2046eSEdward-JW Yang if (!mtk_pm_ops.validate_power_state) {
416ca2046eSEdward-JW Yang mtk_pm_ops.validate_power_state = ops->validate_power_state;
426ca2046eSEdward-JW Yang }
436ca2046eSEdward-JW Yang
446ca2046eSEdward-JW Yang if (!mtk_pm_ops.get_sys_suspend_power_state) {
456ca2046eSEdward-JW Yang mtk_pm_ops.get_sys_suspend_power_state = ops->get_sys_suspend_power_state;
466ca2046eSEdward-JW Yang }
476ca2046eSEdward-JW Yang
48*db5fe4f4SBoyan Karatotev if (!mtk_pm_ops.pwr_domain_pwr_down)
49*db5fe4f4SBoyan Karatotev mtk_pm_ops.pwr_domain_pwr_down = ops->pwr_domain_pwr_down_wfi;
505cb0bc07SKai Liang
516ca2046eSEdward-JW Yang mtk_pm_status |= MTK_PM_ST_PWR_READY;
526ca2046eSEdward-JW Yang #endif
536ca2046eSEdward-JW Yang return MTK_CPUPM_E_OK;
546ca2046eSEdward-JW Yang }
556ca2046eSEdward-JW Yang
plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl * ops)566ca2046eSEdward-JW Yang int plat_pm_ops_setup_smp(struct plat_pm_smp_ctrl *ops)
576ca2046eSEdward-JW Yang {
586ca2046eSEdward-JW Yang if (!ops) {
596ca2046eSEdward-JW Yang return MTK_CPUPM_E_FAIL;
606ca2046eSEdward-JW Yang }
616ca2046eSEdward-JW Yang
626ca2046eSEdward-JW Yang #if CONFIG_MTK_SMP_EN
636ca2046eSEdward-JW Yang if (!mtk_pm_ops.pwr_domain_on) {
646ca2046eSEdward-JW Yang mtk_pm_ops.pwr_domain_on = ops->pwr_domain_on;
656ca2046eSEdward-JW Yang }
666ca2046eSEdward-JW Yang
676ca2046eSEdward-JW Yang if (!mtk_pm_ops.pwr_domain_on_finish) {
686ca2046eSEdward-JW Yang mtk_pm_ops.pwr_domain_on_finish = ops->pwr_domain_on_finish;
696ca2046eSEdward-JW Yang }
706ca2046eSEdward-JW Yang
716ca2046eSEdward-JW Yang if (!mtk_pm_ops.pwr_domain_off) {
726ca2046eSEdward-JW Yang mtk_pm_ops.pwr_domain_off = ops->pwr_domain_off;
736ca2046eSEdward-JW Yang }
746ca2046eSEdward-JW Yang
756ca2046eSEdward-JW Yang if (!mtk_plat_smp_init) {
766ca2046eSEdward-JW Yang mtk_plat_smp_init = ops->init;
776ca2046eSEdward-JW Yang }
786ca2046eSEdward-JW Yang
796ca2046eSEdward-JW Yang mtk_pm_status |= MTK_PM_ST_SMP_READY;
806ca2046eSEdward-JW Yang #endif
816ca2046eSEdward-JW Yang return MTK_CPUPM_E_OK;
826ca2046eSEdward-JW Yang }
836ca2046eSEdward-JW Yang
plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl * ops)846ca2046eSEdward-JW Yang int plat_pm_ops_setup_reset(struct plat_pm_reset_ctrl *ops)
856ca2046eSEdward-JW Yang {
866ca2046eSEdward-JW Yang if (!ops) {
876ca2046eSEdward-JW Yang return MTK_CPUPM_E_FAIL;
886ca2046eSEdward-JW Yang }
896ca2046eSEdward-JW Yang
906ca2046eSEdward-JW Yang if (!mtk_pm_ops.system_off) {
916ca2046eSEdward-JW Yang mtk_pm_ops.system_off = ops->system_off;
926ca2046eSEdward-JW Yang }
936ca2046eSEdward-JW Yang
946ca2046eSEdward-JW Yang if (!mtk_pm_ops.system_reset) {
956ca2046eSEdward-JW Yang mtk_pm_ops.system_reset = ops->system_reset;
966ca2046eSEdward-JW Yang }
976ca2046eSEdward-JW Yang
986ca2046eSEdward-JW Yang if (!mtk_pm_ops.system_reset2) {
996ca2046eSEdward-JW Yang mtk_pm_ops.system_reset2 = ops->system_reset2;
1006ca2046eSEdward-JW Yang }
1016ca2046eSEdward-JW Yang
1026ca2046eSEdward-JW Yang mtk_pm_status |= MTK_PM_ST_RESET_READY;
1036ca2046eSEdward-JW Yang
1046ca2046eSEdward-JW Yang return MTK_CPUPM_E_OK;
1056ca2046eSEdward-JW Yang }
106de310e1eSRex-BC Chen
plat_setup_psci_ops(uintptr_t sec_entrypoint,const plat_psci_ops_t ** psci_ops)107de310e1eSRex-BC Chen int plat_setup_psci_ops(uintptr_t sec_entrypoint,
108de310e1eSRex-BC Chen const plat_psci_ops_t **psci_ops)
109de310e1eSRex-BC Chen {
1106ca2046eSEdward-JW Yang *psci_ops = &mtk_pm_ops;
1116ca2046eSEdward-JW Yang mtk_secure_entrypoint = sec_entrypoint;
112de310e1eSRex-BC Chen
1136ca2046eSEdward-JW Yang if (mtk_plat_smp_init) {
1146ca2046eSEdward-JW Yang unsigned int cpu_id = plat_my_core_pos();
1156ca2046eSEdward-JW Yang
1166ca2046eSEdward-JW Yang mtk_plat_smp_init(cpu_id, mtk_secure_entrypoint);
1176ca2046eSEdward-JW Yang }
1186ca2046eSEdward-JW Yang INFO("%s, smp:(%d), pwr_ctrl:(%d), system_reset:(%d)\n", __func__,
1196ca2046eSEdward-JW Yang !!(mtk_pm_status & MTK_PM_ST_SMP_READY),
1206ca2046eSEdward-JW Yang !!(mtk_pm_status & MTK_PM_ST_PWR_READY),
1216ca2046eSEdward-JW Yang !!(mtk_pm_status & MTK_PM_ST_RESET_READY));
122de310e1eSRex-BC Chen return 0;
123de310e1eSRex-BC Chen }
124