coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
gpio.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <gpio.h>
5 #include <soc/addressmap.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 
9 #include "pinmux.h"
10 
12 {
13  u32 pinmux_config = PINMUX_INPUT_ENABLE | pull;
14 
18  pinmux_set_config(gpio >> GPIO_PINMUX_SHIFT, pinmux_config);
19 }
20 
21 static void __gpio_output(gpio_t gpio, int value, u32 od)
22 {
28 }
29 
30 static const struct gpio_bank *gpio_banks = (void *)TEGRA_GPIO_BASE;
31 
32 static u32 gpio_read_port(int index, size_t offset)
33 {
34  int bank = index / GPIO_GPIOS_PER_BANK;
35  int port = (index - bank * GPIO_GPIOS_PER_BANK) / GPIO_GPIOS_PER_PORT;
36 
37  return read32((u8 *)&gpio_banks[bank] + offset +
38  port * sizeof(u32));
39 }
40 
41 static void gpio_write_port(int index, size_t offset, u32 mask, u32 value)
42 {
43  int bank = index / GPIO_GPIOS_PER_BANK;
44  int port = (index - bank * GPIO_GPIOS_PER_BANK) / GPIO_GPIOS_PER_PORT;
45 
46  u32 reg = read32((u8 *)&gpio_banks[bank] + offset +
47  port * sizeof(u32));
48  u32 new_reg = (reg & ~mask) | (value & mask);
49 
50  if (new_reg != reg) {
51  write32((u8 *)&gpio_banks[bank] + offset + port * sizeof(u32),
52  new_reg);
53  }
54 }
55 
57 {
58  int bit = gpio % GPIO_GPIOS_PER_PORT;
59  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
60  offsetof(struct gpio_bank, config),
61  1 << bit, mode ? (1 << bit) : 0);
62 }
63 
65 {
66  int bit = gpio % GPIO_GPIOS_PER_PORT;
67  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
68  offsetof(struct gpio_bank, config));
69  return (port & (1 << bit)) != 0;
70 }
71 
73 {
75  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
76  offsetof(struct gpio_bank, config),
77  1 << bit, 1 << bit);
78 }
79 
81 {
83  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
84  offsetof(struct gpio_bank, config));
85  return (port & (1 << bit)) != 0;
86 }
87 
88 void gpio_set_out_enable(gpio_t gpio, int enable)
89 {
90  int bit = gpio % GPIO_GPIOS_PER_PORT;
91  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
92  offsetof(struct gpio_bank, out_enable),
93  1 << bit, enable ? (1 << bit) : 0);
94 }
95 
97 {
98  int bit = gpio % GPIO_GPIOS_PER_PORT;
99  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
100  offsetof(struct gpio_bank, out_enable));
101  return (port & (1 << bit)) != 0;
102 }
103 
105 {
106  int bit = gpio % GPIO_GPIOS_PER_PORT;
107  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
108  offsetof(struct gpio_bank, out_value),
109  1 << bit, value ? (1 << bit) : 0);
110 }
111 
113 {
114  int bit = gpio % GPIO_GPIOS_PER_PORT;
115  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
116  offsetof(struct gpio_bank, out_value));
117  return (port & (1 << bit)) != 0;
118 }
119 
121 {
122  int bit = gpio % GPIO_GPIOS_PER_PORT;
123  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
124  offsetof(struct gpio_bank, in_value));
125  return (port & (1 << bit)) != 0;
126 }
127 
129 {
130  int bit = gpio % GPIO_GPIOS_PER_PORT;
131  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
132  offsetof(struct gpio_bank, int_status));
133  return (port & (1 << bit)) != 0;
134 }
135 
136 void gpio_set_int_enable(gpio_t gpio, int enable)
137 {
138  int bit = gpio % GPIO_GPIOS_PER_PORT;
139  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
140  offsetof(struct gpio_bank, int_enable),
141  1 << bit, enable ? (1 << bit) : 0);
142 }
143 
145 {
146  int bit = gpio % GPIO_GPIOS_PER_PORT;
147  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
148  offsetof(struct gpio_bank, int_enable));
149  return (port & (1 << bit)) != 0;
150 }
151 
152 void gpio_set_int_level(gpio_t gpio, int high_rise, int edge, int delta)
153 {
154  int bit = gpio % GPIO_GPIOS_PER_PORT;
155  u32 value = (high_rise ? (0x000001 << bit) : 0) |
156  (edge ? (0x000100 << bit) : 0) |
157  (delta ? (0x010000 << bit) : 0);
158  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
159  offsetof(struct gpio_bank, config),
160  0x010101 << bit, value);
161 }
162 
163 void gpio_get_int_level(gpio_t gpio, int *high_rise, int *edge, int *delta)
164 {
165  int bit = gpio % GPIO_GPIOS_PER_PORT;
166  u32 port = gpio_read_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
167  offsetof(struct gpio_bank, int_level));
168  *high_rise = ((port & (0x000001 << bit)) != 0);
169  *edge = ((port & (0x000100 << bit)) != 0);
170  *delta = ((port & (0x010000 << bit)) != 0);
171 }
172 
174 {
175  int bit = gpio % GPIO_GPIOS_PER_PORT;
176  gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
177  offsetof(struct gpio_bank, int_clear),
178  1 << bit, 1 << bit);
179 }
180 
182 {
184 }
185 
187 {
189 }
190 
192 {
194 }
195 
197 {
198  __gpio_output(gpio, value, 0);
199 }
200 
202 {
204 }
pte_t value
Definition: mmu.c:91
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define pull
Definition: asmlib.h:26
#define offsetof(TYPE, MEMBER)
Definition: helpers.h:84
static size_t offset
Definition: flashconsole.c:16
port
Definition: i915.h:29
enum board_config config
Definition: memory.c:448
@ PINMUX_INPUT_ENABLE
Definition: pinmux.h:17
@ PINMUX_PULL_NONE
Definition: pinmux.h:12
@ PINMUX_PULL_DOWN
Definition: pinmux.h:13
@ PINMUX_PULL_UP
Definition: pinmux.h:14
@ PINMUX_OPEN_DRAIN
Definition: pinmux.h:18
void pinmux_set_config(int pin_index, uint32_t config)
Definition: pinmux.c:10
void gpio_set(gpio_t gpio_num, int value)
Definition: gpio.c:174
void gpio_output(gpio_t gpio_num, int value)
Definition: gpio.c:194
int gpio_get(gpio_t gpio_num)
Definition: gpio.c:166
void gpio_input_pullup(gpio_t gpio_num)
Definition: gpio.c:184
void gpio_input_pulldown(gpio_t gpio_num)
Definition: gpio.c:179
void gpio_input(gpio_t gpio_num)
Definition: gpio.c:189
static const int mask[4]
Definition: gpio.c:308
void gpio_set_mode(gpio_t gpio, int mode)
Definition: gpio.c:45
@ TEGRA_GPIO_BASE
Definition: addressmap.h:23
int gpio_get_int_enable(gpio_t gpio)
Definition: gpio.c:144
static void __gpio_input(gpio_t gpio, u32 pull)
Definition: gpio.c:11
int gpio_get_out_enable(gpio_t gpio)
Definition: gpio.c:96
static void gpio_write_port(int index, size_t offset, u32 mask, u32 value)
Definition: gpio.c:41
int gpio_get_out_value(gpio_t gpio)
Definition: gpio.c:112
void gpio_get_int_level(gpio_t gpio, int *high_rise, int *edge, int *delta)
Definition: gpio.c:163
void gpio_set_int_clear(gpio_t gpio)
Definition: gpio.c:173
void gpio_set_int_level(gpio_t gpio, int high_rise, int edge, int delta)
Definition: gpio.c:152
void gpio_set_out_enable(gpio_t gpio, int enable)
Definition: gpio.c:88
static void __gpio_output(gpio_t gpio, int value, u32 od)
Definition: gpio.c:21
static u32 gpio_read_port(int index, size_t offset)
Definition: gpio.c:32
void gpio_set_lock(gpio_t gpio)
Definition: gpio.c:72
int gpio_get_int_status(gpio_t gpio)
Definition: gpio.c:128
void gpio_output_open_drain(gpio_t gpio, int value)
Definition: gpio.c:201
static const struct gpio_bank * gpio_banks
Definition: gpio.c:30
void gpio_set_int_enable(gpio_t gpio, int enable)
Definition: gpio.c:136
int gpio_get_lock(gpio_t gpio)
Definition: gpio.c:80
int gpio_get_mode(gpio_t gpio)
Definition: gpio.c:64
#define GPIO_PINMUX_SHIFT
Definition: gpio.h:12
gpio_mode
Definition: gpio.h:18
@ GPIO_MODE_GPIO
Definition: gpio.h:20
@ GPIO_GPIOS_PER_PORT
Definition: gpio.h:49
@ GPIO_GPIOS_PER_BANK
Definition: gpio.h:53
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
u32 out_value[GPIO_PORTS_PER_BANK]
Definition: gpio.h:76
u32 out_enable[GPIO_PORTS_PER_BANK]
Definition: gpio.h:75
u32 int_status[GPIO_PORTS_PER_BANK]
Definition: gpio.h:78
u32 int_clear[GPIO_PORTS_PER_BANK]
Definition: gpio.h:81
u32 int_enable[GPIO_PORTS_PER_BANK]
Definition: gpio.h:79
u32 in_value[GPIO_PORTS_PER_BANK]
Definition: gpio.h:77
u32 int_level[GPIO_PORTS_PER_BANK]
Definition: gpio.h:80
Definition: pinmux.c:36