xref: /aosp_15_r20/external/coreboot/src/soc/nvidia/tegra/gpio.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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 
__gpio_input(gpio_t gpio,u32 pull)11 static void __gpio_input(gpio_t gpio, u32 pull)
12 {
13 	u32 pinmux_config = PINMUX_INPUT_ENABLE | pull;
14 
15 	gpio_set_int_enable(gpio, 0);
16 	gpio_set_out_enable(gpio, 0);
17 	gpio_set_mode(gpio, GPIO_MODE_GPIO);
18 	pinmux_set_config(gpio >> GPIO_PINMUX_SHIFT, pinmux_config);
19 }
20 
__gpio_output(gpio_t gpio,int value,u32 od)21 static void __gpio_output(gpio_t gpio, int value, u32 od)
22 {
23 	gpio_set_int_enable(gpio, 0);
24 	gpio_set(gpio, value);
25 	gpio_set_out_enable(gpio, 1);
26 	gpio_set_mode(gpio, GPIO_MODE_GPIO);
27 	pinmux_set_config(gpio >> GPIO_PINMUX_SHIFT, PINMUX_PULL_NONE | od);
28 }
29 
30 static const struct gpio_bank *gpio_banks = (void *)TEGRA_GPIO_BASE;
31 
gpio_read_port(int index,size_t offset)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 
gpio_write_port(int index,size_t offset,u32 mask,u32 value)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 
gpio_set_mode(gpio_t gpio,enum gpio_mode mode)56 void gpio_set_mode(gpio_t gpio, enum gpio_mode mode)
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 
gpio_get_mode(gpio_t gpio)64 int gpio_get_mode(gpio_t gpio)
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 
gpio_set_lock(gpio_t gpio)72 void gpio_set_lock(gpio_t gpio)
73 {
74 	int bit = gpio % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT;
75 	gpio_write_port(gpio & ((1 << GPIO_PINMUX_SHIFT) - 1),
76 			offsetof(struct gpio_bank, config),
77 			1 << bit, 1 << bit);
78 }
79 
gpio_get_lock(gpio_t gpio)80 int gpio_get_lock(gpio_t gpio)
81 {
82 	int bit = gpio % GPIO_GPIOS_PER_PORT + GPIO_GPIOS_PER_PORT;
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 
gpio_set_out_enable(gpio_t gpio,int enable)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 
gpio_get_out_enable(gpio_t gpio)96 int gpio_get_out_enable(gpio_t gpio)
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 
gpio_set(gpio_t gpio,int value)104 void gpio_set(gpio_t gpio, int value)
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 
gpio_get_out_value(gpio_t gpio)112 int gpio_get_out_value(gpio_t gpio)
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 
gpio_get(gpio_t gpio)120 int gpio_get(gpio_t gpio)
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 
gpio_get_int_status(gpio_t gpio)128 int gpio_get_int_status(gpio_t gpio)
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 
gpio_set_int_enable(gpio_t gpio,int enable)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 
gpio_get_int_enable(gpio_t gpio)144 int gpio_get_int_enable(gpio_t gpio)
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 
gpio_set_int_level(gpio_t gpio,int high_rise,int edge,int delta)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 
gpio_get_int_level(gpio_t gpio,int * high_rise,int * edge,int * delta)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 
gpio_set_int_clear(gpio_t gpio)173 void gpio_set_int_clear(gpio_t gpio)
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 
gpio_input_pulldown(gpio_t gpio)181 void gpio_input_pulldown(gpio_t gpio)
182 {
183 	__gpio_input(gpio, PINMUX_PULL_DOWN);
184 }
185 
gpio_input_pullup(gpio_t gpio)186 void gpio_input_pullup(gpio_t gpio)
187 {
188 	__gpio_input(gpio, PINMUX_PULL_UP);
189 }
190 
gpio_input(gpio_t gpio)191 void gpio_input(gpio_t gpio)
192 {
193 	__gpio_input(gpio, PINMUX_PULL_NONE);
194 }
195 
gpio_output(gpio_t gpio,int value)196 void gpio_output(gpio_t gpio, int value)
197 {
198 	__gpio_output(gpio, value, 0);
199 }
200 
gpio_output_open_drain(gpio_t gpio,int value)201 void gpio_output_open_drain(gpio_t gpio, int value)
202 {
203 	__gpio_output(gpio, value, PINMUX_OPEN_DRAIN);
204 }
205