1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * GPIO driver for TI DaVinci DA8xx SOCs.
4 *
5 * (C) Copyright 2011 Guralp Systems Ltd.
6 * Laurence Withers <lwithers@guralp.com>
7 */
8
9#include <common.h>
10#include <dm.h>
11#include <fdtdec.h>
12#include <malloc.h>
13#include <asm/io.h>
14#include <asm/global_data.h>
15#include <asm/gpio.h>
16#include <dt-bindings/gpio/gpio.h>
17
18#include "da8xx_gpio.h"
19
20#if !CONFIG_IS_ENABLED(DM_GPIO)
21#include <asm/arch/hardware.h>
22#include <asm/arch/davinci_misc.h>
23
24static struct gpio_registry {
25	int is_registered;
26	char name[GPIO_NAME_SIZE];
27} gpio_registry[MAX_NUM_GPIOS];
28
29#if defined(CONFIG_SOC_DA8XX)
30#define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])
31
32#if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
33static const struct pinmux_config gpio_pinmux[] = {
34	{ pinmux(13), 8, 6 },	/* GP0[0] */
35	{ pinmux(13), 8, 7 },
36	{ pinmux(14), 8, 0 },
37	{ pinmux(14), 8, 1 },
38	{ pinmux(14), 8, 2 },
39	{ pinmux(14), 8, 3 },
40	{ pinmux(14), 8, 4 },
41	{ pinmux(14), 8, 5 },
42	{ pinmux(14), 8, 6 },
43	{ pinmux(14), 8, 7 },
44	{ pinmux(15), 8, 0 },
45	{ pinmux(15), 8, 1 },
46	{ pinmux(15), 8, 2 },
47	{ pinmux(15), 8, 3 },
48	{ pinmux(15), 8, 4 },
49	{ pinmux(15), 8, 5 },
50	{ pinmux(15), 8, 6 },	/* GP1[0] */
51	{ pinmux(15), 8, 7 },
52	{ pinmux(16), 8, 0 },
53	{ pinmux(16), 8, 1 },
54	{ pinmux(16), 8, 2 },
55	{ pinmux(16), 8, 3 },
56	{ pinmux(16), 8, 4 },
57	{ pinmux(16), 8, 5 },
58	{ pinmux(16), 8, 6 },
59	{ pinmux(16), 8, 7 },
60	{ pinmux(17), 8, 0 },
61	{ pinmux(17), 8, 1 },
62	{ pinmux(17), 8, 2 },
63	{ pinmux(17), 8, 3 },
64	{ pinmux(17), 8, 4 },
65	{ pinmux(17), 8, 5 },
66	{ pinmux(17), 8, 6 },	/* GP2[0] */
67	{ pinmux(17), 8, 7 },
68	{ pinmux(18), 8, 0 },
69	{ pinmux(18), 8, 1 },
70	{ pinmux(18), 8, 2 },
71	{ pinmux(18), 8, 3 },
72	{ pinmux(18), 8, 4 },
73	{ pinmux(18), 8, 5 },
74	{ pinmux(18), 8, 6 },
75	{ pinmux(18), 8, 7 },
76	{ pinmux(19), 8, 0 },
77	{ pinmux(9), 8, 2 },
78	{ pinmux(9), 8, 3 },
79	{ pinmux(9), 8, 4 },
80	{ pinmux(9), 8, 5 },
81	{ pinmux(9), 8, 6 },
82	{ pinmux(10), 8, 1 },	/* GP3[0] */
83	{ pinmux(10), 8, 2 },
84	{ pinmux(10), 8, 3 },
85	{ pinmux(10), 8, 4 },
86	{ pinmux(10), 8, 5 },
87	{ pinmux(10), 8, 6 },
88	{ pinmux(10), 8, 7 },
89	{ pinmux(11), 8, 0 },
90	{ pinmux(11), 8, 1 },
91	{ pinmux(11), 8, 2 },
92	{ pinmux(11), 8, 3 },
93	{ pinmux(11), 8, 4 },
94	{ pinmux(9), 8, 7 },
95	{ pinmux(2), 8, 6 },
96	{ pinmux(11), 8, 5 },
97	{ pinmux(11), 8, 6 },
98	{ pinmux(12), 8, 4 },	/* GP4[0] */
99	{ pinmux(12), 8, 5 },
100	{ pinmux(12), 8, 6 },
101	{ pinmux(12), 8, 7 },
102	{ pinmux(13), 8, 0 },
103	{ pinmux(13), 8, 1 },
104	{ pinmux(13), 8, 2 },
105	{ pinmux(13), 8, 3 },
106	{ pinmux(13), 8, 4 },
107	{ pinmux(13), 8, 5 },
108	{ pinmux(11), 8, 7 },
109	{ pinmux(12), 8, 0 },
110	{ pinmux(12), 8, 1 },
111	{ pinmux(12), 8, 2 },
112	{ pinmux(12), 8, 3 },
113	{ pinmux(9), 8, 1 },
114	{ pinmux(7), 8, 3 },	/* GP5[0] */
115	{ pinmux(7), 8, 4 },
116	{ pinmux(7), 8, 5 },
117	{ pinmux(7), 8, 6 },
118	{ pinmux(7), 8, 7 },
119	{ pinmux(8), 8, 0 },
120	{ pinmux(8), 8, 1 },
121	{ pinmux(8), 8, 2 },
122	{ pinmux(8), 8, 3 },
123	{ pinmux(8), 8, 4 },
124	{ pinmux(8), 8, 5 },
125	{ pinmux(8), 8, 6 },
126	{ pinmux(8), 8, 7 },
127	{ pinmux(9), 8, 0 },
128	{ pinmux(7), 8, 1 },
129	{ pinmux(7), 8, 2 },
130	{ pinmux(5), 8, 1 },	/* GP6[0] */
131	{ pinmux(5), 8, 2 },
132	{ pinmux(5), 8, 3 },
133	{ pinmux(5), 8, 4 },
134	{ pinmux(5), 8, 5 },
135	{ pinmux(5), 8, 6 },
136	{ pinmux(5), 8, 7 },
137	{ pinmux(6), 8, 0 },
138	{ pinmux(6), 8, 1 },
139	{ pinmux(6), 8, 2 },
140	{ pinmux(6), 8, 3 },
141	{ pinmux(6), 8, 4 },
142	{ pinmux(6), 8, 5 },
143	{ pinmux(6), 8, 6 },
144	{ pinmux(6), 8, 7 },
145	{ pinmux(7), 8, 0 },
146	{ pinmux(1), 8, 0 },	/* GP7[0] */
147	{ pinmux(1), 8, 1 },
148	{ pinmux(1), 8, 2 },
149	{ pinmux(1), 8, 3 },
150	{ pinmux(1), 8, 4 },
151	{ pinmux(1), 8, 5 },
152	{ pinmux(1), 8, 6 },
153	{ pinmux(1), 8, 7 },
154	{ pinmux(2), 8, 0 },
155	{ pinmux(2), 8, 1 },
156	{ pinmux(2), 8, 2 },
157	{ pinmux(2), 8, 3 },
158	{ pinmux(2), 8, 4 },
159	{ pinmux(2), 8, 5 },
160	{ pinmux(0), 1, 0 },
161	{ pinmux(0), 1, 1 },
162};
163#else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */
164static const struct pinmux_config gpio_pinmux[] = {
165	{ pinmux(1), 8, 7 },	/* GP0[0] */
166	{ pinmux(1), 8, 6 },
167	{ pinmux(1), 8, 5 },
168	{ pinmux(1), 8, 4 },
169	{ pinmux(1), 8, 3 },
170	{ pinmux(1), 8, 2 },
171	{ pinmux(1), 8, 1 },
172	{ pinmux(1), 8, 0 },
173	{ pinmux(0), 8, 7 },
174	{ pinmux(0), 8, 6 },
175	{ pinmux(0), 8, 5 },
176	{ pinmux(0), 8, 4 },
177	{ pinmux(0), 8, 3 },
178	{ pinmux(0), 8, 2 },
179	{ pinmux(0), 8, 1 },
180	{ pinmux(0), 8, 0 },
181	{ pinmux(4), 8, 7 },	/* GP1[0] */
182	{ pinmux(4), 8, 6 },
183	{ pinmux(4), 8, 5 },
184	{ pinmux(4), 8, 4 },
185	{ pinmux(4), 8, 3 },
186	{ pinmux(4), 8, 2 },
187	{ pinmux(4), 4, 1 },
188	{ pinmux(4), 4, 0 },
189	{ pinmux(3), 4, 0 },
190	{ pinmux(2), 4, 6 },
191	{ pinmux(2), 4, 5 },
192	{ pinmux(2), 4, 4 },
193	{ pinmux(2), 4, 3 },
194	{ pinmux(2), 4, 2 },
195	{ pinmux(2), 4, 1 },
196	{ pinmux(2), 8, 0 },
197	{ pinmux(6), 8, 7 },	/* GP2[0] */
198	{ pinmux(6), 8, 6 },
199	{ pinmux(6), 8, 5 },
200	{ pinmux(6), 8, 4 },
201	{ pinmux(6), 8, 3 },
202	{ pinmux(6), 8, 2 },
203	{ pinmux(6), 8, 1 },
204	{ pinmux(6), 8, 0 },
205	{ pinmux(5), 8, 7 },
206	{ pinmux(5), 8, 6 },
207	{ pinmux(5), 8, 5 },
208	{ pinmux(5), 8, 4 },
209	{ pinmux(5), 8, 3 },
210	{ pinmux(5), 8, 2 },
211	{ pinmux(5), 8, 1 },
212	{ pinmux(5), 8, 0 },
213	{ pinmux(8), 8, 7 },	/* GP3[0] */
214	{ pinmux(8), 8, 6 },
215	{ pinmux(8), 8, 5 },
216	{ pinmux(8), 8, 4 },
217	{ pinmux(8), 8, 3 },
218	{ pinmux(8), 8, 2 },
219	{ pinmux(8), 8, 1 },
220	{ pinmux(8), 8, 0 },
221	{ pinmux(7), 8, 7 },
222	{ pinmux(7), 8, 6 },
223	{ pinmux(7), 8, 5 },
224	{ pinmux(7), 8, 4 },
225	{ pinmux(7), 8, 3 },
226	{ pinmux(7), 8, 2 },
227	{ pinmux(7), 8, 1 },
228	{ pinmux(7), 8, 0 },
229	{ pinmux(10), 8, 7 },	/* GP4[0] */
230	{ pinmux(10), 8, 6 },
231	{ pinmux(10), 8, 5 },
232	{ pinmux(10), 8, 4 },
233	{ pinmux(10), 8, 3 },
234	{ pinmux(10), 8, 2 },
235	{ pinmux(10), 8, 1 },
236	{ pinmux(10), 8, 0 },
237	{ pinmux(9), 8, 7 },
238	{ pinmux(9), 8, 6 },
239	{ pinmux(9), 8, 5 },
240	{ pinmux(9), 8, 4 },
241	{ pinmux(9), 8, 3 },
242	{ pinmux(9), 8, 2 },
243	{ pinmux(9), 8, 1 },
244	{ pinmux(9), 8, 0 },
245	{ pinmux(12), 8, 7 },	/* GP5[0] */
246	{ pinmux(12), 8, 6 },
247	{ pinmux(12), 8, 5 },
248	{ pinmux(12), 8, 4 },
249	{ pinmux(12), 8, 3 },
250	{ pinmux(12), 8, 2 },
251	{ pinmux(12), 8, 1 },
252	{ pinmux(12), 8, 0 },
253	{ pinmux(11), 8, 7 },
254	{ pinmux(11), 8, 6 },
255	{ pinmux(11), 8, 5 },
256	{ pinmux(11), 8, 4 },
257	{ pinmux(11), 8, 3 },
258	{ pinmux(11), 8, 2 },
259	{ pinmux(11), 8, 1 },
260	{ pinmux(11), 8, 0 },
261	{ pinmux(19), 8, 6 },	/* GP6[0] */
262	{ pinmux(19), 8, 5 },
263	{ pinmux(19), 8, 4 },
264	{ pinmux(19), 8, 3 },
265	{ pinmux(19), 8, 2 },
266	{ pinmux(16), 8, 1 },
267	{ pinmux(14), 8, 1 },
268	{ pinmux(14), 8, 0 },
269	{ pinmux(13), 8, 7 },
270	{ pinmux(13), 8, 6 },
271	{ pinmux(13), 8, 5 },
272	{ pinmux(13), 8, 4 },
273	{ pinmux(13), 8, 3 },
274	{ pinmux(13), 8, 2 },
275	{ pinmux(13), 8, 1 },
276	{ pinmux(13), 8, 0 },
277	{ pinmux(18), 8, 1 },	/* GP7[0] */
278	{ pinmux(18), 8, 0 },
279	{ pinmux(17), 8, 7 },
280	{ pinmux(17), 8, 6 },
281	{ pinmux(17), 8, 5 },
282	{ pinmux(17), 8, 4 },
283	{ pinmux(17), 8, 3 },
284	{ pinmux(17), 8, 2 },
285	{ pinmux(17), 8, 1 },
286	{ pinmux(17), 8, 0 },
287	{ pinmux(16), 8, 7 },
288	{ pinmux(16), 8, 6 },
289	{ pinmux(16), 8, 5 },
290	{ pinmux(16), 8, 4 },
291	{ pinmux(16), 8, 3 },
292	{ pinmux(16), 8, 2 },
293	{ pinmux(19), 8, 0 },	/* GP8[0] */
294	{ pinmux(3), 4, 7 },
295	{ pinmux(3), 4, 6 },
296	{ pinmux(3), 4, 5 },
297	{ pinmux(3), 4, 4 },
298	{ pinmux(3), 4, 3 },
299	{ pinmux(3), 4, 2 },
300	{ pinmux(2), 4, 7 },
301	{ pinmux(19), 8, 1 },
302	{ pinmux(19), 8, 0 },
303	{ pinmux(18), 8, 7 },
304	{ pinmux(18), 8, 6 },
305	{ pinmux(18), 8, 5 },
306	{ pinmux(18), 8, 4 },
307	{ pinmux(18), 8, 3 },
308	{ pinmux(18), 8, 2 },
309};
310#endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */
311#else /* !CONFIG_SOC_DA8XX */
312#define davinci_configure_pin_mux(a, b)
313#endif /* CONFIG_SOC_DA8XX */
314
315int gpio_request(unsigned int gpio, const char *label)
316{
317	if (gpio >= MAX_NUM_GPIOS)
318		return -1;
319
320	if (gpio_registry[gpio].is_registered)
321		return -1;
322
323	gpio_registry[gpio].is_registered = 1;
324	strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE);
325	gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0;
326
327	davinci_configure_pin_mux(&gpio_pinmux[gpio], 1);
328
329	return 0;
330}
331
332int gpio_free(unsigned int gpio)
333{
334	if (gpio >= MAX_NUM_GPIOS)
335		return -1;
336
337	if (!gpio_registry[gpio].is_registered)
338		return -1;
339
340	gpio_registry[gpio].is_registered = 0;
341	gpio_registry[gpio].name[0] = '\0';
342	/* Do not configure as input or change pin mux here */
343	return 0;
344}
345#endif
346
347static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio)
348{
349	setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
350	return 0;
351}
352
353static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio)
354{
355	unsigned int ip;
356	ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio));
357	return ip ? 1 : 0;
358}
359
360static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value)
361{
362	if (value)
363		bank->set_data = 1U << GPIO_BIT(gpio);
364	else
365		bank->clr_data = 1U << GPIO_BIT(gpio);
366
367	return 0;
368}
369
370static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio)
371{
372	return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
373}
374
375static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio,
376				  int value)
377{
378	clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
379	_gpio_set_value(bank, gpio, value);
380	return 0;
381}
382
383#if !CONFIG_IS_ENABLED(DM_GPIO)
384
385void gpio_info(void)
386{
387	unsigned int gpio, dir, val;
388	struct davinci_gpio *bank;
389
390	for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) {
391		bank = GPIO_BANK(gpio);
392		dir = _gpio_get_dir(bank, gpio);
393		val = gpio_get_value(gpio);
394
395		printf("% 4d: %s: %d [%c] %s\n",
396			gpio, dir ? " in" : "out", val,
397			gpio_registry[gpio].is_registered ? 'x' : ' ',
398			gpio_registry[gpio].name);
399	}
400}
401
402int gpio_direction_input(unsigned int gpio)
403{
404	struct davinci_gpio *bank;
405
406	bank = GPIO_BANK(gpio);
407	return _gpio_direction_input(bank, gpio);
408}
409
410int gpio_direction_output(unsigned int gpio, int value)
411{
412	struct davinci_gpio *bank;
413
414	bank = GPIO_BANK(gpio);
415	return _gpio_direction_output(bank, gpio, value);
416}
417
418int gpio_get_value(unsigned int gpio)
419{
420	struct davinci_gpio *bank;
421
422	bank = GPIO_BANK(gpio);
423	return _gpio_get_value(bank, gpio);
424}
425
426int gpio_set_value(unsigned int gpio, int value)
427{
428	struct davinci_gpio *bank;
429
430	bank = GPIO_BANK(gpio);
431	return _gpio_set_value(bank, gpio, value);
432}
433
434#else /* DM_GPIO */
435
436static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
437{
438	struct davinci_gpio_bank *bank = dev_get_priv(dev);
439	unsigned long addr;
440
441	/*
442	 * The device tree is not broken into banks but the infrastructure is
443	 * expecting it this way, so we'll first include the 0x10 offset, then
444	 * calculate the bank manually based on the offset.
445	 * Casting 'addr' as Unsigned long is needed to make the math work.
446	 */
447	addr = ((unsigned long)(struct davinci_gpio *)bank->base) +
448			0x10 + (0x28 * (offset >> 5));
449	return (struct davinci_gpio *)addr;
450}
451
452static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset)
453{
454	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
455
456	/*
457	 * Fetch the address based on GPIO, but only pass the masked low 32-bits
458	 */
459	_gpio_direction_input(base, (offset & 0x1f));
460	return 0;
461}
462
463static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset,
464					 int value)
465{
466	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
467
468	_gpio_direction_output(base, (offset & 0x1f), value);
469	return 0;
470}
471
472static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset)
473{
474	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
475
476	return _gpio_get_value(base, (offset & 0x1f));
477}
478
479static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset,
480				  int value)
481{
482	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
483
484	_gpio_set_value(base, (offset & 0x1f), value);
485
486	return 0;
487}
488
489static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset)
490{
491	unsigned int dir;
492	struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
493
494	dir = _gpio_get_dir(base, offset);
495
496	if (dir)
497		return GPIOF_INPUT;
498
499	return GPIOF_OUTPUT;
500}
501
502static int davinci_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
503			      struct ofnode_phandle_args *args)
504{
505	desc->offset = args->args[0];
506
507	if (args->args[1] & GPIO_ACTIVE_LOW)
508		desc->flags = GPIOD_ACTIVE_LOW;
509	else
510		desc->flags = 0;
511	return 0;
512}
513
514static const struct dm_gpio_ops gpio_davinci_ops = {
515	.direction_input	= davinci_gpio_direction_input,
516	.direction_output	= davinci_gpio_direction_output,
517	.get_value		= davinci_gpio_get_value,
518	.set_value		= davinci_gpio_set_value,
519	.get_function		= davinci_gpio_get_function,
520	.xlate			= davinci_gpio_xlate,
521};
522
523static int davinci_gpio_probe(struct udevice *dev)
524{
525	struct davinci_gpio_bank *bank = dev_get_priv(dev);
526	struct davinci_gpio_plat *plat = dev_get_plat(dev);
527	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
528	const void *fdt = gd->fdt_blob;
529	int node = dev_of_offset(dev);
530
531	uc_priv->bank_name = plat->port_name;
532	uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1);
533	bank->base = (struct davinci_gpio *)plat->base;
534	return 0;
535}
536
537static const struct udevice_id davinci_gpio_ids[] = {
538	{ .compatible = "ti,dm6441-gpio" },
539	{ .compatible = "ti,k2g-gpio" },
540	{ .compatible = "ti,keystone-gpio" },
541	{ }
542};
543
544static int davinci_gpio_of_to_plat(struct udevice *dev)
545{
546	struct davinci_gpio_plat *plat = dev_get_plat(dev);
547	fdt_addr_t addr;
548	char name[18], *str;
549
550	addr = dev_read_addr(dev);
551	if (addr == FDT_ADDR_T_NONE)
552		return -EINVAL;
553
554	plat->base = addr;
555
556	sprintf(name, "gpio@%4x_", (unsigned int)plat->base);
557	str = strdup(name);
558	if (!str)
559		return -ENOMEM;
560	plat->port_name = str;
561
562	return 0;
563}
564
565U_BOOT_DRIVER(ti_dm6441_gpio) = {
566	.name	= "ti_dm6441_gpio",
567	.id	= UCLASS_GPIO,
568	.ops	= &gpio_davinci_ops,
569	.of_to_plat = of_match_ptr(davinci_gpio_of_to_plat),
570	.of_match = davinci_gpio_ids,
571	.bind   = dm_scan_fdt_dev,
572	.plat_auto	= sizeof(struct davinci_gpio_plat),
573	.probe	= davinci_gpio_probe,
574	.priv_auto	= sizeof(struct davinci_gpio_bank),
575};
576
577#endif
578