xref: /rk3399_ARM-atf/drivers/st/gpio/stm32_gpio.c (revision 09d40e0e08283a249e7dce0e106c07c5141f9b7e)
1 /*
2  * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdbool.h>
8 
9 #include <common/bl_common.h>
10 #include <common/debug.h>
11 #include <drivers/st/stm32_gpio.h>
12 #include <lib/mmio.h>
13 
14 static bool check_gpio(uint32_t bank, uint32_t pin)
15 {
16 	if (pin > GPIO_PIN_MAX) {
17 		ERROR("%s: wrong pin number (%d)\n", __func__, pin);
18 		return false;
19 	}
20 
21 	if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
22 		ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
23 		return false;
24 	}
25 
26 	return true;
27 }
28 
29 void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
30 	      uint32_t pull, uint32_t alternate)
31 {
32 	volatile uint32_t bank_address;
33 
34 	if (!check_gpio(bank, pin)) {
35 		return;
36 	}
37 
38 	if (bank == GPIO_BANK_Z) {
39 		bank_address = STM32_GPIOZ_BANK;
40 	} else {
41 		bank_address = STM32_GPIOA_BANK +
42 			(bank * STM32_GPIO_BANK_OFFSET);
43 	}
44 
45 	mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
46 			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
47 	mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
48 			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
49 
50 	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
51 		mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
52 				BIT(pin));
53 	}
54 
55 	mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
56 			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
57 	mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
58 
59 	mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
60 			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
61 	mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
62 
63 	if (pin < GPIO_ALT_LOWER_LIMIT) {
64 		mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
65 				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
66 		mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
67 				alternate << (pin << 2));
68 	} else {
69 		mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
70 				((uint32_t)GPIO_ALTERNATE_MASK <<
71 				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
72 		mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
73 				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
74 					      2));
75 	}
76 
77 	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
78 		mmio_read_32(bank_address + GPIO_MODE_OFFSET));
79 	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
80 		mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
81 	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
82 		mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
83 	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
84 		mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
85 	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
86 		mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
87 }
88