stm32_gpio.c 2.38 KB
Newer Older
Yann Gautier's avatar
Yann Gautier committed
1
/*
2
 * Copyright (c) 2016-2019, STMicroelectronics - All Rights Reserved
Yann Gautier's avatar
Yann Gautier committed
3
4
5
6
7
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdbool.h>
8
9
10
11
12

#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/st/stm32_gpio.h>
#include <lib/mmio.h>
Yann Gautier's avatar
Yann Gautier committed
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

static bool check_gpio(uint32_t bank, uint32_t pin)
{
	if (pin > GPIO_PIN_MAX) {
		ERROR("%s: wrong pin number (%d)\n", __func__, pin);
		return false;
	}

	if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
		ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
		return false;
	}

	return true;
}

void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
	      uint32_t pull, uint32_t alternate)
{
32
	uintptr_t base;
Yann Gautier's avatar
Yann Gautier committed
33
34
35
36
37
38

	if (!check_gpio(bank, pin)) {
		return;
	}

	if (bank == GPIO_BANK_Z) {
39
		base = STM32_GPIOZ_BANK;
Yann Gautier's avatar
Yann Gautier committed
40
	} else {
41
		base = STM32_GPIOA_BANK +
Yann Gautier's avatar
Yann Gautier committed
42
43
44
			(bank * STM32_GPIO_BANK_OFFSET);
	}

45
	mmio_clrbits_32(base + GPIO_MODE_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
46
			((uint32_t)GPIO_MODE_MASK << (pin << 1)));
47
	mmio_setbits_32(base + GPIO_MODE_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
48
49
50
			(mode & ~GPIO_OPEN_DRAIN) << (pin << 1));

	if ((mode & GPIO_OPEN_DRAIN) != 0U) {
51
52
53
		mmio_setbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
	} else {
		mmio_clrbits_32(base + GPIO_TYPE_OFFSET, BIT(pin));
Yann Gautier's avatar
Yann Gautier committed
54
55
	}

56
	mmio_clrbits_32(base + GPIO_SPEED_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
57
			((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
58
	mmio_setbits_32(base + GPIO_SPEED_OFFSET, speed << (pin << 1));
Yann Gautier's avatar
Yann Gautier committed
59

60
	mmio_clrbits_32(base + GPIO_PUPD_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
61
			((uint32_t)GPIO_PULL_MASK << (pin << 1)));
62
	mmio_setbits_32(base + GPIO_PUPD_OFFSET, pull << (pin << 1));
Yann Gautier's avatar
Yann Gautier committed
63
64

	if (pin < GPIO_ALT_LOWER_LIMIT) {
65
		mmio_clrbits_32(base + GPIO_AFRL_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
66
				((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
67
		mmio_setbits_32(base + GPIO_AFRL_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
68
69
				alternate << (pin << 2));
	} else {
70
		mmio_clrbits_32(base + GPIO_AFRH_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
71
72
				((uint32_t)GPIO_ALTERNATE_MASK <<
				 ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
73
		mmio_setbits_32(base + GPIO_AFRH_OFFSET,
Yann Gautier's avatar
Yann Gautier committed
74
75
76
77
78
				alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
					      2));
	}

	VERBOSE("GPIO %u mode set to 0x%x\n", bank,
79
		mmio_read_32(base + GPIO_MODE_OFFSET));
Yann Gautier's avatar
Yann Gautier committed
80
	VERBOSE("GPIO %u speed set to 0x%x\n", bank,
81
		mmio_read_32(base + GPIO_SPEED_OFFSET));
Yann Gautier's avatar
Yann Gautier committed
82
	VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
83
		mmio_read_32(base + GPIO_PUPD_OFFSET));
Yann Gautier's avatar
Yann Gautier committed
84
	VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
85
		mmio_read_32(base + GPIO_AFRL_OFFSET));
Yann Gautier's avatar
Yann Gautier committed
86
	VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
87
		mmio_read_32(base + GPIO_AFRH_OFFSET));
Yann Gautier's avatar
Yann Gautier committed
88
}