1 /*
2  * Copyright (c) 2022, MediaTek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stddef.h>
8 #include <string.h>
9 #include <common/debug.h>
10 #include <lib/bakery_lock.h>
11 #include <lib/mmio.h>
12 #include <mt_lp_rm.h>
13 #include <mt_spm.h>
14 #include <mt_spm_cond.h>
15 #include <mt_spm_conservation.h>
16 #include <mt_spm_constraint.h>
17 #include "mt_spm_extern.h"
18 #include <mt_spm_idle.h>
19 #include <mt_spm_internal.h>
20 #include <mt_spm_pmic_wrap.h>
21 #include <mt_spm_rc_internal.h>
22 #include <mt_spm_reg.h>
23 #include <mt_spm_resource_req.h>
24 #include <mt_spm_suspend.h>
25 #include <mtk_plat_common.h>
26 #include <plat_mtk_lpm.h>
27 #include <plat_pm.h>
28 #include <platform_def.h>
29 #include <sleep_def.h>
30 
31 #ifdef MT_SPM_USING_BAKERY_LOCK
32 DEFINE_BAKERY_LOCK(spm_lock);
33 #define plat_spm_lock_init() bakery_lock_init(&spm_lock)
34 #else
35 spinlock_t spm_lock;
36 #define plat_spm_lock_init()
37 #endif
38 
39 /* CLK_SCP_CFG_0 */
40 #define CLK_SCP_CFG_0		(TOPCKGEN_BASE + 0x200)
41 #define SPM_CK_CONTROL_EN	(0x3FF)
42 
43 /* CLK_SCP_CFG_1 */
44 #define CLK_SCP_CFG_1		(TOPCKGEN_BASE + 0x210)
45 #define CLK_SCP_CFG_1_MASK	(0x100C)
46 #define CLK_SCP_CFG_1_SPM	(0x3)
47 
48 #define MT_SPM_EX_OP_TIME_CHECK	BIT(10)
49 
50 struct mt_resource_constraint plat_constraint_bus26m = {
51 	.is_valid = spm_is_valid_rc_bus26m,
52 	.update = spm_update_rc_bus26m,
53 	.allow = spm_allow_rc_bus26m,
54 	.run = spm_run_rc_bus26m,
55 	.reset = spm_reset_rc_bus26m,
56 };
57 
58 struct mt_resource_constraint plat_constraint_syspll = {
59 	.is_valid = spm_is_valid_rc_syspll,
60 	.update = spm_update_rc_syspll,
61 	.allow = spm_allow_rc_syspll,
62 	.run = spm_run_rc_syspll,
63 	.reset = spm_reset_rc_syspll,
64 };
65 
66 struct mt_resource_constraint plat_constraint_dram = {
67 	.is_valid = spm_is_valid_rc_dram,
68 	.update = spm_update_rc_dram,
69 	.allow = spm_allow_rc_dram,
70 	.run = spm_run_rc_dram,
71 	.reset = spm_reset_rc_dram,
72 };
73 
74 /* Maybe remove when the spm won't cpu power control aymore */
75 struct mt_resource_constraint plat_constraint_cpu = {
76 	.is_valid = spm_is_valid_rc_cpu_buck_ldo,
77 	.update = NULL,
78 	.allow = spm_allow_rc_cpu_buck_ldo,
79 	.run = spm_run_rc_cpu_buck_ldo,
80 	.reset = spm_reset_rc_cpu_buck_ldo,
81 };
82 
83 struct mt_resource_constraint *plat_constraints[] = {
84 	&plat_constraint_bus26m,
85 	&plat_constraint_syspll,
86 	&plat_constraint_dram,
87 	&plat_constraint_cpu,
88 	NULL,
89 };
90 
91 struct mt_resource_manager plat_mt8186_rm = {
92 	.update = mt_spm_cond_update,
93 	.consts = plat_constraints,
94 };
95 
spm_boot_init(void)96 void spm_boot_init(void)
97 {
98 	NOTICE("MT8186 %s\n", __func__);
99 
100 	/* switch ck_off/axi_26m control to SPM */
101 	mmio_setbits_32(CLK_SCP_CFG_0, SPM_CK_CONTROL_EN);
102 	mmio_clrsetbits_32(CLK_SCP_CFG_1, CLK_SCP_CFG_1_MASK, CLK_SCP_CFG_1_SPM);
103 
104 	plat_spm_lock_init();
105 	mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
106 	mt_lp_rm_register(&plat_mt8186_rm);
107 	mt_spm_idle_generic_init();
108 	mt_spm_suspend_init();
109 	spm_extern_initialize();
110 }
111