xref: /optee_os/core/drivers/stm32_gpio.c (revision 9fc2442cc66c279cb962c90c4375746fc9b28bb9)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3  * Copyright (c) 2017-2019, STMicroelectronics
4  *
5  * STM32 GPIO driver is used as pin controller for stm32mp SoCs.
6  * The driver API is defined in header file stm32_gpio.h.
7  */
8 
9 #include <assert.h>
10 #include <drivers/stm32_gpio.h>
11 #include <io.h>
12 #include <kernel/dt.h>
13 #include <kernel/boot.h>
14 #include <kernel/panic.h>
15 #include <kernel/spinlock.h>
16 #include <libfdt.h>
17 #include <mm/core_memprot.h>
18 #include <stdbool.h>
19 #include <stm32_util.h>
20 #include <trace.h>
21 #include <util.h>
22 
23 #define GPIO_PIN_MAX		15
24 
25 #define GPIO_MODER_OFFSET	0x00
26 #define GPIO_OTYPER_OFFSET	0x04
27 #define GPIO_OSPEEDR_OFFSET	0x08
28 #define GPIO_PUPDR_OFFSET	0x0c
29 #define GPIO_IDR_OFFSET		0x10
30 #define GPIO_ODR_OFFSET		0x14
31 #define GPIO_BSRR_OFFSET	0x18
32 #define GPIO_AFRL_OFFSET	0x20
33 #define GPIO_AFRH_OFFSET	0x24
34 #define GPIO_SECR_OFFSET	0x30
35 
36 #define GPIO_ALT_LOWER_LIMIT	0x8
37 
38 #define GPIO_MODE_MASK		GENMASK_32(1, 0)
39 #define GPIO_OSPEED_MASK	GENMASK_32(1, 0)
40 #define GPIO_PUPD_PULL_MASK	GENMASK_32(1, 0)
41 #define GPIO_ALTERNATE_MASK	GENMASK_32(3, 0)
42 
43 #define DT_GPIO_BANK_SHIFT	12
44 #define DT_GPIO_BANK_MASK	GENMASK_32(16, 12)
45 #define DT_GPIO_PIN_SHIFT	8
46 #define DT_GPIO_PIN_MASK	GENMASK_32(11, 8)
47 #define DT_GPIO_MODE_MASK	GENMASK_32(7, 0)
48 
49 static unsigned int gpio_lock;
50 
51 /* Save to output @cfg the current GPIO (@bank/@pin) configuration */
52 static void get_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg)
53 {
54 	vaddr_t base = stm32_get_gpio_bank_base(bank);
55 	unsigned int clock = stm32_get_gpio_bank_clock(bank);
56 
57 	stm32_clock_enable(clock);
58 
59 	/*
60 	 * Save GPIO configuration bits spread over the few bank registers.
61 	 * 1bit fields are accessed at bit position being the pin index.
62 	 * 2bit fields are accessed at bit position being twice the pin index.
63 	 * 4bit fields are accessed at bit position being fourth the pin index
64 	 * but accessed from 2 32bit registers at incremental addresses.
65 	 */
66 	cfg->mode = (io_read32(base + GPIO_MODER_OFFSET) >> (pin << 1)) &
67 		     GPIO_MODE_MASK;
68 
69 	cfg->otype = (io_read32(base + GPIO_OTYPER_OFFSET) >> pin) & 1;
70 
71 	cfg->ospeed = (io_read32(base +  GPIO_OSPEEDR_OFFSET) >> (pin << 1)) &
72 		       GPIO_OSPEED_MASK;
73 
74 	cfg->pupd = (io_read32(base +  GPIO_PUPDR_OFFSET) >> (pin << 1)) &
75 		     GPIO_PUPD_PULL_MASK;
76 
77 	cfg->od = (io_read32(base + GPIO_ODR_OFFSET) >> (pin << 1)) & 1;
78 
79 	if (pin < GPIO_ALT_LOWER_LIMIT)
80 		cfg->af = (io_read32(base + GPIO_AFRL_OFFSET) >> (pin << 2)) &
81 			   GPIO_ALTERNATE_MASK;
82 	else
83 		cfg->af = (io_read32(base + GPIO_AFRH_OFFSET) >>
84 			    ((pin - GPIO_ALT_LOWER_LIMIT) << 2)) &
85 			   GPIO_ALTERNATE_MASK;
86 
87 	stm32_clock_disable(clock);
88 }
89 
90 /* Apply GPIO (@bank/@pin) configuration described by @cfg */
91 static void set_gpio_cfg(uint32_t bank, uint32_t pin, struct gpio_cfg *cfg)
92 {
93 	vaddr_t base = stm32_get_gpio_bank_base(bank);
94 	unsigned int clock = stm32_get_gpio_bank_clock(bank);
95 	uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock);
96 
97 	stm32_clock_enable(clock);
98 
99 	/* Load GPIO MODE value, 2bit value shifted by twice the pin number */
100 	io_clrsetbits32(base + GPIO_MODER_OFFSET,
101 			GPIO_MODE_MASK << (pin << 1),
102 			cfg->mode << (pin << 1));
103 
104 	/* Load GPIO Output TYPE value, 1bit shifted by pin number value */
105 	io_clrsetbits32(base + GPIO_OTYPER_OFFSET, BIT(pin), cfg->otype << pin);
106 
107 	/* Load GPIO Output Speed confguration, 2bit value */
108 	io_clrsetbits32(base + GPIO_OSPEEDR_OFFSET,
109 			GPIO_OSPEED_MASK << (pin << 1),
110 			cfg->ospeed << (pin << 1));
111 
112 	/* Load GPIO pull configuration, 2bit value */
113 	io_clrsetbits32(base + GPIO_PUPDR_OFFSET, BIT(pin),
114 			cfg->pupd << (pin << 1));
115 
116 	/* Load pin mux Alternate Function configuration, 4bit value */
117 	if (pin < GPIO_ALT_LOWER_LIMIT) {
118 		io_clrsetbits32(base + GPIO_AFRL_OFFSET,
119 				GPIO_ALTERNATE_MASK << (pin << 2),
120 				cfg->af << (pin << 2));
121 	} else {
122 		size_t shift = (pin - GPIO_ALT_LOWER_LIMIT) << 2;
123 
124 		io_clrsetbits32(base + GPIO_AFRH_OFFSET,
125 				GPIO_ALTERNATE_MASK << shift,
126 				cfg->af << shift);
127 	}
128 
129 	/* Load GPIO Output direction confuguration, 1bit */
130 	io_clrsetbits32(base + GPIO_ODR_OFFSET, BIT(pin), cfg->od << pin);
131 
132 	stm32_clock_disable(clock);
133 	cpu_spin_unlock_xrestore(&gpio_lock, exceptions);
134 }
135 
136 void stm32_pinctrl_load_active_cfg(struct stm32_pinctrl *pinctrl, size_t cnt)
137 {
138 	size_t n = 0;
139 
140 	for (n = 0; n < cnt; n++)
141 		set_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin,
142 			     &pinctrl[n].active_cfg);
143 }
144 
145 void stm32_pinctrl_load_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt)
146 {
147 	size_t n = 0;
148 
149 	for (n = 0; n < cnt; n++)
150 		set_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin,
151 			     &pinctrl[n].standby_cfg);
152 }
153 
154 void stm32_pinctrl_store_standby_cfg(struct stm32_pinctrl *pinctrl, size_t cnt)
155 {
156 	size_t n = 0;
157 
158 	for (n = 0; n < cnt; n++)
159 		get_gpio_cfg(pinctrl[n].bank, pinctrl[n].pin,
160 			     &pinctrl[n].standby_cfg);
161 }
162 
163 #ifdef CFG_DT
164 /* Panic if GPIO bank information from platform do not match DTB description */
165 static void ckeck_gpio_bank(void *fdt, uint32_t bank, int pinctrl_node)
166 {
167 	int pinctrl_subnode = 0;
168 
169 	fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
170 		const fdt32_t *cuint = NULL;
171 
172 		if (fdt_getprop(fdt, pinctrl_subnode,
173 				"gpio-controller", NULL) == NULL)
174 			continue;
175 
176 		/* Check bank register offset matches platform assumptions */
177 		cuint = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
178 		if (fdt32_to_cpu(*cuint) != stm32_get_gpio_bank_offset(bank))
179 			continue;
180 
181 		/* Check bank clock matches platform assumptions */
182 		cuint = fdt_getprop(fdt, pinctrl_subnode, "clocks", NULL);
183 		if (!cuint)
184 			panic();
185 		cuint++;
186 		if (fdt32_to_cpu(*cuint) != stm32_get_gpio_bank_clock(bank))
187 			panic();
188 
189 		/* Check controller is enabled */
190 		if (_fdt_get_status(fdt, pinctrl_subnode) == DT_STATUS_DISABLED)
191 			panic();
192 
193 		return;
194 	}
195 
196 	panic();
197 }
198 
199 /* Count pins described in the DT node and get related data if possible */
200 static int get_pinctrl_from_fdt(void *fdt, int node,
201 				struct stm32_pinctrl *pinctrl, size_t count)
202 {
203 	const fdt32_t *cuint, *slewrate;
204 	int len = 0;
205 	int pinctrl_node = 0;
206 	uint32_t i = 0;
207 	uint32_t speed = GPIO_OSPEED_LOW;
208 	uint32_t pull = GPIO_PUPD_NO_PULL;
209 	size_t found = 0;
210 
211 	cuint = fdt_getprop(fdt, node, "pinmux", &len);
212 	if (!cuint)
213 		return -FDT_ERR_NOTFOUND;
214 
215 	pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
216 	if (pinctrl_node < 0)
217 		return -FDT_ERR_NOTFOUND;
218 
219 	slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
220 	if (slewrate)
221 		speed = fdt32_to_cpu(*slewrate);
222 
223 	if (fdt_getprop(fdt, node, "bias-pull-up", NULL))
224 		pull = GPIO_PUPD_PULL_UP;
225 	if (fdt_getprop(fdt, node, "bias-pull-down", NULL))
226 		pull = GPIO_PUPD_PULL_DOWN;
227 
228 	for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
229 		uint32_t pincfg = 0;
230 		uint32_t bank = 0;
231 		uint32_t pin = 0;
232 		uint32_t mode = 0;
233 		uint32_t alternate = 0;
234 		bool opendrain = false;
235 
236 		pincfg = fdt32_to_cpu(*cuint);
237 		cuint++;
238 
239 		bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
240 
241 		pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
242 
243 		mode = pincfg & DT_GPIO_MODE_MASK;
244 
245 		switch (mode) {
246 		case 0:
247 			mode = GPIO_MODE_INPUT;
248 			break;
249 		case 1:
250 		case 2:
251 		case 3:
252 		case 4:
253 		case 5:
254 		case 6:
255 		case 7:
256 		case 8:
257 		case 9:
258 		case 10:
259 		case 11:
260 		case 12:
261 		case 13:
262 		case 14:
263 		case 15:
264 		case 16:
265 			alternate = mode - 1U;
266 			mode = GPIO_MODE_ALTERNATE;
267 			break;
268 		case 17:
269 			mode = GPIO_MODE_ANALOG;
270 			break;
271 		default:
272 			mode = GPIO_MODE_OUTPUT;
273 			break;
274 		}
275 
276 		if (fdt_getprop(fdt, node, "drive-open-drain", NULL))
277 			opendrain = true;
278 
279 		/* Check GPIO bank clock/base address against platform */
280 		ckeck_gpio_bank(fdt, bank, pinctrl_node);
281 
282 		if (found < count) {
283 			struct stm32_pinctrl *ref = &pinctrl[found];
284 
285 			ref->bank = (uint8_t)bank;
286 			ref->pin = (uint8_t)pin;
287 			ref->active_cfg.mode = mode;
288 			ref->active_cfg.otype = opendrain ? 1 : 0;
289 			ref->active_cfg.ospeed = speed;
290 			ref->active_cfg.pupd = pull;
291 			ref->active_cfg.od = 0;
292 			ref->active_cfg.af = alternate;
293 			/* Default to analog mode for standby state */
294 			ref->standby_cfg.mode = GPIO_MODE_ANALOG;
295 			ref->standby_cfg.pupd = GPIO_PUPD_NO_PULL;
296 		}
297 
298 		found++;
299 	}
300 
301 	return (int)found;
302 }
303 
304 int stm32_pinctrl_fdt_get_pinctrl(void *fdt, int device_node,
305 				  struct stm32_pinctrl *pinctrl, size_t count)
306 {
307 	const fdt32_t *cuint = NULL;
308 	int lenp = 0;
309 	int i = 0;
310 	size_t found = 0;
311 
312 	cuint = fdt_getprop(fdt, device_node, "pinctrl-0", &lenp);
313 	if (!cuint)
314 		return -FDT_ERR_NOTFOUND;
315 
316 	for (i = 0; i < (lenp / 4); i++) {
317 		int node = 0;
318 		int subnode = 0;
319 
320 		node = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
321 		if (node < 0)
322 			return -FDT_ERR_NOTFOUND;
323 
324 		fdt_for_each_subnode(subnode, fdt, node) {
325 			size_t n = 0;
326 			int rc = 0;
327 
328 			if (count > found)
329 				n = count - found;
330 			else
331 				n = 0;
332 
333 			rc = get_pinctrl_from_fdt(fdt, subnode,
334 						  &pinctrl[found], n);
335 			if (rc < 0)
336 				return rc;
337 
338 			found += (size_t)rc;
339 		}
340 
341 		cuint++;
342 	}
343 
344 	return (int)found;
345 }
346 
347 int stm32_get_gpio_count(void *fdt, int pinctrl_node, unsigned int bank)
348 {
349 	int node = 0;
350 	const fdt32_t *cuint = NULL;
351 
352 	fdt_for_each_subnode(node, fdt, pinctrl_node) {
353 		if (!fdt_getprop(fdt, node, "gpio-controller", NULL))
354 			continue;
355 
356 		cuint = fdt_getprop(fdt, node, "reg", NULL);
357 		if (!cuint)
358 			continue;
359 
360 		if (fdt32_to_cpu(*cuint) != stm32_get_gpio_bank_offset(bank))
361 			continue;
362 
363 		cuint = fdt_getprop(fdt, node, "ngpios", NULL);
364 		if (!cuint)
365 			panic();
366 
367 		return (int)fdt32_to_cpu(*cuint);
368 	}
369 
370 	return -1;
371 }
372 #endif /*CFG_DT*/
373 
374 static __maybe_unused bool valid_gpio_config(unsigned int bank,
375 					     unsigned int pin, bool input)
376 {
377 	vaddr_t base = stm32_get_gpio_bank_base(bank);
378 	uint32_t mode = (io_read32(base + GPIO_MODER_OFFSET) >> (pin << 1)) &
379 			GPIO_MODE_MASK;
380 
381 	if (pin > GPIO_PIN_MAX)
382 		return false;
383 
384 	if (input)
385 		return mode == GPIO_MODE_INPUT;
386 	else
387 		return mode == GPIO_MODE_OUTPUT;
388 }
389 
390 int stm32_gpio_get_input_level(unsigned int bank, unsigned int pin)
391 {
392 	vaddr_t base = stm32_get_gpio_bank_base(bank);
393 	unsigned int clock = stm32_get_gpio_bank_clock(bank);
394 	int rc = 0;
395 
396 	assert(valid_gpio_config(bank, pin, true));
397 
398 	stm32_clock_enable(clock);
399 
400 	if (io_read32(base + GPIO_IDR_OFFSET) == BIT(pin))
401 		rc = 1;
402 
403 	stm32_clock_disable(clock);
404 
405 	return rc;
406 }
407 
408 void stm32_gpio_set_output_level(unsigned int bank, unsigned int pin, int level)
409 {
410 	vaddr_t base = stm32_get_gpio_bank_base(bank);
411 	unsigned int clock = stm32_get_gpio_bank_clock(bank);
412 
413 	assert(valid_gpio_config(bank, pin, false));
414 
415 	stm32_clock_enable(clock);
416 
417 	if (level)
418 		io_write32(base + GPIO_BSRR_OFFSET, BIT(pin));
419 	else
420 		io_write32(base + GPIO_BSRR_OFFSET, BIT(pin + 16));
421 
422 	stm32_clock_disable(clock);
423 }
424 
425 void stm32_gpio_set_secure_cfg(unsigned int bank, unsigned int pin, bool secure)
426 {
427 	vaddr_t base = stm32_get_gpio_bank_base(bank);
428 	unsigned int clock = stm32_get_gpio_bank_clock(bank);
429 	uint32_t exceptions = cpu_spin_lock_xsave(&gpio_lock);
430 
431 	stm32_clock_enable(clock);
432 
433 	if (secure)
434 		io_setbits32(base + GPIO_SECR_OFFSET, BIT(pin));
435 	else
436 		io_clrbits32(base + GPIO_SECR_OFFSET, BIT(pin));
437 
438 	stm32_clock_disable(clock);
439 	cpu_spin_unlock_xrestore(&gpio_lock, exceptions);
440 }
441