xref: /openbmc/u-boot/drivers/gpio/tegra186_gpio.c (revision 699e831e158a5846778d8bd6af054d4276277cb6)
1 /*
2  * Copyright (c) 2010-2016, NVIDIA CORPORATION.
3  * (based on tegra_gpio.c)
4  *
5  * SPDX-License-Identifier: GPL-2.0
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <malloc.h>
11 #include <errno.h>
12 #include <fdtdec.h>
13 #include <asm/io.h>
14 #include <asm/bitops.h>
15 #include <asm/gpio.h>
16 #include <dm/device-internal.h>
17 #include <dt-bindings/gpio/gpio.h>
18 #include "tegra186_gpio_priv.h"
19 
20 struct tegra186_gpio_port_data {
21 	const char *name;
22 	uint32_t offset;
23 };
24 
25 struct tegra186_gpio_ctlr_data {
26 	const struct tegra186_gpio_port_data *ports;
27 	uint32_t port_count;
28 };
29 
30 struct tegra186_gpio_platdata {
31 	const char *name;
32 	uint32_t *regs;
33 };
34 
35 static uint32_t *tegra186_gpio_reg(struct udevice *dev, uint32_t reg,
36 				   uint32_t gpio)
37 {
38 	struct tegra186_gpio_platdata *plat = dev->platdata;
39 	uint32_t index = (reg + (gpio * TEGRA186_GPIO_PER_GPIO_STRIDE)) / 4;
40 
41 	return &(plat->regs[index]);
42 }
43 
44 static int tegra186_gpio_set_out(struct udevice *dev, unsigned offset,
45 				 bool output)
46 {
47 	uint32_t *reg;
48 	uint32_t rval;
49 
50 	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_CONTROL, offset);
51 	rval = readl(reg);
52 	if (output)
53 		rval &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
54 	else
55 		rval |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
56 	writel(rval, reg);
57 
58 	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
59 	rval = readl(reg);
60 	if (output)
61 		rval |= TEGRA186_GPIO_ENABLE_CONFIG_OUT;
62 	else
63 		rval &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT;
64 	rval |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE;
65 	writel(rval, reg);
66 
67 	return 0;
68 }
69 
70 static int tegra186_gpio_set_val(struct udevice *dev, unsigned offset, bool val)
71 {
72 	uint32_t *reg;
73 	uint32_t rval;
74 
75 	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE, offset);
76 	rval = readl(reg);
77 	if (val)
78 		rval |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
79 	else
80 		rval &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
81 	writel(rval, reg);
82 
83 	return 0;
84 }
85 
86 static int tegra186_gpio_direction_input(struct udevice *dev, unsigned offset)
87 {
88 	return tegra186_gpio_set_out(dev, offset, false);
89 }
90 
91 static int tegra186_gpio_direction_output(struct udevice *dev, unsigned offset,
92 				       int value)
93 {
94 	int ret;
95 
96 	ret = tegra186_gpio_set_val(dev, offset, value != 0);
97 	if (ret)
98 		return ret;
99 	return tegra186_gpio_set_out(dev, offset, true);
100 }
101 
102 static int tegra186_gpio_get_value(struct udevice *dev, unsigned offset)
103 {
104 	uint32_t *reg;
105 	uint32_t rval;
106 
107 	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
108 	rval = readl(reg);
109 
110 	if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
111 		reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE,
112 					offset);
113 	else
114 		reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_INPUT, offset);
115 
116 	rval = readl(reg);
117 	return !!rval;
118 }
119 
120 static int tegra186_gpio_set_value(struct udevice *dev, unsigned offset,
121 				   int value)
122 {
123 	return tegra186_gpio_set_val(dev, offset, value != 0);
124 }
125 
126 static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset)
127 {
128 	uint32_t *reg;
129 	uint32_t rval;
130 
131 	reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset);
132 	rval = readl(reg);
133 	if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
134 		return GPIOF_OUTPUT;
135 	else
136 		return GPIOF_INPUT;
137 }
138 
139 static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
140 			       struct ofnode_phandle_args *args)
141 {
142 	int gpio, port, ret;
143 
144 	gpio = args->args[0];
145 	port = gpio / TEGRA186_GPIO_PER_GPIO_COUNT;
146 	ret = device_get_child(dev, port, &desc->dev);
147 	if (ret)
148 		return ret;
149 	desc->offset = gpio % TEGRA186_GPIO_PER_GPIO_COUNT;
150 	desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
151 
152 	return 0;
153 }
154 
155 static const struct dm_gpio_ops tegra186_gpio_ops = {
156 	.direction_input	= tegra186_gpio_direction_input,
157 	.direction_output	= tegra186_gpio_direction_output,
158 	.get_value		= tegra186_gpio_get_value,
159 	.set_value		= tegra186_gpio_set_value,
160 	.get_function		= tegra186_gpio_get_function,
161 	.xlate			= tegra186_gpio_xlate,
162 };
163 
164 /**
165  * We have a top-level GPIO device with no actual GPIOs. It has a child device
166  * for each port within the controller.
167  */
168 static int tegra186_gpio_bind(struct udevice *parent)
169 {
170 	struct tegra186_gpio_platdata *parent_plat = parent->platdata;
171 	struct tegra186_gpio_ctlr_data *ctlr_data =
172 		(struct tegra186_gpio_ctlr_data *)dev_get_driver_data(parent);
173 	uint32_t *regs;
174 	int port, ret;
175 
176 	/* If this is a child device, there is nothing to do here */
177 	if (parent_plat)
178 		return 0;
179 
180 	regs = (uint32_t *)devfdt_get_addr_name(parent, "gpio");
181 	if (regs == (uint32_t *)FDT_ADDR_T_NONE)
182 		return -EINVAL;
183 
184 	for (port = 0; port < ctlr_data->port_count; port++) {
185 		struct tegra186_gpio_platdata *plat;
186 		struct udevice *dev;
187 
188 		plat = calloc(1, sizeof(*plat));
189 		if (!plat)
190 			return -ENOMEM;
191 		plat->name = ctlr_data->ports[port].name;
192 		plat->regs = &(regs[ctlr_data->ports[port].offset / 4]);
193 
194 		ret = device_bind(parent, parent->driver, plat->name, plat,
195 				  -1, &dev);
196 		if (ret)
197 			return ret;
198 		dev_set_of_offset(dev, dev_of_offset(parent));
199 	}
200 
201 	return 0;
202 }
203 
204 static int tegra186_gpio_probe(struct udevice *dev)
205 {
206 	struct tegra186_gpio_platdata *plat = dev->platdata;
207 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
208 
209 	/* Only child devices have ports */
210 	if (!plat)
211 		return 0;
212 
213 	uc_priv->gpio_count = TEGRA186_GPIO_PER_GPIO_COUNT;
214 	uc_priv->bank_name = plat->name;
215 
216 	return 0;
217 }
218 
219 static const struct tegra186_gpio_port_data tegra186_gpio_main_ports[] = {
220 	{"A",  0x2000},
221 	{"B",  0x3000},
222 	{"C",  0x3200},
223 	{"D",  0x3400},
224 	{"E",  0x2200},
225 	{"F",  0x2400},
226 	{"G",  0x4200},
227 	{"H",  0x1000},
228 	{"I",  0x0800},
229 	{"J",  0x5000},
230 	{"K",  0x5200},
231 	{"L",  0x1200},
232 	{"M",  0x5600},
233 	{"N",  0x0000},
234 	{"O",  0x0200},
235 	{"P",  0x4000},
236 	{"Q",  0x0400},
237 	{"R",  0x0a00},
238 	{"T",  0x0600},
239 	{"X",  0x1400},
240 	{"Y",  0x1600},
241 	{"BB", 0x2600},
242 	{"CC", 0x5400},
243 };
244 
245 static const struct tegra186_gpio_ctlr_data tegra186_gpio_main_data = {
246 	.ports = tegra186_gpio_main_ports,
247 	.port_count = ARRAY_SIZE(tegra186_gpio_main_ports),
248 };
249 
250 static const struct tegra186_gpio_port_data tegra186_gpio_aon_ports[] = {
251 	{"S",  0x0200},
252 	{"U",  0x0400},
253 	{"V",  0x0800},
254 	{"W",  0x0a00},
255 	{"Z",  0x0e00},
256 	{"AA", 0x0c00},
257 	{"EE", 0x0600},
258 	{"FF", 0x0000},
259 };
260 
261 static const struct tegra186_gpio_ctlr_data tegra186_gpio_aon_data = {
262 	.ports = tegra186_gpio_aon_ports,
263 	.port_count = ARRAY_SIZE(tegra186_gpio_aon_ports),
264 };
265 
266 static const struct udevice_id tegra186_gpio_ids[] = {
267 	{
268 		.compatible = "nvidia,tegra186-gpio",
269 		.data = (ulong)&tegra186_gpio_main_data,
270 	},
271 	{
272 		.compatible = "nvidia,tegra186-gpio-aon",
273 		.data = (ulong)&tegra186_gpio_aon_data,
274 	},
275 	{ }
276 };
277 
278 U_BOOT_DRIVER(tegra186_gpio) = {
279 	.name = "tegra186_gpio",
280 	.id = UCLASS_GPIO,
281 	.of_match = tegra186_gpio_ids,
282 	.bind = tegra186_gpio_bind,
283 	.probe = tegra186_gpio_probe,
284 	.ops = &tegra186_gpio_ops,
285 	.flags = DM_FLAG_PRE_RELOC,
286 };
287