blob: 200b47340a2e167bcef94a8a92b230c94678af77 [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
7#include <bl_common.h>
8#include <debug.h>
9#include <mmio.h>
10#include <stdbool.h>
11#include <stm32_gpio.h>
12
13static bool check_gpio(uint32_t bank, uint32_t pin)
14{
15 if (pin > GPIO_PIN_MAX) {
16 ERROR("%s: wrong pin number (%d)\n", __func__, pin);
17 return false;
18 }
19
20 if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
21 ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
22 return false;
23 }
24
25 return true;
26}
27
28void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
29 uint32_t pull, uint32_t alternate)
30{
31 volatile uint32_t bank_address;
32
33 if (!check_gpio(bank, pin)) {
34 return;
35 }
36
37 if (bank == GPIO_BANK_Z) {
38 bank_address = STM32_GPIOZ_BANK;
39 } else {
40 bank_address = STM32_GPIOA_BANK +
41 (bank * STM32_GPIO_BANK_OFFSET);
42 }
43
44 mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
45 ((uint32_t)GPIO_MODE_MASK << (pin << 1)));
46 mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
47 (mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
48
49 if ((mode & GPIO_OPEN_DRAIN) != 0U) {
50 mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
51 BIT(pin));
52 }
53
54 mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
55 ((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
56 mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
57
58 mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
59 ((uint32_t)GPIO_PULL_MASK << (pin << 1)));
60 mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
61
62 if (pin < GPIO_ALT_LOWER_LIMIT) {
63 mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
64 ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
65 mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
66 alternate << (pin << 2));
67 } else {
68 mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
69 ((uint32_t)GPIO_ALTERNATE_MASK <<
70 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
71 mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
72 alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
73 2));
74 }
75
76 VERBOSE("GPIO %u mode set to 0x%x\n", bank,
77 mmio_read_32(bank_address + GPIO_MODE_OFFSET));
78 VERBOSE("GPIO %u speed set to 0x%x\n", bank,
79 mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
80 VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
81 mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
82 VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
83 mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
84 VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
85 mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
86}