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