xref: /rk3399_ARM-atf/plat/mediatek/include/drivers/pmic/pmic_set_lowpower.h (revision 52c47c174fadb9e1398af41e9bbf290af314e8ec)
1d4e6f98dSHope Wang /*
2d4e6f98dSHope Wang  * Copyright (c) 2025, Mediatek Inc. All rights reserved.
3d4e6f98dSHope Wang  *
4d4e6f98dSHope Wang  * SPDX-License-Identifier: BSD-3-Clause
5d4e6f98dSHope Wang  */
6d4e6f98dSHope Wang 
7d4e6f98dSHope Wang #ifndef PMIC_SET_LOWPOWER_H
8d4e6f98dSHope Wang #define PMIC_SET_LOWPOWER_H
9d4e6f98dSHope Wang 
10d4e6f98dSHope Wang #include <stdint.h>
11d4e6f98dSHope Wang 
12d4e6f98dSHope Wang #include <drivers/spmi_api.h>
13d4e6f98dSHope Wang 
14d4e6f98dSHope Wang #include "mt6316_lowpower_reg.h"
15*868b2d60SZhigang Qin #include "mt6319_lowpower_reg.h"
16d4e6f98dSHope Wang #include "mt6363_lowpower_reg.h"
17d4e6f98dSHope Wang #include "mt6373_lowpower_reg.h"
18d4e6f98dSHope Wang 
19d4e6f98dSHope Wang #define OP_MODE_MU	0
20d4e6f98dSHope Wang #define OP_MODE_LP	1
21d4e6f98dSHope Wang 
22d4e6f98dSHope Wang #define HW_OFF		0
23d4e6f98dSHope Wang #define HW_ON		0
24d4e6f98dSHope Wang #define HW_LP		1
25d4e6f98dSHope Wang #define HW_ONLV		(0x10 | 1)
26d4e6f98dSHope Wang #define NORMAL_OP_CFG	0x10
27d4e6f98dSHope Wang 
28d4e6f98dSHope Wang enum {
29d4e6f98dSHope Wang 	RC0 = 0,
30d4e6f98dSHope Wang 	RC1,
31d4e6f98dSHope Wang 	RC2,
32d4e6f98dSHope Wang 	RC3,
33d4e6f98dSHope Wang 	RC4,
34d4e6f98dSHope Wang 	RC5,
35d4e6f98dSHope Wang 	RC6,
36d4e6f98dSHope Wang 	RC7,
37d4e6f98dSHope Wang 	RC8 = 0,
38d4e6f98dSHope Wang 	RC9,
39d4e6f98dSHope Wang 	RC10,
40d4e6f98dSHope Wang 	RC11,
41d4e6f98dSHope Wang 	RC12,
42d4e6f98dSHope Wang 	RC13,
43d4e6f98dSHope Wang 	HW0 = 0,
44d4e6f98dSHope Wang 	HW1,
45d4e6f98dSHope Wang 	HW2,
46d4e6f98dSHope Wang 	HW3,
47d4e6f98dSHope Wang 	HW4,
48d4e6f98dSHope Wang 	HW5,
49d4e6f98dSHope Wang 	HW6,
50d4e6f98dSHope Wang 	HW7,
51d4e6f98dSHope Wang 	HW8 = 0,
52d4e6f98dSHope Wang 	HW9,
53d4e6f98dSHope Wang 	HW10,
54d4e6f98dSHope Wang 	HW11,
55d4e6f98dSHope Wang 	HW12,
56d4e6f98dSHope Wang 	HW13,
57d4e6f98dSHope Wang };
58d4e6f98dSHope Wang 
59d4e6f98dSHope Wang #define VOTER_EN_SET	1
60d4e6f98dSHope Wang #define VOTER_EN_CLR	2
61d4e6f98dSHope Wang 
62d4e6f98dSHope Wang enum {
63d4e6f98dSHope Wang 	VOTER_EN_LO_BIT0 = 0,
64d4e6f98dSHope Wang 	VOTER_EN_LO_BIT1,
65d4e6f98dSHope Wang 	VOTER_EN_LO_BIT2,
66d4e6f98dSHope Wang 	VOTER_EN_LO_BIT3,
67d4e6f98dSHope Wang 	VOTER_EN_LO_BIT4,
68d4e6f98dSHope Wang 	VOTER_EN_LO_BIT5,
69d4e6f98dSHope Wang 	VOTER_EN_LO_BIT6,
70d4e6f98dSHope Wang 	VOTER_EN_LO_BIT7,
71d4e6f98dSHope Wang 	VOTER_EN_HI_BIT0 = 0,
72d4e6f98dSHope Wang 	VOTER_EN_HI_BIT1,
73d4e6f98dSHope Wang 	VOTER_EN_HI_BIT2,
74d4e6f98dSHope Wang 	VOTER_EN_HI_BIT3,
75d4e6f98dSHope Wang };
76d4e6f98dSHope Wang 
77d4e6f98dSHope Wang enum {
78d4e6f98dSHope Wang 	MT6363_SLAVE = SPMI_SLAVE_4,
79d4e6f98dSHope Wang 	MT6368_SLAVE = SPMI_SLAVE_5,
80d4e6f98dSHope Wang 	MT6369_SLAVE = SPMI_SLAVE_5,
81d4e6f98dSHope Wang 	MT6373_SLAVE = SPMI_SLAVE_5,
82d4e6f98dSHope Wang 	MT6316_S6_SLAVE = SPMI_SLAVE_6,
83d4e6f98dSHope Wang 	MT6316_S7_SLAVE = SPMI_SLAVE_7,
84d4e6f98dSHope Wang 	MT6316_S8_SLAVE = SPMI_SLAVE_8,
85d4e6f98dSHope Wang 	MT6316_S15_SLAVE = SPMI_SLAVE_15,
86d4e6f98dSHope Wang 	MT6319_S6_SLAVE = SPMI_SLAVE_6,
87d4e6f98dSHope Wang 	MT6319_S7_SLAVE = SPMI_SLAVE_7,
88d4e6f98dSHope Wang 	MT6319_S8_SLAVE = SPMI_SLAVE_8,
89d4e6f98dSHope Wang 	MT6319_S15_SLAVE = SPMI_SLAVE_15,
90d4e6f98dSHope Wang };
91d4e6f98dSHope Wang 
92d4e6f98dSHope Wang extern struct spmi_device *lowpower_sdev[SPMI_MAX_SLAVE_ID];
93d4e6f98dSHope Wang 
94d4e6f98dSHope Wang #define PMIC_BUCK_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
95d4e6f98dSHope Wang { \
96d4e6f98dSHope Wang 	uint8_t val = 0; \
97d4e6f98dSHope Wang 	struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
98d4e6f98dSHope Wang 	if (sdev && \
99d4e6f98dSHope Wang 	    !spmi_ext_register_readl(sdev, _chip##_RG_BUCK_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
100d4e6f98dSHope Wang 	    !(val & NORMAL_OP_CFG)) {\
101d4e6f98dSHope Wang 		if ((_cfg) == HW_ONLV) { \
102d4e6f98dSHope Wang 			pmic_spmi_update_bits(sdev, \
103d4e6f98dSHope Wang 					      _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
104d4e6f98dSHope Wang 					      (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
105d4e6f98dSHope Wang 					      (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT)); \
106d4e6f98dSHope Wang 		} else if ((_cfg) == HW_LP) { \
107d4e6f98dSHope Wang 			pmic_spmi_update_bits(sdev, \
108d4e6f98dSHope Wang 					      _chip##_RG_BUCK_##_name##_ONLV_EN_ADDR, \
109d4e6f98dSHope Wang 					      (1 << _chip##_RG_BUCK_##_name##_ONLV_EN_SHIFT), \
110d4e6f98dSHope Wang 					      0); \
111d4e6f98dSHope Wang 		} \
112d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
113d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
114d4e6f98dSHope Wang 				      1 << (_user), \
115d4e6f98dSHope Wang 				      ((_cfg) & 0x1) ? 1 << (_user) : 0); \
116d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
117d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
118d4e6f98dSHope Wang 				      1 << (_user), \
119d4e6f98dSHope Wang 				      (_mode) ? 1 << (_user) : 0); \
120d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
121d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
122d4e6f98dSHope Wang 				      1 << (_user), \
123d4e6f98dSHope Wang 				      (_en) ? 1 << (_user) : 0); \
124d4e6f98dSHope Wang 	} \
125d4e6f98dSHope Wang }
126d4e6f98dSHope Wang 
127d4e6f98dSHope Wang #define PMIC_LDO_SET_LP(_chip, _name, _user, _en, _mode, _cfg) \
128d4e6f98dSHope Wang { \
129d4e6f98dSHope Wang 	uint8_t val = 0; \
130d4e6f98dSHope Wang 	struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
131d4e6f98dSHope Wang 	if (sdev && \
132d4e6f98dSHope Wang 	    !spmi_ext_register_readl(sdev, _chip##_RG_LDO_##_name##_HW0_OP_CFG_ADDR, &val, 1) && \
133d4e6f98dSHope Wang 	    !(val & NORMAL_OP_CFG)) {\
134d4e6f98dSHope Wang 		if ((_cfg) == HW_ONLV) { \
135d4e6f98dSHope Wang 			pmic_spmi_update_bits(sdev, \
136d4e6f98dSHope Wang 					      _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
137d4e6f98dSHope Wang 					      (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
138d4e6f98dSHope Wang 					      (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT)); \
139d4e6f98dSHope Wang 		} else { \
140d4e6f98dSHope Wang 			pmic_spmi_update_bits(sdev, \
141d4e6f98dSHope Wang 					      _chip##_RG_LDO_##_name##_ONLV_EN_ADDR, \
142d4e6f98dSHope Wang 					      (1 << _chip##_RG_LDO_##_name##_ONLV_EN_SHIFT), \
143d4e6f98dSHope Wang 					      0); \
144d4e6f98dSHope Wang 		} \
145d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
146d4e6f98dSHope Wang 				      _chip##_RG_LDO_##_name##_##_user##_OP_CFG_ADDR, \
147d4e6f98dSHope Wang 				      1 << (_user), \
148d4e6f98dSHope Wang 				      ((_cfg) & 0x1) ? 1 << (_user) : 0); \
149d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
150d4e6f98dSHope Wang 				      _chip##_RG_LDO_##_name##_##_user##_OP_MODE_ADDR, \
151d4e6f98dSHope Wang 				      1 << (_user), \
152d4e6f98dSHope Wang 				      (_mode) ? 1 << (_user) : 0); \
153d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
154d4e6f98dSHope Wang 				      _chip##_RG_LDO_##_name##_##_user##_OP_EN_ADDR, \
155d4e6f98dSHope Wang 				      1 << (_user), \
156d4e6f98dSHope Wang 				      (_en) ? 1 << (_user) : 0); \
157d4e6f98dSHope Wang 	} \
158d4e6f98dSHope Wang }
159d4e6f98dSHope Wang 
160d4e6f98dSHope Wang #define PMIC_SLVID_BUCK_SET_LP(_chip, _slvid, _name, _user, _en, _mode, _cfg) \
161d4e6f98dSHope Wang { \
162d4e6f98dSHope Wang 	struct spmi_device *sdev = lowpower_sdev[_chip##_##_slvid##_SLAVE]; \
163d4e6f98dSHope Wang 	if (sdev) {\
164d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
165d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_CFG_ADDR, \
166d4e6f98dSHope Wang 				      1 << (_user), \
167d4e6f98dSHope Wang 				      (_cfg) ? 1 << (_user) : 0); \
168d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
169d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_MODE_ADDR, \
170d4e6f98dSHope Wang 				      1 << (_user), \
171d4e6f98dSHope Wang 				      (_mode) ? 1 << (_user) : 0); \
172d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
173d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_OP_EN_ADDR, \
174d4e6f98dSHope Wang 				      1 << (_user), \
175d4e6f98dSHope Wang 				      (_en) ? 1 << (_user) : 0); \
176d4e6f98dSHope Wang 	} \
177d4e6f98dSHope Wang }
178d4e6f98dSHope Wang 
179d4e6f98dSHope Wang #define PMIC_BUCK_VOTER_EN(_chip, _name, _user, _cfg) \
180d4e6f98dSHope Wang { \
181d4e6f98dSHope Wang 	struct spmi_device *sdev = lowpower_sdev[_chip##_SLAVE]; \
182d4e6f98dSHope Wang 	if (sdev) {\
183d4e6f98dSHope Wang 		pmic_spmi_update_bits(sdev, \
184d4e6f98dSHope Wang 				      _chip##_RG_BUCK_##_name##_##_user##_ADDR + (_cfg), \
185d4e6f98dSHope Wang 				      1 << (_user), \
186d4e6f98dSHope Wang 				      1 << (_user)); \
187d4e6f98dSHope Wang 	} \
188d4e6f98dSHope Wang }
189d4e6f98dSHope Wang 
pmic_spmi_update_bits(struct spmi_device * sdev,uint16_t reg,uint8_t mask,uint8_t val)190d4e6f98dSHope Wang static inline int pmic_spmi_update_bits(struct spmi_device *sdev, uint16_t reg,
191d4e6f98dSHope Wang 					uint8_t mask, uint8_t val)
192d4e6f98dSHope Wang {
193d4e6f98dSHope Wang 	uint8_t org = 0;
194d4e6f98dSHope Wang 	int ret = 0;
195d4e6f98dSHope Wang 
196d4e6f98dSHope Wang 	ret = spmi_ext_register_readl(sdev, reg, &org, 1);
197d4e6f98dSHope Wang 	if (ret < 0)
198d4e6f98dSHope Wang 		return ret;
199d4e6f98dSHope Wang 
200d4e6f98dSHope Wang 	org &= ~mask;
201d4e6f98dSHope Wang 	org |= val & mask;
202d4e6f98dSHope Wang 
203d4e6f98dSHope Wang 	ret = spmi_ext_register_writel(sdev, reg, &org, 1);
204d4e6f98dSHope Wang 	return ret;
205d4e6f98dSHope Wang }
206d4e6f98dSHope Wang 
207d4e6f98dSHope Wang #endif /* PMIC_SET_LOWPOWER_H */
208