blob: 8c012e7519cbfedc9f92119eee53a47a3e3b9461 [file] [log] [blame]
developerba7b7d22021-11-14 10:14:45 +08001/*
2 * Copyright (c) 2021, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8#include <stdint.h>
9
10#include <arch_helpers.h>
11#include <lib/psci/psci.h>
12#include <lib/spinlock.h>
13
14#include <mt_cpu_pm_cpc.h>
jason-ch chenfa82b9b2021-11-16 09:48:20 +080015#include <mt_lp_irqremain.h>
16#include <mt_lp_rm.h>
developerba7b7d22021-11-14 10:14:45 +080017#include <mt_mcdi.h>
18#include <plat_mtk_lpm.h>
19#include <plat_pm.h>
20
21DEFINE_SYSREG_RW_FUNCS(dbgprcr_el1);
22
23static int plat_mt_lp_cpu_rc;
24
25static int pwr_state_prompt(unsigned int cpu, const psci_power_state_t *state)
26{
27 return 0;
28}
29
30static int pwr_state_reflect(unsigned int cpu, const psci_power_state_t *state)
31{
32 mtk_cpc_core_on_hint_clr(cpu);
33
34 if (IS_SYSTEM_SUSPEND_STATE(state)) {
35 mtk_cpc_time_sync();
36 }
37
38 return 0;
39}
40
41static int pwr_cpu_pwron(unsigned int cpu, const psci_power_state_t *state)
42{
43 return 0;
44}
45
46static int pwr_cpu_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
47{
48 /* clear DBGPRCR.CORENPDRQ to allow CPU power down */
49 write_dbgprcr_el1(0ULL);
50
51 return 0;
52}
53
54static int pwr_cluster_pwron(unsigned int cpu, const psci_power_state_t *state)
55{
56 return 0;
57}
58
59static int pwr_cluster_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
60{
61 return 0;
62}
63
64static int pwr_mcusys_pwron(unsigned int cpu, const psci_power_state_t *state)
65{
66 if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) {
67 return -1;
68 }
69
70 mtk_cpc_mcusys_off_reflect();
71
72 return 0;
73}
74
75static int pwr_mcusys_pwron_finished(unsigned int cpu,
76 const psci_power_state_t *state)
77{
jason-ch chenfa82b9b2021-11-16 09:48:20 +080078 int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS];
79
developerba7b7d22021-11-14 10:14:45 +080080 if (!IS_MCUSYS_OFF_STATE(state) || (plat_mt_lp_cpu_rc < 0)) {
81 return -1;
82 }
83
jason-ch chenfa82b9b2021-11-16 09:48:20 +080084 mt_lp_rm_reset_constraint(plat_mt_lp_cpu_rc, cpu, state_id);
85 mt_lp_irqremain_release();
86
developerba7b7d22021-11-14 10:14:45 +080087 return 0;
88}
89
90static int pwr_mcusys_pwrdwn(unsigned int cpu, const psci_power_state_t *state)
91{
jason-ch chenfa82b9b2021-11-16 09:48:20 +080092 int state_id = state->pwr_domain_state[MTK_AFFLVL_MCUSYS];
93
developerba7b7d22021-11-14 10:14:45 +080094 if (!IS_MCUSYS_OFF_STATE(state)) {
95 goto mt_pwr_mcusysoff_break;
96 }
97
98 if (mcdi_try_init() != 0) { /* not ready to process mcusys-off */
99 goto mt_pwr_mcusysoff_break;
100 }
101
jason-ch chenfa82b9b2021-11-16 09:48:20 +0800102 if (mtk_cpc_mcusys_off_prepare() != CPC_SUCCESS) {
103 goto mt_pwr_mcusysoff_break;
104 }
105
106 plat_mt_lp_cpu_rc =
107 mt_lp_rm_find_and_run_constraint(0, cpu, state_id, NULL);
108
109 if (plat_mt_lp_cpu_rc < 0) {
110 goto mt_pwr_mcusysoff_reflect;
111 }
112
113 mt_lp_irqremain_aquire();
114
developerba7b7d22021-11-14 10:14:45 +0800115 return 0;
116
jason-ch chenfa82b9b2021-11-16 09:48:20 +0800117mt_pwr_mcusysoff_reflect:
118 mtk_cpc_mcusys_off_reflect();
developerba7b7d22021-11-14 10:14:45 +0800119
jason-ch chenfa82b9b2021-11-16 09:48:20 +0800120mt_pwr_mcusysoff_break:
developerba7b7d22021-11-14 10:14:45 +0800121 plat_mt_lp_cpu_rc = -1;
122
123 return -1;
124}
125
126static const struct mt_lpm_tz plat_pm = {
127 .pwr_prompt = pwr_state_prompt,
128 .pwr_reflect = pwr_state_reflect,
129 .pwr_cpu_on = pwr_cpu_pwron,
130 .pwr_cpu_dwn = pwr_cpu_pwrdwn,
131 .pwr_cluster_on = pwr_cluster_pwron,
132 .pwr_cluster_dwn = pwr_cluster_pwrdwn,
133 .pwr_mcusys_dwn = pwr_mcusys_pwrdwn,
134 .pwr_mcusys_on = pwr_mcusys_pwron,
135 .pwr_mcusys_on_finished = pwr_mcusys_pwron_finished
136};
137
138const struct mt_lpm_tz *mt_plat_cpu_pm_init(void)
139{
140 mtk_cpc_init();
141
142 if (mcdi_try_init() == 0) {
143 INFO("MCDI init done.\n");
144 }
145
jason-ch chenfa82b9b2021-11-16 09:48:20 +0800146 mt_lp_irqremain_init();
147
developerba7b7d22021-11-14 10:14:45 +0800148 return &plat_pm;
149}