xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8196/mt_spm_pmic_lp.c (revision 10ecd58093a34e95e2dfad65b1180610f29397cc)
1 /*
2  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <errno.h>
8 
9 #include <common/debug.h>
10 #include <lib/mmio.h>
11 
12 #include <drivers/pmic/pmic_set_lowpower.h>
13 #include <drivers/spmi/spmi_common.h>
14 #include <lib/mtk_init/mtk_init.h>
15 #include <mt_spm_constraint.h>
16 #include <mt_spm_pmic_lp.h>
17 #include <mt_spm_reg.h>
18 
19 /* SPMI_M: 6363, SPMI_P: 6373/6316 */
20 /* SPMI_M: 6363, SPMI_P: 6373/6316 */
21 static struct lp_pmic_cfg {
22 	uint8_t slave;
23 	uint8_t master;
24 	char *name;
25 } pmics[] = {
26 	[LP_MT6363] = {MT6363_SLAVE, SPMI_MASTER_1, "MT6363"},
27 	[LP_MT6373] = {MT6373_SLAVE, SPMI_MASTER_P_1, "MT6373"},
28 	[LP_MT6316_1] = {MT6316_S8_SLAVE, SPMI_MASTER_P_1, "MT6316_S8"},
29 	[LP_MT6316_2] = {MT6316_S6_SLAVE, SPMI_MASTER_P_1, "MT6316_S6"},
30 	[LP_MT6316_3] = {MT6316_S7_SLAVE, SPMI_MASTER_P_1, "MT6316_S7"},
31 	[LP_MT6316_4] = {MT6316_S15_SLAVE, SPMI_MASTER_P_1, "MT6316_S15"},
32 };
33 
34 #ifdef MTK_SPM_PMIC_GS_DUMP
35 static struct pmic_gs_info pmic_gs_dump_info;
36 static char *pmic_str[] = {
37 	[LP_MT6363] = "MT6363",
38 	[LP_MT6373] = "MT6373",
39 	[LP_MT6316_1] = "MT6316_1",
40 	[LP_MT6316_2] = "MT6316_2",
41 	[LP_MT6316_3] = "MT6316_3",
42 	[LP_MT6316_4] = "MT6316_4",
43 };
44 #endif
45 struct spmi_device *lp_sdev[LP_PMIC_SLAVE_NUM];
46 
47 #define VSRAM_CORE_0_35V		56
48 #define VSRAM_CORE_0_55V		88
49 #define VSRAM_CORE_0_75V		120
50 
51 /* VSRAM_CORE Low bound */
52 #ifdef MTK_AGING_FLAVOR_LOAD
53 #define SUSPEND_AGING_VAL_SHIFT		3
54 #define SUSPEND_AGING_VAL_DEFAULT	85
55 #define VSRAM_CORE_LOWBOUND		(74 - SUSPEND_AGING_VAL_SHIFT)
56 #else
57 #define VSRAM_CORE_LOWBOUND		74
58 #endif
59 #define MT6363_LP_REG			0x1687
60 #define MT6363_VIO18_SWITCH		0x53
61 #define MT6373_VIO18_SWITCH		0x58
62 
63 static uint32_t vcore_sram_suspend_vol = VSRAM_CORE_0_55V;
64 static bool vcore_sram_lp_enable = true;
65 static bool vcore_lp_enable = true;
66 
67 static uint32_t get_vcore_sram_suspend_vol(void)
68 {
69 	uint8_t value;
70 	/* Set vcore_sram to 0.55V by default */
71 	value = VSRAM_CORE_0_55V;
72 
73 #ifdef MTK_AGING_FLAVOR_LOAD
74 	value -= SUSPEND_AGING_VAL_SHIFT;
75 	if (value > SUSPEND_AGING_VAL_DEFAULT)
76 		value = SUSPEND_AGING_VAL_DEFAULT;
77 	INFO("%s(%d) enable aging with value: %u\n",
78 	     __func__, __LINE__, value);
79 #endif
80 	return value;
81 }
82 
83 #ifdef MTK_SPM_PMIC_GS_DUMP
84 static void mt_spm_dump_pmic_gs(uint32_t cmd)
85 {
86 #ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
87 	if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND) { /* Suspend enter */
88 		mt_spm_pmic_gs_dump(SUSPEND, LP_MT6363);
89 		mt_spm_pmic_gs_dump(SUSPEND, LP_MT6373);
90 	}
91 #endif
92 	if (cmd & MT_RM_CONSTRAINT_ALLOW_VCORE_LP) {
93 		if (cmd & MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF) { /* SODI3 */
94 #ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
95 			mt_spm_pmic_gs_dump(SODI3, LP_MT6363);
96 			mt_spm_pmic_gs_dump(SODI3, LP_MT6373);
97 #endif
98 		} else { /* DPIDLE enter */
99 #ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
100 			mt_spm_pmic_gs_dump(DPIDLE, LP_MT6363);
101 			mt_spm_pmic_gs_dump(DPIDLE, LP_MT6373);
102 #endif
103 		}
104 	}
105 }
106 #endif
107 
108 int spm_lp_setting_init(void)
109 {
110 	uint8_t i, slvid, spmi_master;
111 
112 	for (i = 0; i < ARRAY_SIZE(pmics); i++) {
113 		slvid = pmics[i].slave;
114 		spmi_master = pmics[i].master;
115 		lp_sdev[i] = get_spmi_device(spmi_master, slvid);
116 		if (!lp_sdev[i])
117 			return -ENODEV;
118 	}
119 
120 	PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, RC8,
121 			       false, OP_MODE_LP, HW_OFF);
122 
123 	/* Get suspend case vcore_sram sleep voltage */
124 	vcore_sram_suspend_vol = get_vcore_sram_suspend_vol();
125 
126 #ifdef MTK_SPM_PMIC_GS_DUMP
127 	pmic_gs_dump_info.lp_sdev = lp_sdev;
128 	pmic_gs_dump_info.pmic_str = pmic_str;
129 	pmic_gs_dump_info.pmic_num = LP_PMIC_SLAVE_NUM;
130 #ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
131 	pmic_gs_dump_info.scen_gs[SUSPEND].data = pmic_gs_suspend;
132 #endif
133 #ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
134 	pmic_gs_dump_info.scen_gs[SODI3].data = pmic_gs_sodi3;
135 #endif
136 #ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
137 	pmic_gs_dump_info.scen_gs[DPIDLE].data = pmic_gs_dpidle;
138 #endif
139 	return register_pmic_gs_info(&pmic_gs_dump_info);
140 #else
141 	return 0;
142 #endif
143 }
144 
145 #ifdef MTK_SPM_PMIC_LP_SUPPORT
146 MTK_PLAT_SETUP_0_INIT(spm_lp_setting_init);
147 #endif
148 
149 void set_vcore_lp_enable(bool enable)
150 {
151 	vcore_lp_enable = enable;
152 }
153 
154 bool get_vcore_lp_enable(void)
155 {
156 	return vcore_lp_enable;
157 }
158 
159 void set_vsram_lp_enable(bool enable)
160 {
161 	vcore_sram_lp_enable = enable;
162 }
163 
164 bool get_vsram_lp_enable(void)
165 {
166 	return vcore_sram_lp_enable;
167 }
168 
169 void set_vsram_lp_volt(uint32_t volt)
170 {
171 	/* Allow 0.35V ~ 0.75V */
172 	if (volt < VSRAM_CORE_0_35V || volt > VSRAM_CORE_0_75V)
173 		return;
174 	vcore_sram_suspend_vol = volt;
175 }
176 
177 uint32_t get_vsram_lp_volt(void)
178 {
179 	return vcore_sram_suspend_vol;
180 }
181 
182 static int pmic_lp_setting(uint8_t data)
183 {
184 	int ret;
185 
186 	if (data != 0x0 && data != 0x1)
187 		return -ENODEV;
188 	/* SUSPEND:VS1 HW2&RC9 normal mode */
189 	PMIC_BUCK_SET_LP(MT6363, VS1, HW2,
190 			 false, OP_MODE_LP, HW_LP);
191 	PMIC_BUCK_SET_LP(MT6363, VS1, RC9,
192 			 false, OP_MODE_MU, HW_ON);
193 	PMIC_LDO_SET_LP(MT6363, VIO18, HW2,
194 			false, OP_MODE_LP, HW_LP);
195 	PMIC_LDO_SET_LP(MT6363, VIO18, RC9,
196 			false, OP_MODE_MU, HW_ON);
197 
198 	/* Switch DIG18 to VIO18 for power saving */
199 	ret = spmi_ext_register_writel(lp_sdev[LP_MT6363], MT6363_VIO18_SWITCH, &data, 1);
200 	if (ret)
201 		INFO("MT6363 RG_VIO18 spmi failed\n");
202 
203 	ret = spmi_ext_register_writel(lp_sdev[LP_MT6373], MT6373_VIO18_SWITCH, &data, 1);
204 	if (ret)
205 		INFO("MT6373 RG_VIO18 spmi failed\n");
206 	return ret;
207 }
208 
209 int do_spm_low_power(enum SPM_PWR_TYPE type, uint32_t cmd)
210 {
211 	int ret;
212 	uint8_t value;
213 	bool enter_suspend, vcore_sram_lp = false;
214 
215 	if (type == SPM_LP_ENTER) {
216 		enter_suspend = true;
217 		vcore_sram_lp = vcore_sram_lp_enable;
218 
219 		if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND) {
220 			value = vcore_sram_suspend_vol;
221 			if (value < VSRAM_CORE_LOWBOUND ||
222 				value > VSRAM_CORE_0_75V) {
223 				INFO("Vsram_core voltage wrong\n");
224 				panic();
225 			}
226 		} else {
227 			value = VSRAM_CORE_0_55V;
228 		}
229 	} else {
230 		enter_suspend = false;
231 		vcore_sram_lp = false;
232 		value = VSRAM_CORE_0_75V;
233 	}
234 	/* Enable VA12_2/VSRAM_CPUL HW_LP for suspend/idle */
235 	PMIC_LDO_SET_LP(MT6363, VA12_2, HW2, enter_suspend, OP_MODE_LP, HW_LP);
236 	PMIC_LDO_SET_LP(MT6363, VSRAM_CPUL, HW2,
237 			enter_suspend, OP_MODE_LP, HW_LP);
238 
239 	if (!(cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND))
240 		return 0;
241 	PMIC_SLVID_BUCK_SET_LP(MT6316, S8, VBUCK1, HW2, vcore_lp_enable,
242 			       OP_MODE_LP, HW_LP);
243 	PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW0, vcore_sram_lp,
244 			 OP_MODE_LP, HW_LP);
245 	PMIC_BUCK_SET_LP(MT6363, VBUCK4, HW2, !enter_suspend,
246 			 OP_MODE_LP, HW_LP);
247 	ret = spmi_ext_register_writel(lp_sdev[LP_MT6363], MT6363_LP_REG, &value, 1);
248 	if (ret)
249 		INFO("BUCK(VSRAM_CORE) spmi write failed\n");
250 
251 	if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND)
252 		pmic_lp_setting(enter_suspend ? 1 : 0);
253 
254 	return 0;
255 }
256