xref: /rk3399_ARM-atf/plat/mediatek/drivers/pmic/mt8196/pmic_shutdown_cfg.c (revision 06f3c7058c42a9f1a9f7df75ea2de71a000855e8)
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 
11 #include <drivers/pmic/pmic_shutdown_cfg.h>
12 #include <drivers/spmi/spmi_common.h>
13 #include <drivers/spmi_api.h>
14 #include <lib/mtk_init/mtk_init.h>
15 
16 #define MASTER_ID				SPMI_MASTER_1
17 
18 #ifndef MT8678_PMIC_SUPPORT
19 /* MT6316 will automatically disable wdt in poffs */
20 #define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR	0x408
21 #define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK	0x1
22 #define MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT	1
23 #else
24 /* MT6319 will automatically disable wdt in poffs */
25 #define MT6319_TOP_RST_MISC_CLR			0x128
26 #define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR	0x138
27 #define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK	0x1
28 #define MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT	2
29 #endif
30 
31 #define MT6373_TOP_RST_MISC1_CLR		0x13B
32 #define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR	0x408
33 #define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK	0x1
34 #define MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT	1
35 
36 #define MT6685_TOP_RST_MISC_CLR			0x129
37 #define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR	0x408
38 #define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK	0x1
39 #define MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT	1
40 
41 struct spmi_device *sdev_arr[SPMI_MAX_SLAVE_ID];
42 
43 struct cfg_t {
44 	uint8_t slvid;
45 	uint32_t addr;
46 	uint32_t shutdown_src_addr;
47 	uint32_t shutdown_src_mask;
48 	uint32_t shutdown_src_shift;
49 	uint8_t val;
50 };
51 
52 #ifndef MT8678_PMIC_SUPPORT
53 static const struct cfg_t cfg_arr[] = {
54 	{
55 		.slvid = SPMI_SLAVE_6,
56 		.addr = 0,
57 		.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
58 		.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
59 		.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
60 		.val = 0x1
61 	}, {
62 		.slvid = SPMI_SLAVE_7,
63 		.addr = 0,
64 		.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
65 		.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
66 		.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
67 		.val = 0x1
68 	}, {
69 		.slvid = SPMI_SLAVE_8,
70 		.addr = 0,
71 		.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
72 		.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
73 		.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
74 		.val = 0x1
75 	}, {
76 		.slvid = SPMI_SLAVE_15,
77 		.addr = 0,
78 		.shutdown_src_addr = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
79 		.shutdown_src_mask = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
80 		.shutdown_src_shift = MT6316_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
81 		.val = 0x1
82 	}, {
83 		.slvid = SPMI_SLAVE_5,
84 		.addr = MT6373_TOP_RST_MISC1_CLR,
85 		.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
86 		.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
87 		.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
88 		.val = 0x1
89 	}, {
90 		.slvid = SPMI_SLAVE_9,
91 		.addr = MT6685_TOP_RST_MISC_CLR,
92 		.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
93 		.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
94 		.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
95 		.val = 0x1
96 	}
97 };
98 #else /* MT8678_PMIC_SUPPORT */
99 static const struct cfg_t cfg_arr[] = {
100 	{
101 		.slvid = SPMI_SLAVE_6,
102 		.addr = MT6319_TOP_RST_MISC_CLR,
103 		.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
104 		.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
105 		.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
106 		.val = 0x1
107 	}, {
108 		.slvid = SPMI_SLAVE_7,
109 		.addr = MT6319_TOP_RST_MISC_CLR,
110 		.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
111 		.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
112 		.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
113 		.val = 0x1
114 	}, {
115 		.slvid = SPMI_SLAVE_8,
116 		.addr = MT6319_TOP_RST_MISC_CLR,
117 		.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
118 		.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
119 		.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
120 		.val = 0x1
121 	}, {
122 		.slvid = SPMI_SLAVE_15,
123 		.addr = MT6319_TOP_RST_MISC_CLR,
124 		.shutdown_src_addr = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
125 		.shutdown_src_mask = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
126 		.shutdown_src_shift = MT6319_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
127 		.val = 0x1
128 	}, {
129 		.slvid = SPMI_SLAVE_5,
130 		.addr = MT6373_TOP_RST_MISC1_CLR,
131 		.shutdown_src_addr = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
132 		.shutdown_src_mask = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
133 		.shutdown_src_shift = MT6373_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
134 		.val = 0x1
135 	}, {
136 		.slvid = SPMI_SLAVE_9,
137 		.addr = MT6685_TOP_RST_MISC_CLR,
138 		.shutdown_src_addr = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_ADDR,
139 		.shutdown_src_mask = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_MASK,
140 		.shutdown_src_shift = MT6685_PMIC_RG_SHUTDOWN_SRC_SEL_SHIFT,
141 		.val = 0x1
142 	}
143 };
144 #endif /* MT8678_PMIC_SUPPORT */
145 
146 #define MT6316_TOP_ANA_KEY			0x3AA
147 #define MT6316_PMIC_RG_VI075_SINK_CUR_ADDR	0x994
148 #define MT6316_PMIC_RG_VI075_SINK_CUR_MASK	0xF
149 #define MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT	4
150 #define MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR	0xA2C
151 #define MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK	0x7
152 #define MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT	5
153 #define PSEQ_ELR_RSV2_VAL_MASK_1		0x3
154 #define PSEQ_ELR_RSV2_VAL_MASK_2		0x1
155 #define VI075_SINK_CUR_SOURCE_1			0x5
156 #define VI075_SINK_CUR_SOURCE_2			0
157 #define VI075_SINK_CUR_SOURCE_3			0xB
158 #define ARRAY_LENGTH_MAX			2
159 
160 #ifndef MT8678_PMIC_SUPPORT
161 static void mt6316_key_lock_check(struct spmi_device *mt6316_dev, uint16_t key)
162 {
163 	int i, ret;
164 	uint16_t rdata;
165 	uint8_t work_val[ARRAY_LENGTH_MAX];
166 	uint8_t wdata[ARRAY_LENGTH_MAX];
167 
168 	for (i = 0; i < 2; i++) {
169 		ret = spmi_ext_register_readl(mt6316_dev, key, &work_val[0], 2);
170 		if (ret < 0) {
171 			INFO("[%s]: read fail, addr = 0x%x, ret = %d\n"
172 			      , __func__, key, ret);
173 			i = 0;
174 			continue;
175 		}
176 		rdata = work_val[0] | (work_val[1] << 8);
177 
178 		if (rdata != 0) {
179 			INFO("[%s] lock fail, addr = 0x%x, rdata = 0x%x.\n"
180 			      , __func__, key, rdata);
181 			wdata[0] = 0;
182 			wdata[1] = 0;
183 			spmi_ext_register_writel(mt6316_dev, key, &wdata[0], 2);
184 			i = 0;
185 		}
186 	}
187 }
188 
189 static void wk_vio075_sink_cur(struct spmi_device *mt6316_dev, unsigned char en_seq_off)
190 {
191 	uint8_t rval, wval;
192 	int ret;
193 	uint8_t buf[ARRAY_LENGTH_MAX];
194 
195 	ret = spmi_ext_register_readl(mt6316_dev, MT6316_PMIC_RG_PSEQ_ELR_RSV2_ADDR, &rval, 1);
196 	if (ret < 0)
197 		return;
198 	rval = (rval >> MT6316_PMIC_RG_PSEQ_ELR_RSV2_SHIFT) & MT6316_PMIC_RG_PSEQ_ELR_RSV2_MASK;
199 
200 	if (!(rval & PSEQ_ELR_RSV2_VAL_MASK_1)) {
201 		wval = VI075_SINK_CUR_SOURCE_1;
202 	} else if (rval & PSEQ_ELR_RSV2_VAL_MASK_2) {
203 		if (en_seq_off)
204 			wval = VI075_SINK_CUR_SOURCE_2;
205 		else
206 			wval = VI075_SINK_CUR_SOURCE_3;
207 	} else {
208 		wval = VI075_SINK_CUR_SOURCE_2;
209 	}
210 
211 	buf[0] = 0xDC;
212 	buf[1] = 0xF1;
213 	spmi_ext_register_writel(mt6316_dev,
214 				 MT6316_TOP_ANA_KEY,
215 				 &buf[0], 2); /* unlock TOP_ANA key */
216 	spmi_ext_register_writel_field(mt6316_dev,
217 				       MT6316_PMIC_RG_VI075_SINK_CUR_ADDR, wval,
218 				       MT6316_PMIC_RG_VI075_SINK_CUR_MASK,
219 				       MT6316_PMIC_RG_VI075_SINK_CUR_SHIFT);
220 	buf[0] = 0;
221 	buf[1] = 0;
222 	spmi_ext_register_writel(mt6316_dev,
223 				 MT6316_TOP_ANA_KEY,
224 				 &buf[0], 2); /* lock TOP_ANA key */
225 	mt6316_key_lock_check(mt6316_dev, MT6316_TOP_ANA_KEY);
226 }
227 #endif
228 
229 static int pmic_shutdown_cfg_init(void)
230 {
231 	uint8_t i, slvid;
232 
233 	for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
234 		slvid = cfg_arr[i].slvid;
235 		if (sdev_arr[slvid] != NULL)
236 			continue;
237 		sdev_arr[slvid] = get_spmi_device(MASTER_ID, slvid);
238 		if (!sdev_arr[slvid])
239 			return -ENODEV;
240 	}
241 	return 0;
242 }
243 MTK_PLAT_SETUP_0_INIT(pmic_shutdown_cfg_init);
244 
245 int pmic_shutdown_cfg(void)
246 {
247 	int ret;
248 	uint8_t i, slvid;
249 	uint32_t addr;
250 	uint8_t val;
251 
252 	for (i = 0; i < ARRAY_SIZE(cfg_arr); i++) {
253 		slvid = cfg_arr[i].slvid;
254 		if (!sdev_arr[slvid])
255 			return -ENODEV;
256 		/* mt6316 vio075 sink current adjustment */
257 		if ((slvid >= SPMI_SLAVE_6 && slvid <= SPMI_SLAVE_8) || slvid == SPMI_SLAVE_15)
258 			wk_vio075_sink_cur(sdev_arr[slvid], 1);
259 		addr = cfg_arr[i].addr;
260 		val = cfg_arr[i].val;
261 		/* Disable WDTRSTB_EN */
262 		if (addr) {
263 			ret = spmi_ext_register_writel(sdev_arr[slvid], addr, &val, 1);
264 			if (ret < 0)
265 				return ret;
266 		}
267 
268 		/* set RG_SHUTDOWN_SRC_SEL to 1, shutdown PMIC by SPMI command */
269 		spmi_ext_register_writel_field(sdev_arr[slvid],
270 					       cfg_arr[i].shutdown_src_addr, 1,
271 					       cfg_arr[i].shutdown_src_mask,
272 					       cfg_arr[i].shutdown_src_shift);
273 	}
274 	return 1; /* 1: use spmi_command_shutdown API */
275 }
276 
277 /* shutdown PMIC by SPMI command */
278 int spmi_shutdown(void)
279 {
280 	struct spmi_device *mt6363_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4);
281 
282 	if (!mt6363_sdev)
283 		return -ENODEV;
284 
285 	/* set RG_SHUTDOWN_SRC_SEL to 1 */
286 	spmi_ext_register_writel_field(mt6363_sdev, 0x408, 1, 0x1, 1);
287 	spmi_command_shutdown(SPMI_MASTER_P_1, mt6363_sdev, 0x800);
288 	spmi_command_shutdown(SPMI_MASTER_1, mt6363_sdev, 0x800);
289 
290 	return 0;
291 }
292