16a339a49SYann Gautier /* 26a339a49SYann Gautier * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved 36a339a49SYann Gautier * 46a339a49SYann Gautier * SPDX-License-Identifier: BSD-3-Clause 56a339a49SYann Gautier */ 66a339a49SYann Gautier 76a339a49SYann Gautier #include <stdbool.h> 8*09d40e0eSAntonio Nino Diaz 9*09d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 10*09d40e0eSAntonio Nino Diaz #include <common/debug.h> 11*09d40e0eSAntonio Nino Diaz #include <drivers/st/stm32_gpio.h> 12*09d40e0eSAntonio 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 { 326a339a49SYann Gautier volatile uint32_t bank_address; 336a339a49SYann Gautier 346a339a49SYann Gautier if (!check_gpio(bank, pin)) { 356a339a49SYann Gautier return; 366a339a49SYann Gautier } 376a339a49SYann Gautier 386a339a49SYann Gautier if (bank == GPIO_BANK_Z) { 396a339a49SYann Gautier bank_address = STM32_GPIOZ_BANK; 406a339a49SYann Gautier } else { 416a339a49SYann Gautier bank_address = STM32_GPIOA_BANK + 426a339a49SYann Gautier (bank * STM32_GPIO_BANK_OFFSET); 436a339a49SYann Gautier } 446a339a49SYann Gautier 456a339a49SYann Gautier mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET, 466a339a49SYann Gautier ((uint32_t)GPIO_MODE_MASK << (pin << 1))); 476a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_MODE_OFFSET, 486a339a49SYann Gautier (mode & ~GPIO_OPEN_DRAIN) << (pin << 1)); 496a339a49SYann Gautier 506a339a49SYann Gautier if ((mode & GPIO_OPEN_DRAIN) != 0U) { 516a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET, 526a339a49SYann Gautier BIT(pin)); 536a339a49SYann Gautier } 546a339a49SYann Gautier 556a339a49SYann Gautier mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET, 566a339a49SYann Gautier ((uint32_t)GPIO_SPEED_MASK << (pin << 1))); 576a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1)); 586a339a49SYann Gautier 596a339a49SYann Gautier mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET, 606a339a49SYann Gautier ((uint32_t)GPIO_PULL_MASK << (pin << 1))); 616a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1)); 626a339a49SYann Gautier 636a339a49SYann Gautier if (pin < GPIO_ALT_LOWER_LIMIT) { 646a339a49SYann Gautier mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET, 656a339a49SYann Gautier ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2))); 666a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET, 676a339a49SYann Gautier alternate << (pin << 2)); 686a339a49SYann Gautier } else { 696a339a49SYann Gautier mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET, 706a339a49SYann Gautier ((uint32_t)GPIO_ALTERNATE_MASK << 716a339a49SYann Gautier ((pin - GPIO_ALT_LOWER_LIMIT) << 2))); 726a339a49SYann Gautier mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET, 736a339a49SYann Gautier alternate << ((pin - GPIO_ALT_LOWER_LIMIT) << 746a339a49SYann Gautier 2)); 756a339a49SYann Gautier } 766a339a49SYann Gautier 776a339a49SYann Gautier VERBOSE("GPIO %u mode set to 0x%x\n", bank, 786a339a49SYann Gautier mmio_read_32(bank_address + GPIO_MODE_OFFSET)); 796a339a49SYann Gautier VERBOSE("GPIO %u speed set to 0x%x\n", bank, 806a339a49SYann Gautier mmio_read_32(bank_address + GPIO_SPEED_OFFSET)); 816a339a49SYann Gautier VERBOSE("GPIO %u mode pull to 0x%x\n", bank, 826a339a49SYann Gautier mmio_read_32(bank_address + GPIO_PUPD_OFFSET)); 836a339a49SYann Gautier VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank, 846a339a49SYann Gautier mmio_read_32(bank_address + GPIO_AFRL_OFFSET)); 856a339a49SYann Gautier VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank, 866a339a49SYann Gautier mmio_read_32(bank_address + GPIO_AFRH_OFFSET)); 876a339a49SYann Gautier } 88