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