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