xref: /optee_os/core/arch/arm/plat-stm32mp1/drivers/stm32mp1_pwr.c (revision 0d7276ac260cf982daf8f15a969fbd33ca43b19e)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2018-2023, STMicroelectronics
4  */
5 
6 #include <assert.h>
7 #include <drivers/regulator.h>
8 #include <drivers/stm32_shared_io.h>
9 #include <drivers/stm32_bsec.h>
10 #include <drivers/stm32mp1_pwr.h>
11 #include <drivers/stm32mp1_syscfg.h>
12 #include <io.h>
13 #include <kernel/delay.h>
14 #include <kernel/dt_driver.h>
15 #include <kernel/panic.h>
16 #include <kernel/pm.h>
17 #include <libfdt.h>
18 #include <mm/core_memprot.h>
19 #include <platform_config.h>
20 
21 #define PWR_CR3_USB33_EN	BIT(24)
22 #define PWR_CR3_USB33_RDY	BIT(26)
23 #define PWR_CR3_REG18_EN	BIT(28)
24 #define PWR_CR3_REG18_RDY	BIT(29)
25 #define PWR_CR3_REG11_EN	BIT(30)
26 #define PWR_CR3_REG11_RDY	BIT(31)
27 
28 #define TIMEOUT_US_10MS		U(10000)
29 
30 #define VOLTAGE_2V7_THREDSHOLD_UV	2700000
31 
32 struct pwr_regu_desc {
33 	unsigned int level_mv;
34 	uint32_t cr3_enable_mask;
35 	uint32_t cr3_ready_mask;
36 };
37 
38 static const struct pwr_regu_desc pwr_regulators[PWR_REGU_COUNT] = {
39 	 [PWR_REG11] = {
40 		 .level_mv = 1100,
41 		 .cr3_enable_mask = PWR_CR3_REG11_EN,
42 		 .cr3_ready_mask = PWR_CR3_REG11_RDY,
43 	 },
44 	 [PWR_REG18] = {
45 		 .level_mv = 1800,
46 		 .cr3_enable_mask = PWR_CR3_REG18_EN,
47 		 .cr3_ready_mask = PWR_CR3_REG18_RDY,
48 	 },
49 	 [PWR_USB33] = {
50 		 .level_mv = 3300,
51 		 .cr3_enable_mask = PWR_CR3_USB33_EN,
52 		 .cr3_ready_mask = PWR_CR3_USB33_RDY,
53 	 },
54 };
55 
stm32_pwr_base(void)56 vaddr_t stm32_pwr_base(void)
57 {
58 	static struct io_pa_va base = { .pa = PWR_BASE };
59 
60 	return io_pa_or_va_secure(&base, 1);
61 }
62 
stm32mp1_pwr_regulator_mv(enum pwr_regulator id)63 unsigned int stm32mp1_pwr_regulator_mv(enum pwr_regulator id)
64 {
65 	assert(id < PWR_REGU_COUNT);
66 
67 	return pwr_regulators[id].level_mv;
68 }
69 
stm32mp1_pwr_regulator_set_state(enum pwr_regulator id,bool enable)70 void stm32mp1_pwr_regulator_set_state(enum pwr_regulator id, bool enable)
71 {
72 	uintptr_t cr3 = stm32_pwr_base() + PWR_CR3_OFF;
73 	uint32_t enable_mask = pwr_regulators[id].cr3_enable_mask;
74 
75 	assert(id < PWR_REGU_COUNT);
76 
77 	if (enable) {
78 		uint32_t ready_mask = pwr_regulators[id].cr3_ready_mask;
79 		uint64_t to = 0;
80 
81 		io_setbits32(cr3, enable_mask);
82 
83 		to = timeout_init_us(10 * 1000);
84 		while (!timeout_elapsed(to))
85 			if (io_read32(cr3) & ready_mask)
86 				break;
87 
88 		if (!(io_read32(cr3) & ready_mask))
89 			panic();
90 	} else {
91 		io_clrbits32(cr3, enable_mask);
92 	}
93 }
94 
stm32mp1_pwr_regulator_is_enabled(enum pwr_regulator id)95 bool stm32mp1_pwr_regulator_is_enabled(enum pwr_regulator id)
96 {
97 	assert(id < PWR_REGU_COUNT);
98 
99 	return io_read32(stm32_pwr_base() + PWR_CR3_OFF) &
100 	       pwr_regulators[id].cr3_enable_mask;
101 }
102 
stm32mp1_pwr_regu_set_state(struct regulator * regu,bool enable)103 static TEE_Result stm32mp1_pwr_regu_set_state(struct regulator *regu,
104 					      bool enable)
105 {
106 	const struct pwr_regu_desc *desc = regu->priv;
107 	uintptr_t cr3 = stm32_pwr_base() + PWR_CR3_OFF;
108 
109 	assert(desc);
110 
111 	if (enable) {
112 		uint32_t value = 0;
113 
114 		io_setbits32_stm32shregs(cr3, desc->cr3_enable_mask);
115 
116 		if (IO_READ32_POLL_TIMEOUT(cr3, value,
117 					   value & desc->cr3_ready_mask,
118 					   0, TIMEOUT_US_10MS))
119 			return TEE_ERROR_GENERIC;
120 	} else {
121 		io_clrbits32_stm32shregs(cr3, desc->cr3_enable_mask);
122 	}
123 
124 	return TEE_SUCCESS;
125 }
126 
stm32mp1_pwr_regu_read_state(struct regulator * regu,bool * enabled)127 static TEE_Result stm32mp1_pwr_regu_read_state(struct regulator *regu,
128 					       bool *enabled)
129 {
130 	const struct pwr_regu_desc *desc = regu->priv;
131 
132 	assert(desc);
133 
134 	*enabled = io_read32(stm32_pwr_base() + PWR_CR3_OFF) &
135 		   desc->cr3_enable_mask;
136 
137 	return TEE_SUCCESS;
138 }
139 
stm32mp1_pwr_regu_read_voltage(struct regulator * regu,int * level_uv)140 static TEE_Result stm32mp1_pwr_regu_read_voltage(struct regulator *regu,
141 						 int *level_uv)
142 {
143 	const struct pwr_regu_desc *desc = regu->priv;
144 
145 	assert(desc);
146 
147 	*level_uv = (int)desc->level_mv * 1000;
148 
149 	return TEE_SUCCESS;
150 }
151 
152 static const struct regulator_ops stm32mp1_pwr_regu_ops = {
153 	.set_state = stm32mp1_pwr_regu_set_state,
154 	.get_state = stm32mp1_pwr_regu_read_state,
155 	.get_voltage = stm32mp1_pwr_regu_read_voltage,
156 };
157 
158 /* Preallocated regulator devices */
159 static struct regulator pwr_regu_device[PWR_REGU_COUNT];
160 
161 #define DEFINE_REG(_id, _name, _supply) { \
162 	.ops = &stm32mp1_pwr_regu_ops, \
163 	.name = _name, \
164 	.supply_name = _supply, \
165 	.priv = (void *)(pwr_regulators + (_id)), \
166 	.regulator = pwr_regu_device + (_id), \
167 }
168 
169 static const struct regu_dt_desc stm32mp1_pwr_regu_dt_desc[] = {
170 	[PWR_REG11] = DEFINE_REG(PWR_REG11, "reg11", "vdd"),
171 	[PWR_REG18] = DEFINE_REG(PWR_REG18, "reg18", "vdd"),
172 	[PWR_USB33] = DEFINE_REG(PWR_USB33, "usb33", "vdd_3v3_usbfs"),
173 };
174 DECLARE_KEEP_PAGER(stm32mp1_pwr_regu_dt_desc);
175 
stm32mp1_pwr_get_regulator(enum pwr_regulator id)176 struct regulator *stm32mp1_pwr_get_regulator(enum pwr_regulator id)
177 {
178 	if (id < ARRAY_SIZE(pwr_regu_device))
179 		return pwr_regu_device + id;
180 
181 	return NULL;
182 }
183 
vdd_hslv_pm(enum pm_op op,uint32_t pm_hint __unused,const struct pm_callback_handle * pm_hdl __unused)184 static TEE_Result vdd_hslv_pm(enum pm_op op, uint32_t pm_hint __unused,
185 			      const struct pm_callback_handle *pm_hdl __unused)
186 {
187 	if (op == PM_OP_RESUME)
188 		stm32mp_enable_fixed_vdd_hslv();
189 
190 	return TEE_SUCCESS;
191 }
192 DECLARE_KEEP_PAGER(vdd_hslv_pm);
193 
set_fixed_vdd_hslv_mode(struct regulator * vdd_supply)194 static TEE_Result set_fixed_vdd_hslv_mode(struct regulator *vdd_supply)
195 {
196 	TEE_Result res = TEE_ERROR_GENERIC;
197 	bool product_below_2v5 = false;
198 	uint32_t otp_value = 0;
199 	uint32_t otp_id = 0;
200 
201 	/*
202 	 * High Speed Low Voltage Pad mode Enable for SPI, SDMMC, ETH, QSPI
203 	 * and TRACE. Needed above ~50MHz and conditioned by AFMUX selection.
204 	 * It could be disabled for low frequencies or if AFMUX is selected
205 	 * but the function is not used, typically for TRACE.
206 	 * If high speed low voltage pad mode is enabled, platform will
207 	 * over consume.
208 	 *
209 	 * WARNING:
210 	 *   Enabling High Speed mode while Vdd > 2.7V
211 	 *   with the OTP product_below_2v5 (OTP 18, BIT 13)
212 	 *   erroneously set to 1 can damage the SoC.
213 	 */
214 	res = stm32_bsec_find_otp_in_nvmem_layout("hw2_otp", &otp_id,
215 						  NULL, NULL);
216 	if (res)
217 		panic();
218 
219 	res = stm32_bsec_read_otp(&otp_value, otp_id);
220 	if (res)
221 		panic();
222 
223 	if (otp_value & HW2_OTP_PRODUCT_BELOW_2V5)
224 		product_below_2v5 = true;
225 
226 	if (regulator_get_voltage(vdd_supply) < VOLTAGE_2V7_THREDSHOLD_UV) {
227 		if (!product_below_2v5) {
228 			DMSG("Vdd domains HSLV protected by HW");
229 		} else {
230 			stm32mp_enable_fixed_vdd_hslv();
231 			register_pm_driver_cb(vdd_hslv_pm, NULL,
232 					      "stm32mp1-pwr-hslv");
233 		}
234 	} else if (product_below_2v5) {
235 		panic("Vdd too high for related IO domains");
236 	}
237 
238 	return TEE_SUCCESS;
239 }
240 
stm32mp1_pwr_regu_probe(const void * fdt,int node,const void * compat_data __unused)241 static TEE_Result stm32mp1_pwr_regu_probe(const void *fdt, int node,
242 					  const void *compat_data __unused)
243 {
244 	TEE_Result res = TEE_ERROR_GENERIC;
245 	const struct regu_dt_desc *dt_desc = stm32mp1_pwr_regu_dt_desc;
246 	struct regulator *vdd_supply = NULL;
247 	int subnode = 0;
248 
249 	/* Setup High Speed Low Voltage mode for fixed VDD domain */
250 	res = regulator_dt_get_supply(fdt, node, "vdd", &vdd_supply);
251 	if (res)
252 		return res;
253 
254 	res = set_fixed_vdd_hslv_mode(vdd_supply);
255 	if (res)
256 		return res;
257 
258 	/* Register PWR regulators */
259 	fdt_for_each_subnode(subnode, fdt, node) {
260 		const char *node_name = fdt_get_name(fdt, subnode, NULL);
261 		unsigned int n = 0;
262 
263 		for (n = 0; n < ARRAY_SIZE(stm32mp1_pwr_regu_dt_desc); n++)
264 			if (!strcmp(dt_desc[n].name, node_name))
265 				break;
266 
267 		if (n >= ARRAY_SIZE(stm32mp1_pwr_regu_dt_desc)) {
268 			EMSG("Invalid PWR regulator node %s", node_name);
269 			panic();
270 		}
271 
272 		res = regulator_dt_register(fdt, subnode, node, dt_desc + n);
273 		if (res) {
274 			EMSG("Can't register %s: %#"PRIx32, node_name, res);
275 			panic();
276 		}
277 	}
278 
279 	return TEE_SUCCESS;
280 }
281 
282 static const struct dt_device_match stm32mp1_pwr_regu_match_table[] = {
283 	{ .compatible = "st,stm32mp1-pwr-reg" },
284 	{ }
285 };
286 
287 DEFINE_DT_DRIVER(stm32mp1_pwr_regu_dt_driver) = {
288 	.name = "stm32mp1-pwr-regu",
289 	.match_table = stm32mp1_pwr_regu_match_table,
290 	.probe = stm32mp1_pwr_regu_probe,
291 };
292