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