xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8189/mt_spm_pmic_lp.c (revision 982ee634e7c4decd941b2fe97d85181b5615797a)
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/mt6359p_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 <pmic_wrap_init_common.h>
18 
19 #ifdef MTK_SPM_PMIC_GS_DUMP
20 static struct pmic_gs_info pmic_gs_dump_info;
21 static char *pmic_str[] = {
22 	[LP_MT6365] = "MT6365",
23 	[LP_MT6319_S7] = "MT6319",
24 };
25 #endif
26 
27 struct spmi_device *lp_sdev[LP_PMIC_SLAVE_NUM];
28 
29 #define VCORE_BASE_UV			40000
30 #define VCORE_TO_PMIC_VAL(volt)		(((volt) - VCORE_BASE_UV + 625 - 1) / 625)
31 #define PMIC_VAL_TO_VCORE(pmic)		(((pmic) * 625) + VCORE_BASE_UV)
32 
33 #define VCORE_0_45V			VCORE_TO_PMIC_VAL(45000)
34 #define VCORE_0_55V			VCORE_TO_PMIC_VAL(55000)
35 #define VCORE_0_75V			VCORE_TO_PMIC_VAL(75000)
36 
37 #define VSRAM_CORE_BASE_UV		40000
38 #define VSRAM_CORE_TO_PMIC_VAL(volt)	(((volt) - VSRAM_CORE_BASE_UV + 625 - 1) / 625)
39 #define PMIC_VAL_TO_VSRAM_CORE(pmic)	(((pmic) * 625) + VSRAM_CORE_BASE_UV)
40 
41 #define VSRAM_CORE_0_40V		VSRAM_CORE_TO_PMIC_VAL(40000)
42 #define VSRAM_CORE_0_55V		VSRAM_CORE_TO_PMIC_VAL(55000)
43 #define VSRAM_CORE_0_75V		VSRAM_CORE_TO_PMIC_VAL(75000)
44 
45 static uint32_t vcore_sram_suspend_vol = VSRAM_CORE_0_55V;
46 static uint32_t vcore_suspend_vol = VCORE_0_55V;
47 static bool vcore_sram_lp_enable = true;
48 static bool vcore_lp_enable = true;
49 
50 static uint32_t get_vcore_sram_suspend_vol(void)
51 {
52 	uint8_t value = VSRAM_CORE_0_55V;
53 #ifdef MTK_SUSPEND_VOL_BIN_SUPPORT
54 	static const uint32_t vlp_vb_efuse_val_arr[] = { 24, 24, 24, 24, 24, 24,
55 							 22, 21, 20, 19, 18, 17,
56 							 16, 15, 14, 13 };
57 	uint32_t volbin_efuse_reg;
58 
59 	volbin_efuse_reg = mmio_read_32(SOC_VB_REG);
60 	INFO("11#@# %s(%d) enable voltage bin support with efuse value: 0x%x\n",
61 	     __func__, __LINE__, volbin_efuse_reg);
62 	volbin_efuse_reg = (volbin_efuse_reg >> SUSPEND_VB_USE_SHIFT) &
63 			   SUSPEND_VB_USE_MASK;
64 
65 	if (volbin_efuse_reg < ARRAY_SIZE(vlp_vb_efuse_val_arr))
66 		value = vlp_vb_efuse_val_arr[volbin_efuse_reg];
67 #endif
68 #ifdef MTK_AGING_FLAVOR_LOAD
69 	value -= SUSPEND_AGING_VAL_SHIFT;
70 	if (value > SUSPEND_AGING_VAL_DEFAULT)
71 		value = SUSPEND_AGING_VAL_DEFAULT;
72 	INFO("11#@# %s(%d) enable aging with value: %d\n", __func__, __LINE__,
73 	     value);
74 #endif
75 #ifdef MTK_AGING_HV_FLAVOR_LOAD
76 	/* ignore binning and configure as sign off + 5% */
77 	value = SUSPEND_AGING_HV_VAL_DEFAULT;
78 	INFO("11#@# %s(%d) enable aging hv with value: %d\n", __func__,
79 	     __LINE__, value);
80 #endif
81 	return value;
82 }
83 
84 #ifdef MTK_SPM_PMIC_GS_DUMP
85 static void mt_spm_dump_pmic_gs(uint32_t cmd)
86 {
87 #ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
88 	if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND) { /*Suspend enter*/
89 		mt_spm_pmic_gs_dump(SUSPEND, LP_MT6365);
90 	}
91 #endif
92 	if (cmd & MT_RM_CONSTRAINT_ALLOW_VCORE_LP) {
93 		if (cmd & MT_RM_CONSTRAINT_ALLOW_BUS26M_OFF) { /*SODI3 enter*/
94 #ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
95 			mt_spm_pmic_gs_dump(SODI3, LP_MT6365);
96 #endif
97 		} else { /*DPIDLE enter*/
98 #ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
99 			mt_spm_pmic_gs_dump(DPIDLE, LP_MT6365);
100 #endif
101 		}
102 	}
103 }
104 #endif
105 
106 int spm_lp_setting_init(void)
107 {
108 	/* AOC2.5: VCORE O0 OFF */
109 	PMIC_BUCK_SET_LP(MT6359P, VPROC2, HW0, true, OP_MODE_LP, HW_OFF);
110 
111 	/* AOC2.5 : VSRAM_CORE O0 HW:LP */
112 	PMIC_BUCK_SET_LP(MT6359P, VGPU11, HW0, true, OP_MODE_LP, HW_LP);
113 
114 	/* Get suspend case VSRAM_CORE sleep voltage */
115 	vcore_sram_suspend_vol = get_vcore_sram_suspend_vol();
116 	/* Set VCORE LP default 0.55V */
117 	vcore_suspend_vol = VCORE_0_55V;
118 
119 #ifdef MTK_SPM_PMIC_GS_DUMP
120 	pmic_gs_dump_info.lp_sdev = lp_sdev;
121 	pmic_gs_dump_info.pmic_str = pmic_str;
122 	pmic_gs_dump_info.pmic_num = LP_PMIC_SLAVE_NUM;
123 #ifdef MTK_SPM_PMIC_GS_DUMP_SUSPEND
124 	pmic_gs_dump_info.scen_gs[SUSPEND].data = pmic_gs_suspend;
125 #endif
126 #ifdef MTK_SPM_PMIC_GS_DUMP_SODI3
127 	pmic_gs_dump_info.scen_gs[SODI3].data = pmic_gs_sodi3;
128 #endif
129 #ifdef MTK_SPM_PMIC_GS_DUMP_DPIDLE
130 	pmic_gs_dump_info.scen_gs[DPIDLE].data = pmic_gs_dpidle;
131 #endif
132 	return register_pmic_gs_info(&pmic_gs_dump_info);
133 #else
134 	return 0;
135 #endif
136 }
137 
138 MTK_PLAT_SETUP_0_INIT(spm_lp_setting_init);
139 
140 void set_vcore_lp_enable(bool enable)
141 {
142 	vcore_lp_enable = enable;
143 }
144 
145 bool get_vcore_lp_enable(void)
146 {
147 	return vcore_lp_enable;
148 }
149 
150 void set_vcore_lp_volt(uint32_t volt)
151 {
152 	/* allow 0.45V ~ 0.75V */
153 	if (volt < VCORE_0_45V)
154 		return;
155 	if (volt > VCORE_0_75V)
156 		return;
157 	vcore_suspend_vol = volt;
158 }
159 
160 uint32_t get_vcore_lp_volt(void)
161 {
162 	return vcore_suspend_vol;
163 }
164 
165 void set_vsram_lp_enable(bool enable)
166 {
167 	vcore_sram_lp_enable = enable;
168 }
169 
170 bool get_vsram_lp_enable(void)
171 {
172 	return vcore_sram_lp_enable;
173 }
174 
175 void set_vsram_lp_volt(uint32_t volt)
176 {
177 	/* allow 0.40V ~ 0.75V */
178 	if (volt > VSRAM_CORE_0_75V)
179 		return;
180 	vcore_sram_suspend_vol = volt;
181 }
182 
183 uint32_t get_vsram_lp_volt(void)
184 {
185 	return vcore_sram_suspend_vol;
186 }
187 
188 int do_spm_low_power(enum SPM_PWR_TYPE type, uint32_t cmd)
189 {
190 	int ret = 0;
191 	uint8_t value = 0;
192 	uint32_t reg = 0;
193 	bool vproc2_lp_enable = false;
194 	bool vgpu11_hw0_lp_enable = false;
195 	bool vgpu11_hw2_lp_enable = false;
196 
197 	if (!(cmd & MT_RM_CONSTRAINT_ALLOW_AP_SUSPEND))
198 		return 0;
199 
200 	if (type == SPM_LP_ENTER) {
201 		/* SUSPEND enter */
202 		vproc2_lp_enable = vcore_lp_enable;
203 		vgpu11_hw0_lp_enable = vcore_sram_lp_enable;
204 		vgpu11_hw2_lp_enable = false;
205 		reg = 0x158E; /* LDO_VSRAM_CORE_VOSEL0 */
206 
207 		if (cmd & MT_RM_CONSTRAINT_ALLOW_AP_PLAT_SUSPEND)
208 			value = vcore_sram_suspend_vol; /* SUSPEND: VSRAM_CORE 0.55V */
209 		else
210 			value = VSRAM_CORE_0_55V;       /* SODI5.0: VSRAM_CORE 0.55V */
211 	} else {
212 		/* SUSPEND leave (SODI3/DPIDLE) */
213 		vproc2_lp_enable = true;
214 		vgpu11_hw0_lp_enable = true;
215 		vgpu11_hw2_lp_enable = true;
216 		reg = 0x15b4; /* LDO_VSRAM_CORE_VOSEL0 */
217 		value = VSRAM_CORE_0_75V; /* 0.75V SODI3/DPIDLE */
218 	}
219 
220 	PMIC_BUCK_SET_LP(MT6359P, VPROC2, HW0, vproc2_lp_enable, OP_MODE_LP, HW_OFF);
221 	PMIC_BUCK_SET_LP(MT6359P, VGPU11, HW0, vgpu11_hw0_lp_enable, OP_MODE_LP, HW_LP);
222 	PMIC_BUCK_SET_LP(MT6359P, VGPU11, HW2, vgpu11_hw2_lp_enable, OP_MODE_LP, HW_LP);
223 
224 	ret = pwrap_write_field(reg, value, 0xff, 0);
225 	if (ret) {
226 		if (type == SPM_LP_ENTER)
227 			INFO("LDO_VSRAM_CORE_VOSEL0(VSRAM_CORE) spmi write failed\n");
228 		else
229 			INFO("BUCK_VBUCK4_CON1(VSRAM_CORE) spmi write failed\n");
230 	}
231 
232 #ifdef MTK_SPM_PMIC_GS_DUMP
233 	if (type == SPM_LP_ENTER)
234 		mt_spm_dump_pmic_gs(cmd);
235 #endif
236 
237 	return 0;
238 }
239