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