xref: /rk3399_ARM-atf/drivers/st/gpio/stm32_gpio.c (revision 4156d4daa8c4f5de7e71d5c497cb466cf4cb83e6)
16a339a49SYann Gautier /*
2*4156d4daSYann Gautier  * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
36a339a49SYann Gautier  *
46a339a49SYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
56a339a49SYann Gautier  */
66a339a49SYann Gautier 
76a339a49SYann Gautier #include <stdbool.h>
809d40e0eSAntonio Nino Diaz 
909d40e0eSAntonio Nino Diaz #include <common/bl_common.h>
1009d40e0eSAntonio Nino Diaz #include <common/debug.h>
1109d40e0eSAntonio Nino Diaz #include <drivers/st/stm32_gpio.h>
1209d40e0eSAntonio Nino Diaz #include <lib/mmio.h>
136a339a49SYann Gautier 
146a339a49SYann Gautier static bool check_gpio(uint32_t bank, uint32_t pin)
156a339a49SYann Gautier {
166a339a49SYann Gautier 	if (pin > GPIO_PIN_MAX) {
176a339a49SYann Gautier 		ERROR("%s: wrong pin number (%d)\n", __func__, pin);
186a339a49SYann Gautier 		return false;
196a339a49SYann Gautier 	}
206a339a49SYann Gautier 
216a339a49SYann Gautier 	if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
226a339a49SYann Gautier 		ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
236a339a49SYann Gautier 		return false;
246a339a49SYann Gautier 	}
256a339a49SYann Gautier 
266a339a49SYann Gautier 	return true;
276a339a49SYann Gautier }
286a339a49SYann Gautier 
296a339a49SYann Gautier void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
306a339a49SYann Gautier 	      uint32_t pull, uint32_t alternate)
316a339a49SYann Gautier {
32*4156d4daSYann Gautier 	uintptr_t base;
336a339a49SYann Gautier 
346a339a49SYann Gautier 	if (!check_gpio(bank, pin)) {
356a339a49SYann Gautier 		return;
366a339a49SYann Gautier 	}
376a339a49SYann Gautier 
386a339a49SYann Gautier 	if (bank == GPIO_BANK_Z) {
39*4156d4daSYann Gautier 		base = STM32_GPIOZ_BANK;
406a339a49SYann Gautier 	} else {
41*4156d4daSYann Gautier 		base = STM32_GPIOA_BANK +
426a339a49SYann Gautier 			(bank * STM32_GPIO_BANK_OFFSET);
436a339a49SYann Gautier 	}
446a339a49SYann Gautier 
45*4156d4daSYann Gautier 	mmio_clrbits_32(base + GPIO_MODE_OFFSET,
466a339a49SYann Gautier 			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
47*4156d4daSYann Gautier 	mmio_setbits_32(base + GPIO_MODE_OFFSET,
486a339a49SYann Gautier 			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
496a339a49SYann Gautier 
506a339a49SYann Gautier 	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
51*4156d4daSYann Gautier 		mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
52*4156d4daSYann Gautier 	} else {
53*4156d4daSYann Gautier 		mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
546a339a49SYann Gautier 	}
556a339a49SYann Gautier 
56*4156d4daSYann Gautier 	mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
576a339a49SYann Gautier 			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
58*4156d4daSYann Gautier 	mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
596a339a49SYann Gautier 
60*4156d4daSYann Gautier 	mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
616a339a49SYann Gautier 			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
62*4156d4daSYann Gautier 	mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
636a339a49SYann Gautier 
646a339a49SYann Gautier 	if (pin < GPIO_ALT_LOWER_LIMIT) {
65*4156d4daSYann Gautier 		mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
666a339a49SYann Gautier 				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
67*4156d4daSYann Gautier 		mmio_setbits_32(base + GPIO_AFRL_OFFSET,
686a339a49SYann Gautier 				alternate << (pin << 2));
696a339a49SYann Gautier 	} else {
70*4156d4daSYann Gautier 		mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
716a339a49SYann Gautier 				((uint32_t)GPIO_ALTERNATE_MASK <<
726a339a49SYann Gautier 				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
73*4156d4daSYann Gautier 		mmio_setbits_32(base + GPIO_AFRH_OFFSET,
746a339a49SYann Gautier 				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
756a339a49SYann Gautier 					      2));
766a339a49SYann Gautier 	}
776a339a49SYann Gautier 
786a339a49SYann Gautier 	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
79*4156d4daSYann Gautier 		mmio_read_32(base + GPIO_MODE_OFFSET));
806a339a49SYann Gautier 	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
81*4156d4daSYann Gautier 		mmio_read_32(base + GPIO_SPEED_OFFSET));
826a339a49SYann Gautier 	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
83*4156d4daSYann Gautier 		mmio_read_32(base + GPIO_PUPD_OFFSET));
846a339a49SYann Gautier 	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
85*4156d4daSYann Gautier 		mmio_read_32(base + GPIO_AFRL_OFFSET));
866a339a49SYann Gautier 	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
87*4156d4daSYann Gautier 		mmio_read_32(base + GPIO_AFRH_OFFSET));
886a339a49SYann Gautier }
89