xref: /openbsd-src/sys/dev/fdt/rkpinctrl.c (revision 8cff70dd7f9ae4b7290bc90cf5505ae9a5b6479a)
1 /*	$OpenBSD: rkpinctrl.c,v 1.15 2024/02/11 16:01:09 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2017, 2018 Mark Kettenis <kettenis@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/malloc.h>
22 
23 #include <machine/intr.h>
24 #include <machine/bus.h>
25 #include <machine/fdt.h>
26 
27 #include <dev/ofw/openfirm.h>
28 #include <dev/ofw/ofw_misc.h>
29 #include <dev/ofw/ofw_pinctrl.h>
30 #include <dev/ofw/fdt.h>
31 
32 #include <machine/simplebusvar.h>
33 
34 /* Pin numbers (from devicetree bindings) */
35 #define RK_PA0		0
36 #define RK_PA1		1
37 #define RK_PA2		2
38 #define RK_PA3		3
39 #define RK_PA4		4
40 #define RK_PA5		5
41 #define RK_PA6		6
42 #define RK_PA7		7
43 #define RK_PB0		8
44 #define RK_PB1		9
45 #define RK_PB2		10
46 #define RK_PB3		11
47 #define RK_PB4		12
48 #define RK_PB5		13
49 #define RK_PB6		14
50 #define RK_PB7		15
51 #define RK_PC0		16
52 #define RK_PC1		17
53 #define RK_PC2		18
54 #define RK_PC3		19
55 #define RK_PC4		20
56 #define RK_PC5		21
57 #define RK_PC6		22
58 #define RK_PC7		23
59 #define RK_PD0		24
60 #define RK_PD1		25
61 #define RK_PD2		26
62 #define RK_PD3		27
63 #define RK_PD4		28
64 #define RK_PD5		29
65 #define RK_PD6		30
66 #define RK_PD7		31
67 
68 /* RK3288 registers */
69 #define RK3288_GRF_GPIO1A_IOMUX		0x0000
70 #define RK3288_PMUGRF_GPIO0A_IOMUX	0x0084
71 
72 /* RK3308 registers */
73 #define RK3308_GRF_GPIO0A_IOMUX		0x0000
74 
75 /* RK3328 registers */
76 #define RK3328_GRF_GPIO0A_IOMUX		0x0000
77 
78 /* RK3399 registers */
79 #define RK3399_GRF_GPIO2A_IOMUX		0xe000
80 #define RK3399_PMUGRF_GPIO0A_IOMUX	0x0000
81 
82 /* RK3568 registers */
83 #define RK3568_GRF_GPIO1A_IOMUX_L	0x0000
84 #define RK3568_GRF_GPIO1A_P		0x0080
85 #define RK3568_GRF_GPIO1A_IE		0x00c0
86 #define RK3568_GRF_GPIO1A_DS_0		0x0200
87 #define RK3568_PMUGRF_GPIO0A_IOMUX_L	0x0000
88 #define RK3568_PMUGRF_GPIO0A_P		0x0020
89 #define RK3568_PMUGRF_GPIO0A_IE		0x0030
90 #define RK3568_PMUGRF_GPIO0A_DS_0	0x0070
91 
92 struct rockchip_route_table {
93 	u_int bank : 3;
94 	u_int idx : 5;
95 	u_int mux : 3;
96 	u_int grf : 1;
97 #define ROUTE_GRF	0
98 #define ROUTE_PMU	1
99 	uint16_t reg;
100 	uint32_t val;
101 #define ROUTE_VAL(bit, val)	((0x3 << (bit)) << 16 | ((val) << (bit)))
102 };
103 
104 struct rkpinctrl_softc {
105 	struct simplebus_softc	sc_sbus;
106 
107 	struct regmap		*sc_grf;
108 	struct regmap		*sc_pmu;
109 };
110 
111 int	rkpinctrl_match(struct device *, void *, void *);
112 void	rkpinctrl_attach(struct device *, struct device *, void *);
113 
114 const struct cfattach	rkpinctrl_ca = {
115 	sizeof (struct rkpinctrl_softc), rkpinctrl_match, rkpinctrl_attach
116 };
117 
118 struct cfdriver rkpinctrl_cd = {
119 	NULL, "rkpinctrl", DV_DULL
120 };
121 
122 int	rk3288_pinctrl(uint32_t, void *);
123 int	rk3308_pinctrl(uint32_t, void *);
124 int	rk3328_pinctrl(uint32_t, void *);
125 int	rk3399_pinctrl(uint32_t, void *);
126 int	rk3568_pinctrl(uint32_t, void *);
127 int	rk3588_pinctrl(uint32_t, void *);
128 
129 int
rkpinctrl_match(struct device * parent,void * match,void * aux)130 rkpinctrl_match(struct device *parent, void *match, void *aux)
131 {
132 	struct fdt_attach_args *faa = aux;
133 
134 	return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") ||
135 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl") ||
136 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl") ||
137 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl") ||
138 	    OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl") ||
139 	    OF_is_compatible(faa->fa_node, "rockchip,rk3588-pinctrl"));
140 }
141 
142 void
rkpinctrl_attach(struct device * parent,struct device * self,void * aux)143 rkpinctrl_attach(struct device *parent, struct device *self, void *aux)
144 {
145 	struct rkpinctrl_softc *sc = (struct rkpinctrl_softc *)self;
146 	struct fdt_attach_args *faa = aux;
147 	uint32_t grf, pmu;
148 
149 	grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0);
150 	pmu = OF_getpropint(faa->fa_node, "rockchip,pmu", 0);
151 	sc->sc_grf = regmap_byphandle(grf);
152 	sc->sc_pmu = regmap_byphandle(pmu);
153 
154 	if (sc->sc_grf == NULL && sc->sc_pmu == NULL) {
155 		printf(": no registers\n");
156 		return;
157 	}
158 
159 	if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl"))
160 		pinctrl_register(faa->fa_node, rk3288_pinctrl, sc);
161 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl"))
162 		pinctrl_register(faa->fa_node, rk3308_pinctrl, sc);
163 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl"))
164 		pinctrl_register(faa->fa_node, rk3328_pinctrl, sc);
165 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl"))
166 		pinctrl_register(faa->fa_node, rk3399_pinctrl, sc);
167 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl"))
168 		pinctrl_register(faa->fa_node, rk3568_pinctrl, sc);
169 	else
170 		pinctrl_register(faa->fa_node, rk3588_pinctrl, sc);
171 
172 	/* Attach GPIO banks. */
173 	simplebus_attach(parent, &sc->sc_sbus.sc_dev, faa);
174 }
175 
176 /*
177  * Rockchip RK3288
178  */
179 
180 int
rk3288_pull(uint32_t bank,uint32_t idx,uint32_t phandle)181 rk3288_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
182 {
183 	int node;
184 
185 	node = OF_getnodebyphandle(phandle);
186 	if (node == 0)
187 		return -1;
188 
189 	/* XXX */
190 	if (bank == 0)
191 		return -1;
192 
193 	if (OF_getproplen(node, "bias-disable") == 0)
194 		return 0;
195 	if (OF_getproplen(node, "bias-pull-up") == 0)
196 		return 1;
197 	if (OF_getproplen(node, "bias-pull-down") == 0)
198 		return 2;
199 
200 	return -1;
201 }
202 
203 int
rk3288_strength(uint32_t bank,uint32_t idx,uint32_t phandle)204 rk3288_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
205 {
206 	int strength, level;
207 	int levels[4] = { 2, 4, 8, 12 };
208 	int node;
209 
210 	node = OF_getnodebyphandle(phandle);
211 	if (node == 0)
212 		return -1;
213 
214 	/* XXX */
215 	if (bank == 0)
216 		return -1;
217 
218 	strength = OF_getpropint(node, "drive-strength", -1);
219 	if (strength == -1)
220 		return -1;
221 
222 	/* Convert drive strength to level. */
223 	for (level = 3; level >= 0; level--) {
224 		if (strength >= levels[level])
225 			break;
226 	}
227 	return level;
228 }
229 
230 int
rk3288_pinctrl(uint32_t phandle,void * cookie)231 rk3288_pinctrl(uint32_t phandle, void *cookie)
232 {
233 	struct rkpinctrl_softc *sc = cookie;
234 	uint32_t *pins;
235 	int node, len, i;
236 
237 	KASSERT(sc->sc_grf);
238 	KASSERT(sc->sc_pmu);
239 
240 	node = OF_getnodebyphandle(phandle);
241 	if (node == 0)
242 		return -1;
243 
244 	len = OF_getproplen(node, "rockchip,pins");
245 	if (len <= 0)
246 		return -1;
247 
248 	pins = malloc(len, M_TEMP, M_WAITOK);
249 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
250 		goto fail;
251 
252 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
253 		struct regmap *rm;
254 		bus_size_t base, off;
255 		uint32_t bank, idx, mux;
256 		int pull, strength;
257 		uint32_t mask, bits;
258 		int s;
259 
260 		bank = pins[i];
261 		idx = pins[i + 1];
262 		mux = pins[i + 2];
263 
264 		if (bank > 8 || idx >= 32 || mux > 7)
265 			continue;
266 
267 		pull = rk3288_pull(bank, idx, pins[i + 3]);
268 		strength = rk3288_strength(bank, idx, pins[i + 3]);
269 
270 		/* Bank 0 lives in the PMU. */
271 		if (bank < 1) {
272 			rm = sc->sc_pmu;
273 			base = RK3288_PMUGRF_GPIO0A_IOMUX;
274 		} else {
275 			rm = sc->sc_grf;
276 			base = RK3288_GRF_GPIO1A_IOMUX - 0x10;
277 		}
278 
279 		s = splhigh();
280 
281 		/* IOMUX control */
282 		off = bank * 0x10 + (idx / 8) * 0x04;
283 
284 		/* GPIO3D, GPIO4A and GPIO4B are special. */
285 		if ((bank == 3 && idx >= 24) || (bank == 4 && idx < 16)) {
286 			mask = (0x7 << ((idx % 4) * 4));
287 			bits = (mux << ((idx % 4) * 4));
288 		} else {
289 			mask = (0x3 << ((idx % 8) * 2));
290 			bits = (mux << ((idx % 8) * 2));
291 		}
292 		if (bank > 3 || (bank == 3 && idx >= 28))
293 			off += 0x04;
294 		if (bank > 4 || (bank == 4 && idx >= 4))
295 			off += 0x04;
296 		if (bank > 4 || (bank == 4 && idx >= 12))
297 			off += 0x04;
298 		regmap_write_4(rm, base + off, mask << 16 | bits);
299 
300 		/* GPIO pad pull down and pull up control */
301 		if (pull >= 0) {
302 			off = 0x140 + bank * 0x10 + (idx / 8) * 0x04;
303 			mask = (0x3 << ((idx % 8) * 2));
304 			bits = (pull << ((idx % 8) * 2));
305 			regmap_write_4(rm, base + off, mask << 16 | bits);
306 		}
307 
308 		/* GPIO drive strength control */
309 		if (strength >= 0) {
310 			off = 0x1c0 + bank * 0x10 + (idx / 8) * 0x04;
311 			mask = (0x3 << ((idx % 8) * 2));
312 			bits = (strength << ((idx % 8) * 2));
313 			regmap_write_4(rm, base + off, mask << 16 | bits);
314 		}
315 
316 		splx(s);
317 	}
318 
319 	free(pins, M_TEMP, len);
320 	return 0;
321 
322 fail:
323 	free(pins, M_TEMP, len);
324 	return -1;
325 }
326 
327 /*
328  * Rockchip RK3308
329  */
330 
331 int
rk3308_pull(uint32_t bank,uint32_t idx,uint32_t phandle)332 rk3308_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
333 {
334 	int node;
335 
336 	node = OF_getnodebyphandle(phandle);
337 	if (node == 0)
338 		return -1;
339 
340 	if (OF_getproplen(node, "bias-disable") == 0)
341 		return 0;
342 	if (OF_getproplen(node, "bias-pull-up") == 0)
343 		return 1;
344 	if (OF_getproplen(node, "bias-pull-down") == 0)
345 		return 2;
346 
347 	return -1;
348 }
349 
350 int
rk3308_strength(uint32_t bank,uint32_t idx,uint32_t phandle)351 rk3308_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
352 {
353 	int strength, level;
354 	int levels[4] = { 2, 4, 8, 12 };
355 	int node;
356 
357 	node = OF_getnodebyphandle(phandle);
358 	if (node == 0)
359 		return -1;
360 
361 	strength = OF_getpropint(node, "drive-strength", -1);
362 	if (strength == -1)
363 		return -1;
364 
365 	/* Convert drive strength to level. */
366 	for (level = 3; level >= 0; level--) {
367 		if (strength >= levels[level])
368 			break;
369 	}
370 	return level;
371 }
372 
373 int
rk3308_pinctrl(uint32_t phandle,void * cookie)374 rk3308_pinctrl(uint32_t phandle, void *cookie)
375 {
376 	struct rkpinctrl_softc *sc = cookie;
377 	uint32_t *pins;
378 	int node, len, i;
379 
380 	KASSERT(sc->sc_grf);
381 
382 	node = OF_getnodebyphandle(phandle);
383 	if (node == 0)
384 		return -1;
385 
386 	len = OF_getproplen(node, "rockchip,pins");
387 	if (len <= 0)
388 		return -1;
389 
390 	pins = malloc(len, M_TEMP, M_WAITOK);
391 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
392 		goto fail;
393 
394 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
395 		struct regmap *rm = sc->sc_grf;
396 		bus_size_t base, off;
397 		uint32_t bank, idx, mux;
398 		int pull, strength;
399 		uint32_t mask, bits;
400 		int s;
401 
402 		bank = pins[i];
403 		idx = pins[i + 1];
404 		mux = pins[i + 2];
405 
406 		if (bank > 4 || idx >= 32 || mux > 7)
407 			continue;
408 
409 		pull = rk3308_pull(bank, idx, pins[i + 3]);
410 		strength = rk3308_strength(bank, idx, pins[i + 3]);
411 
412 		base = RK3308_GRF_GPIO0A_IOMUX;
413 
414 		s = splhigh();
415 
416 		/* IOMUX control */
417 		off = bank * 0x20 + (idx / 8) * 0x08;
418 
419 		/* GPIO1B, GPIO1C and GPIO3B are special. */
420 		if ((bank == 1) && (idx == 14)) {
421 			mask = (0xf << 12);
422 			bits = (mux << 12);
423 		} else if ((bank == 1) && (idx == 15)) {
424 			off += 4;
425 			mask = 0x3;
426 			bits = mux;
427 		} else if ((bank == 1) && (idx >= 16 && idx <= 17)) {
428 			mask = (0x3 << ((idx - 16) * 2));
429 			bits = (mux << ((idx - 16) * 2));
430 		} else if ((bank == 1) && (idx >= 18 && idx <= 20)) {
431 			mask = (0xf << (((idx - 18) * 4) + 4));
432 			bits = (mux << (((idx - 18) * 4) + 4));
433 		} else if ((bank == 1) && (idx >= 21 && idx <= 23)) {
434 			off += 4;
435 			mask = (0xf << ((idx - 21) * 4));
436 			bits = (mux << ((idx - 21) * 4));
437 		} else if ((bank == 3) && (idx >= 12 && idx <= 13)) {
438 			mask = (0xf << (((idx - 12) * 4) + 8));
439 			bits = (mux << (((idx - 12) * 4) + 8));
440 		} else {
441 			mask = (0x3 << ((idx % 8) * 2));
442 			bits = (mux << ((idx % 8) * 2));
443 		}
444 		regmap_write_4(rm, base + off, mask << 16 | bits);
445 
446 		/* GPIO pad pull down and pull up control */
447 		if (pull >= 0) {
448 			off = 0xa0 + bank * 0x10 + (idx / 8) * 0x04;
449 			mask = (0x3 << ((idx % 8) * 2));
450 			bits = (pull << ((idx % 8) * 2));
451 			regmap_write_4(rm, base + off, mask << 16 | bits);
452 		}
453 
454 		/* GPIO drive strength control */
455 		if (strength >= 0) {
456 			off = 0x100 + bank * 0x10 + (idx / 8) * 0x04;
457 			mask = (0x3 << ((idx % 8) * 2));
458 			bits = (strength << ((idx % 8) * 2));
459 			regmap_write_4(rm, base + off, mask << 16 | bits);
460 		}
461 
462 		splx(s);
463 	}
464 
465 	free(pins, M_TEMP, len);
466 	return 0;
467 
468 fail:
469 	free(pins, M_TEMP, len);
470 	return -1;
471 }
472 
473 /*
474  * Rockchip RK3328
475  */
476 
477 int
rk3328_pull(uint32_t bank,uint32_t idx,uint32_t phandle)478 rk3328_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
479 {
480 	int node;
481 
482 	node = OF_getnodebyphandle(phandle);
483 	if (node == 0)
484 		return -1;
485 
486 	if (OF_getproplen(node, "bias-disable") == 0)
487 		return 0;
488 	if (OF_getproplen(node, "bias-pull-up") == 0)
489 		return 1;
490 	if (OF_getproplen(node, "bias-pull-down") == 0)
491 		return 2;
492 
493 	return -1;
494 }
495 
496 int
rk3328_strength(uint32_t bank,uint32_t idx,uint32_t phandle)497 rk3328_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
498 {
499 	int strength, level;
500 	int levels[4] = { 2, 4, 8, 12 };
501 	int node;
502 
503 	node = OF_getnodebyphandle(phandle);
504 	if (node == 0)
505 		return -1;
506 
507 	strength = OF_getpropint(node, "drive-strength", -1);
508 	if (strength == -1)
509 		return -1;
510 
511 	/* Convert drive strength to level. */
512 	for (level = 3; level >= 0; level--) {
513 		if (strength >= levels[level])
514 			break;
515 	}
516 	return level;
517 }
518 
519 int
rk3328_pinctrl(uint32_t phandle,void * cookie)520 rk3328_pinctrl(uint32_t phandle, void *cookie)
521 {
522 	struct rkpinctrl_softc *sc = cookie;
523 	uint32_t *pins;
524 	int node, len, i;
525 
526 	KASSERT(sc->sc_grf);
527 
528 	node = OF_getnodebyphandle(phandle);
529 	if (node == 0)
530 		return -1;
531 
532 	len = OF_getproplen(node, "rockchip,pins");
533 	if (len <= 0)
534 		return -1;
535 
536 	pins = malloc(len, M_TEMP, M_WAITOK);
537 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
538 		goto fail;
539 
540 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
541 		struct regmap *rm = sc->sc_grf;
542 		bus_size_t base, off;
543 		uint32_t bank, idx, mux;
544 		int pull, strength;
545 		uint32_t mask, bits;
546 		int s;
547 
548 		bank = pins[i];
549 		idx = pins[i + 1];
550 		mux = pins[i + 2];
551 
552 		if (bank > 3 || idx >= 32 || mux > 3)
553 			continue;
554 
555 		pull = rk3328_pull(bank, idx, pins[i + 3]);
556 		strength = rk3328_strength(bank, idx, pins[i + 3]);
557 
558 		base = RK3328_GRF_GPIO0A_IOMUX;
559 
560 		s = splhigh();
561 
562 		/* IOMUX control */
563 		off = bank * 0x10 + (idx / 8) * 0x04;
564 
565 		/* GPIO2B, GPIO2C, GPIO3A and GPIO3B are special. */
566 		if (bank == 2 && idx == 15) {
567 			mask = 0x7;
568 			bits = mux;
569 		} else if (bank == 2 && idx >= 16 && idx <= 20) {
570 			mask = (0x7 << ((idx - 16) * 3));
571 			bits = (mux << ((idx - 16) * 3));
572 		} else if (bank == 2 && idx >= 21 && idx <= 23) {
573 			mask = (0x7 << ((idx - 21) * 3));
574 			bits = (mux << ((idx - 21) * 3));
575 		} else if (bank == 3 && idx <= 4) {
576 			mask = (0x7 << (idx * 3));
577 			bits = (mux << (idx * 3));
578 		} else if (bank == 3 && idx >= 5 && idx <= 7) {
579 			mask = (0x7 << ((idx - 5) * 3));
580 			bits = (mux << ((idx - 5) * 3));
581 		} else if (bank == 3 && idx >= 8 && idx <= 12) {
582 			mask = (0x7 << ((idx - 8) * 3));
583 			bits = (mux << ((idx - 8) * 3));
584 		} else if (bank == 3 && idx >= 13 && idx <= 15) {
585 			mask = (0x7 << ((idx - 13) * 3));
586 			bits = (mux << ((idx - 13) * 3));
587 		} else {
588 			mask = (0x3 << ((idx % 8) * 2));
589 			bits = (mux << ((idx % 8) * 2));
590 		}
591 		if (bank > 2 || (bank == 2 && idx >= 15))
592 			off += 0x04;
593 		if (bank > 2 || (bank == 2 && idx >= 21))
594 			off += 0x04;
595 		if (bank > 3 || (bank == 3 && idx >= 5))
596 			off += 0x04;
597 		if (bank > 3 || (bank == 3 && idx >= 13))
598 			off += 0x04;
599 		regmap_write_4(rm, base + off, mask << 16 | bits);
600 
601 		/* GPIO pad pull down and pull up control */
602 		if (pull >= 0) {
603 			off = 0x100 + bank * 0x10 + (idx / 8) * 0x04;
604 			mask = (0x3 << ((idx % 8) * 2));
605 			bits = (pull << ((idx % 8) * 2));
606 			regmap_write_4(rm, base + off, mask << 16 | bits);
607 		}
608 
609 		/* GPIO drive strength control */
610 		if (strength >= 0) {
611 			off = 0x200 + bank * 0x10 + (idx / 8) * 0x04;
612 			mask = (0x3 << ((idx % 8) * 2));
613 			bits = (strength << ((idx % 8) * 2));
614 			regmap_write_4(rm, base + off, mask << 16 | bits);
615 		}
616 
617 		splx(s);
618 	}
619 
620 	free(pins, M_TEMP, len);
621 	return 0;
622 
623 fail:
624 	free(pins, M_TEMP, len);
625 	return -1;
626 }
627 
628 /*
629  * Rockchip RK3399
630  */
631 
632 int
rk3399_pull(uint32_t bank,uint32_t idx,uint32_t phandle)633 rk3399_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
634 {
635 	int pull_up, pull_down;
636 	int node;
637 
638 	node = OF_getnodebyphandle(phandle);
639 	if (node == 0)
640 		return -1;
641 
642 	if (bank == 2 && idx >= 16) {
643 		pull_up = 3;
644 		pull_down = 1;
645 	} else {
646 		pull_up = 1;
647 		pull_down = 2;
648 	}
649 
650 	if (OF_getproplen(node, "bias-disable") == 0)
651 		return 0;
652 	if (OF_getproplen(node, "bias-pull-up") == 0)
653 		return pull_up;
654 	if (OF_getproplen(node, "bias-pull-down") == 0)
655 		return pull_down;
656 
657 	return -1;
658 }
659 
660 /* Magic because the drive strength configurations vary wildly. */
661 
662 const int rk3399_strength_levels[][8] = {
663 	{ 2, 4, 8, 12 },			/* default */
664 	{ 3, 6, 9, 12 },			/* 1.8V or 3.0V */
665 	{ 5, 10, 15, 20 },			/* 1.8V only */
666 	{ 4, 6, 8, 10, 12, 14, 16, 18 },	/* 1.8V or 3.0V auto */
667 	{ 4, 7, 10, 13, 16, 19, 22, 26 },	/* 3.3V */
668 };
669 
670 const int rk3399_strength_types[][4] = {
671 	{ 2, 2, 0, 0 },
672 	{ 1, 1, 1, 1 },
673 	{ 1, 1, 2, 2 },
674 	{ 4, 4, 4, 1 },
675 	{ 1, 3, 1, 1 },
676 };
677 
678 const int rk3399_strength_regs[][4] = {
679 	{ 0x0080, 0x0088, 0x0090, 0x0098 },
680 	{ 0x00a0, 0x00a8, 0x00b0, 0x00b8 },
681 	{ 0x0100, 0x0104, 0x0108, 0x010c },
682 	{ 0x0110, 0x0118, 0x0120, 0x0128 },
683 	{ 0x012c, 0x0130, 0x0138, 0x013c },
684 };
685 
686 int
rk3399_strength(uint32_t bank,uint32_t idx,uint32_t phandle)687 rk3399_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
688 {
689 	int strength, type, level;
690 	const int *levels;
691 	int node;
692 
693 	node = OF_getnodebyphandle(phandle);
694 	if (node == 0)
695 		return -1;
696 
697 	strength = OF_getpropint(node, "drive-strength", -1);
698 	if (strength == -1)
699 		return -1;
700 
701 	/* Convert drive strength to level. */
702 	type = rk3399_strength_types[bank][idx / 8];
703 	levels = rk3399_strength_levels[type];
704 	for (level = 7; level >= 0; level--) {
705 		if (strength >= levels[level] && levels[level] > 0)
706 			break;
707 	}
708 	return level;
709 }
710 
711 int
rk3399_pinctrl(uint32_t phandle,void * cookie)712 rk3399_pinctrl(uint32_t phandle, void *cookie)
713 {
714 	struct rkpinctrl_softc *sc = cookie;
715 	uint32_t *pins;
716 	int node, len, i;
717 
718 	KASSERT(sc->sc_grf);
719 	KASSERT(sc->sc_pmu);
720 
721 	node = OF_getnodebyphandle(phandle);
722 	if (node == 0)
723 		return -1;
724 
725 	len = OF_getproplen(node, "rockchip,pins");
726 	if (len <= 0)
727 		return -1;
728 
729 	pins = malloc(len, M_TEMP, M_WAITOK);
730 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
731 		goto fail;
732 
733 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
734 		struct regmap *rm;
735 		bus_size_t base, off;
736 		uint32_t bank, idx, mux;
737 		int pull, strength, type, shift;
738 		uint32_t mask, bits;
739 		int s;
740 
741 		bank = pins[i];
742 		idx = pins[i + 1];
743 		mux = pins[i + 2];
744 
745 		if (bank > 4 || idx >= 32 || mux > 3)
746 			continue;
747 
748 		pull = rk3399_pull(bank, idx, pins[i + 3]);
749 		strength = rk3399_strength(bank, idx, pins[i + 3]);
750 
751 		/* Bank 0 and 1 live in the PMU. */
752 		if (bank < 2) {
753 			rm = sc->sc_pmu;
754 			base = RK3399_PMUGRF_GPIO0A_IOMUX;
755 		} else {
756 			rm = sc->sc_grf;
757 			base = RK3399_GRF_GPIO2A_IOMUX - 0x20;
758 		}
759 
760 		s = splhigh();
761 
762 		/* IOMUX control */
763 		off = bank * 0x10 + (idx / 8) * 0x04;
764 		mask = (0x3 << ((idx % 8) * 2));
765 		bits = (mux << ((idx % 8) * 2));
766 		regmap_write_4(rm, base + off, mask << 16 | bits);
767 
768 		/* GPIO pad pull down and pull up control */
769 		if (pull >= 0) {
770 			off = 0x40 + bank * 0x10 + (idx / 8) * 0x04;
771 			mask = (0x3 << ((idx % 8) * 2));
772 			bits = (pull << ((idx % 8) * 2));
773 			regmap_write_4(rm, base + off, mask << 16 | bits);
774 		}
775 
776 		/* GPIO drive strength control */
777 		if (strength >= 0) {
778 			off = rk3399_strength_regs[bank][idx / 8];
779 			type = rk3399_strength_types[bank][idx / 8];
780 			shift = (type > 2) ? 3 : 2;
781 			mask = (((1 << shift) - 1) << ((idx % 8) * shift));
782 			bits = (strength << ((idx % 8) * shift));
783 			if (mask & 0x0000ffff) {
784 				regmap_write_4(rm, base + off,
785 				    mask << 16 | (bits & 0x0000ffff));
786 			}
787 			if (mask & 0xffff0000) {
788 				regmap_write_4(rm, base + off + 0x04,
789 				    (mask & 0xffff0000) | bits >> 16);
790 			}
791 		}
792 
793 		splx(s);
794 	}
795 
796 	free(pins, M_TEMP, len);
797 	return 0;
798 
799 fail:
800 	free(pins, M_TEMP, len);
801 	return -1;
802 }
803 
804 /*
805  * Rockchip RK3568
806  */
807 
808 int
rk3568_pull(uint32_t bank,uint32_t idx,uint32_t phandle)809 rk3568_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
810 {
811 	int node;
812 
813 	node = OF_getnodebyphandle(phandle);
814 	if (node == 0)
815 		return -1;
816 
817 	if (OF_getproplen(node, "bias-disable") == 0)
818 		return 0;
819 	if (OF_getproplen(node, "bias-pull-up") == 0)
820 		return 1;
821 	if (OF_getproplen(node, "bias-pull-down") == 0)
822 		return 2;
823 
824 	return -1;
825 }
826 
827 int
rk3568_strength(uint32_t bank,uint32_t idx,uint32_t phandle)828 rk3568_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
829 {
830 	int node;
831 
832 	node = OF_getnodebyphandle(phandle);
833 	if (node == 0)
834 		return -1;
835 
836 	return OF_getpropint(node, "drive-strength", -1);
837 }
838 
839 int
rk3568_schmitt(uint32_t bank,uint32_t idx,uint32_t phandle)840 rk3568_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle)
841 {
842 	int node;
843 
844 	node = OF_getnodebyphandle(phandle);
845 	if (node == 0)
846 		return -1;
847 
848 	if (OF_getproplen(node, "input-schmitt-disable") == 0)
849 		return 1;
850 	if (OF_getproplen(node, "input-schmitt-enable") == 0)
851 		return 2;
852 
853 	return -1;
854 }
855 
856 struct rockchip_route_table rk3568_route_table[] = {
857 	{ 0, RK_PB7, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(0, 0) }, /* PWM0 M0 */
858 	{ 0, RK_PC7, 2, ROUTE_PMU, 0x0110, ROUTE_VAL(0, 1) }, /* PWM0 M1 */
859 	{ 0, RK_PC0, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(2, 0) }, /* PWM1 M0 */
860 	{ 0, RK_PB5, 4, ROUTE_PMU, 0x0110, ROUTE_VAL(2, 1) }, /* PWM1 M1 */
861 	{ 0, RK_PC1, 1, ROUTE_PMU, 0x0110, ROUTE_VAL(4, 0) }, /* PWM2 M0 */
862 	{ 0, RK_PB6, 4, ROUTE_PMU, 0x0110, ROUTE_VAL(4, 1) }, /* PWM2 M1 */
863 
864 	{ 3, RK_PB1, 3, ROUTE_GRF, 0x0300, ROUTE_VAL(8, 0) }, /* GMAC1 M0 */
865 	{ 4, RK_PA7, 3, ROUTE_GRF, 0x0300, ROUTE_VAL(8, 1) }, /* GMAC1 M1 */
866 	{ 0, RK_PB6, 1, ROUTE_GRF, 0x0300, ROUTE_VAL(14, 0) }, /* I2C2 M0 */
867 	{ 4, RK_PB4, 1, ROUTE_GRF, 0x0300, ROUTE_VAL(14, 1) }, /* I2C2 M1 */
868 
869 	{ 1, RK_PA0, 1, ROUTE_GRF, 0x0304, ROUTE_VAL(0, 0) }, /* I2C3 M0 */
870 	{ 3, RK_PB6, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(0, 1) }, /* I2C3 M1 */
871 	{ 4, RK_PB2, 1, ROUTE_GRF, 0x0304, ROUTE_VAL(2, 0) }, /* I2C4 M0 */
872 	{ 2, RK_PB1, 2, ROUTE_GRF, 0x0304, ROUTE_VAL(2, 1) }, /* I2C4 M1 */
873 	{ 3, RK_PB4, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(4, 0) }, /* I2C5 M0 */
874 	{ 4, RK_PD0, 2, ROUTE_GRF, 0x0304, ROUTE_VAL(4, 1) }, /* I2C5 M1 */
875 	{ 3, RK_PB1, 5, ROUTE_GRF, 0x0304, ROUTE_VAL(14, 0) }, /* PWM8 M0 */
876 	{ 1, RK_PD5, 4, ROUTE_GRF, 0x0304, ROUTE_VAL(14, 1) }, /* PWM8 M1 */
877 
878 	{ 3, RK_PB2, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(0, 0) }, /* PWM9 M0 */
879 	{ 1, RK_PD6, 4, ROUTE_GRF, 0x0308, ROUTE_VAL(0, 1) }, /* PWM9 M1 */
880 	{ 3, RK_PB5, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(2, 0) }, /* PWM10 M0 */
881 	{ 2, RK_PA1, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(2, 1) }, /* PWM10 M1 */
882 	{ 3, RK_PB6, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(4, 0) }, /* PWM11 M0 */
883 	{ 4, RK_PC0, 3, ROUTE_GRF, 0x0308, ROUTE_VAL(4, 1) }, /* PWM11 M1 */
884 	{ 3, RK_PB7, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(6, 0) }, /* PWM12 M0 */
885 	{ 4, RK_PC5, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(6, 1) }, /* PWM12 M1 */
886 	{ 3, RK_PC0, 2, ROUTE_GRF, 0x0308, ROUTE_VAL(8, 0) }, /* PWM13 M0 */
887 	{ 4, RK_PC6, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(8, 1) }, /* PWM13 M1 */
888 	{ 3, RK_PC4, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(10, 0) }, /* PWM14 M0 */
889 	{ 4, RK_PC2, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(10, 1) }, /* PWM14 M1 */
890 	{ 3, RK_PC5, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(12, 0) }, /* PWM15 M0 */
891 	{ 4, RK_PC3, 1, ROUTE_GRF, 0x0308, ROUTE_VAL(12, 1) }, /* PWM15 M1 */
892 	{ 3, RK_PD2, 3, ROUTE_GRF, 0x0308, ROUTE_VAL(14, 0) }, /* SDMMC2 M0 */
893 	{ 3, RK_PA5, 5, ROUTE_GRF, 0x0308, ROUTE_VAL(14, 1) }, /* SDMMC2 M1 */
894 
895 	{ 2, RK_PB4, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(8, 0) }, /* UART1 M0 */
896 	{ 3, RK_PD6, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(8, 1) }, /* UART1 M1 */
897 	{ 0, RK_PD1, 1, ROUTE_GRF, 0x030c, ROUTE_VAL(10, 0) }, /* UART2 M0 */
898 	{ 1, RK_PD5, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(10, 1) }, /* UART2 M1 */
899 	{ 1, RK_PA1, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(12, 0) }, /* UART3 M0 */
900 	{ 3, RK_PB7, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(12, 1) }, /* UART3 M1 */
901 	{ 1, RK_PA6, 2, ROUTE_GRF, 0x030c, ROUTE_VAL(14, 0) }, /* UART4 M0 */
902 	{ 3, RK_PB2, 4, ROUTE_GRF, 0x030c, ROUTE_VAL(14, 1) }, /* UART4 M1 */
903 
904 	{ 2, RK_PA2, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(0, 0) }, /* UART5 M0 */
905 	{ 3, RK_PC2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(0, 1) }, /* UART5 M1 */
906 	{ 2, RK_PA4, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(2, 0) }, /* UART6 M0 */
907 	{ 1, RK_PD5, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(2, 1) }, /* UART6 M1 */
908 	{ 2, RK_PA6, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 0) }, /* UART7 M0 */
909 	{ 3, RK_PC4, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 1) }, /* UART7 M1 */
910 	{ 4, RK_PA2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(4, 2) }, /* UART7 M2 */
911 	{ 2, RK_PC5, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(6, 0) }, /* UART8 M0 */
912 	{ 2, RK_PD7, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(6, 1) }, /* UART8 M1 */
913 	{ 2, RK_PB0, 3, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 0) }, /* UART9 M0 */
914 	{ 4, RK_PC5, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 1) }, /* UART9 M1 */
915 	{ 4, RK_PA4, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(8, 2) }, /* UART9 M2 */
916 	{ 1, RK_PA2, 1, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 0) }, /* I2S1 M0 */
917 	{ 3, RK_PC6, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 1) }, /* I2S1 M1 */
918 	{ 2, RK_PD0, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(10, 2) }, /* I2S1 M2 */
919 	{ 2, RK_PC1, 1, ROUTE_GRF, 0x0310, ROUTE_VAL(12, 0) }, /* I2S2 M0 */
920 	{ 4, RK_PB6, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(12, 1) }, /* I2S2 M1 */
921 	{ 3, RK_PA2, 4, ROUTE_GRF, 0x0310, ROUTE_VAL(14, 0) }, /* I2S3 M0 */
922 	{ 4, RK_PC2, 5, ROUTE_GRF, 0x0310, ROUTE_VAL(14, 1) }, /* I2S3 M1 */
923 
924 	{ 0, RK_PA5, 3, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 0) }, /* PCIE20 M0 */
925 	{ 2, RK_PD0, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 1) }, /* PCIE20 M1 */
926 	{ 1, RK_PB0, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(2, 2) }, /* PCIE20 M2 */
927 	{ 0, RK_PA4, 3, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 0) }, /* PCIE30X1 M0 */
928 	{ 2, RK_PD2, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 1) }, /* PCIE30X1 M1 */
929 	{ 1, RK_PA5, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(4, 2) }, /* PCIE30X1 M2 */
930 	{ 0, RK_PA6, 2, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 0) }, /* PCIE30X2 M0 */
931 	{ 2, RK_PD4, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 1) }, /* PCIE30X2 M1 */
932 	{ 4, RK_PC2, 4, ROUTE_GRF, 0x0314, ROUTE_VAL(6, 2) }, /* PCIE30X2 M2 */
933 };
934 
935 void
rk3568_route(struct rkpinctrl_softc * sc,uint32_t * pins)936 rk3568_route(struct rkpinctrl_softc *sc, uint32_t *pins)
937 {
938 	struct rockchip_route_table *route = NULL;
939 	struct regmap *rm;
940 	int bank = pins[0];
941 	int idx = pins[1];
942 	int mux = pins[2];
943 	int i;
944 
945 	for (i = 0; i < nitems(rk3568_route_table); i++) {
946 		if (bank == rk3568_route_table[i].bank &&
947 		    idx == rk3568_route_table[i].idx &&
948 		    mux == rk3568_route_table[i].mux) {
949 			route = &rk3568_route_table[i];
950 			break;
951 		}
952 	}
953 	if (route == NULL)
954 		return;
955 
956 	rm = route->grf ? sc->sc_pmu : sc->sc_grf;
957 	regmap_write_4(rm, route->reg, route->val);
958 }
959 
960 int
rk3568_pinctrl(uint32_t phandle,void * cookie)961 rk3568_pinctrl(uint32_t phandle, void *cookie)
962 {
963 	struct rkpinctrl_softc *sc = cookie;
964 	uint32_t *pins;
965 	int node, len, i;
966 
967 	KASSERT(sc->sc_grf);
968 	KASSERT(sc->sc_pmu);
969 
970 	node = OF_getnodebyphandle(phandle);
971 	if (node == 0)
972 		return -1;
973 
974 	len = OF_getproplen(node, "rockchip,pins");
975 	if (len <= 0)
976 		return -1;
977 
978 	pins = malloc(len, M_TEMP, M_WAITOK);
979 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
980 		goto fail;
981 
982 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
983 		struct regmap *rm;
984 		bus_size_t iomux_base, p_base, ds_base, ie_base, off;
985 		uint32_t bank, idx, mux;
986 		int pull, strength, schmitt;
987 		uint32_t mask, bits;
988 		int s;
989 
990 		bank = pins[i];
991 		idx = pins[i + 1];
992 		mux = pins[i + 2];
993 
994 		if (bank > 5 || idx >= 32 || mux > 7)
995 			continue;
996 
997 		pull = rk3568_pull(bank, idx, pins[i + 3]);
998 		strength = rk3568_strength(bank, idx, pins[i + 3]);
999 		schmitt = rk3568_schmitt(bank, idx, pins[i + 3]);
1000 
1001 		/* Bank 0 lives in the PMU. */
1002 		if (bank < 1) {
1003 			rm = sc->sc_pmu;
1004 			iomux_base = RK3568_PMUGRF_GPIO0A_IOMUX_L;
1005 			p_base = RK3568_PMUGRF_GPIO0A_P;
1006 			ds_base = RK3568_PMUGRF_GPIO0A_DS_0;
1007 			ie_base = RK3568_PMUGRF_GPIO0A_IE;
1008 		} else {
1009 			rm = sc->sc_grf;
1010 			iomux_base = RK3568_GRF_GPIO1A_IOMUX_L;
1011 			p_base = RK3568_GRF_GPIO1A_P;
1012 			ds_base = RK3568_GRF_GPIO1A_DS_0;
1013 			ie_base = RK3568_GRF_GPIO1A_IE;
1014 			bank = bank - 1;
1015 		}
1016 
1017 		s = splhigh();
1018 
1019 		/* IOMUX control */
1020 		rk3568_route(sc, &pins[i]);
1021 		off = bank * 0x20 + (idx / 4) * 0x04;
1022 		mask = (0x7 << ((idx % 4) * 4));
1023 		bits = (mux << ((idx % 4) * 4));
1024 		regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1025 
1026 		/* GPIO pad pull down and pull up control */
1027 		if (pull >= 0) {
1028 			off = bank * 0x10 + (idx / 8) * 0x04;
1029 			mask = (0x3 << ((idx % 8) * 2));
1030 			bits = (pull << ((idx % 8) * 2));
1031 			regmap_write_4(rm, p_base + off, mask << 16 | bits);
1032 		}
1033 
1034 		/* GPIO drive strength control */
1035 		if (strength >= 0) {
1036 			off = bank * 0x40 + (idx / 2) * 0x04;
1037 			mask = (0x3f << ((idx % 2) * 8));
1038 			bits = ((1 << (strength + 1)) - 1) << ((idx % 2) * 8);
1039 			regmap_write_4(rm, ds_base + off, mask << 16 | bits);
1040 		}
1041 
1042 		/* GPIO Schmitt trigger. */
1043 		if (schmitt >= 0) {
1044 			off = bank * 0x10 + (idx / 8) * 0x04;
1045 			mask = (0x3 << ((idx % 8) * 2));
1046 			bits = schmitt << ((idx % 8) * 2);
1047 			regmap_write_4(rm, ie_base + off, mask << 16 | bits);
1048 		}
1049 
1050 		splx(s);
1051 	}
1052 
1053 	free(pins, M_TEMP, len);
1054 	return 0;
1055 
1056 fail:
1057 	free(pins, M_TEMP, len);
1058 	return -1;
1059 }
1060 
1061 
1062 /*
1063  * Rockchip RK3588
1064  */
1065 
1066 int
rk3588_pull(uint32_t bank,uint32_t idx,uint32_t phandle)1067 rk3588_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
1068 {
1069 	int node;
1070 
1071 	node = OF_getnodebyphandle(phandle);
1072 	if (node == 0)
1073 		return -1;
1074 
1075 	if (OF_getproplen(node, "bias-disable") == 0)
1076 		return 0;
1077 	if (OF_getproplen(node, "bias-pull-up") == 0)
1078 		return 3;
1079 	if (OF_getproplen(node, "bias-pull-down") == 0)
1080 		return 1;
1081 
1082 	return -1;
1083 }
1084 
1085 int
rk3588_strength(uint32_t bank,uint32_t idx,uint32_t phandle)1086 rk3588_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
1087 {
1088 	int node;
1089 
1090 	node = OF_getnodebyphandle(phandle);
1091 	if (node == 0)
1092 		return -1;
1093 
1094 	return OF_getpropint(node, "drive-strength", -1);
1095 }
1096 
1097 int
rk3588_schmitt(uint32_t bank,uint32_t idx,uint32_t phandle)1098 rk3588_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle)
1099 {
1100 	int node;
1101 
1102 	node = OF_getnodebyphandle(phandle);
1103 	if (node == 0)
1104 		return -1;
1105 
1106 	if (OF_getproplen(node, "input-schmitt-disable") == 0)
1107 		return 0;
1108 	if (OF_getproplen(node, "input-schmitt-enable") == 0)
1109 		return 1;
1110 
1111 	return -1;
1112 }
1113 
1114 #define RK3588_PMU1_IOC		0x0000
1115 #define RK3588_PMU2_IOC		0x4000
1116 #define RK3588_BUS_IOC		0x8000
1117 #define RK3588_VCCIO1_4_IOC	0x9000
1118 #define RK3588_VCCIO3_5_IOC	0xa000
1119 #define RK3588_VCCIO2_IOC	0xb000
1120 #define RK3588_VCCIO6_IOC	0xc000
1121 #define RK3588_EMMC_IOC		0xd000
1122 
1123 bus_size_t
rk3588_base(uint32_t bank,uint32_t idx)1124 rk3588_base(uint32_t bank, uint32_t idx)
1125 {
1126 	if (bank == 1 && idx < 32)
1127 		return RK3588_VCCIO1_4_IOC;
1128 	if (bank == 2 && idx < 6)
1129 		return RK3588_EMMC_IOC;
1130 	if (bank == 2 && idx < 24)
1131 		return RK3588_VCCIO3_5_IOC;
1132 	if (bank == 2 && idx < 32)
1133 		return RK3588_EMMC_IOC;
1134 	if (bank == 3 && idx < 32)
1135 		return RK3588_VCCIO3_5_IOC;
1136 	if (bank == 4 && idx < 18)
1137 		return RK3588_VCCIO6_IOC;
1138 	if (bank == 4 && idx < 24)
1139 		return RK3588_VCCIO3_5_IOC;
1140 	if (bank == 4 && idx < 32)
1141 		return RK3588_VCCIO2_IOC;
1142 
1143 	return (bus_size_t)-1;
1144 }
1145 
1146 int
rk3588_pinctrl(uint32_t phandle,void * cookie)1147 rk3588_pinctrl(uint32_t phandle, void *cookie)
1148 {
1149 	struct rkpinctrl_softc *sc = cookie;
1150 	struct regmap *rm = sc->sc_grf;
1151 	uint32_t *pins;
1152 	int node, len, i;
1153 
1154 	KASSERT(sc->sc_grf);
1155 
1156 	node = OF_getnodebyphandle(phandle);
1157 	if (node == 0)
1158 		return -1;
1159 
1160 	len = OF_getproplen(node, "rockchip,pins");
1161 	if (len <= 0)
1162 		return -1;
1163 
1164 	pins = malloc(len, M_TEMP, M_WAITOK);
1165 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
1166 		goto fail;
1167 
1168 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
1169 		bus_size_t iomux_base, p_base, ds_base, smt_base, off;
1170 		uint32_t bank, idx, mux;
1171 		int pull, strength, schmitt;
1172 		uint32_t mask, bits;
1173 		int s;
1174 
1175 		bank = pins[i];
1176 		idx = pins[i + 1];
1177 		mux = pins[i + 2];
1178 
1179 		if (bank > 5 || idx >= 32 || mux > 15)
1180 			continue;
1181 
1182 		pull = rk3588_pull(bank, idx, pins[i + 3]);
1183 		strength = rk3588_strength(bank, idx, pins[i + 3]);
1184 		schmitt = rk3588_schmitt(bank, idx, pins[i + 3]);
1185 
1186 		if (bank == 0 && idx < 12) {
1187 			/* PMU1 */
1188 			iomux_base = RK3588_PMU1_IOC;
1189 		} else {
1190 			/* BUS */
1191 			iomux_base = RK3588_BUS_IOC;
1192 		}
1193 
1194 		if (bank == 0) {
1195 			if (idx < 12) {
1196 				/* PMU1 */
1197 				p_base = RK3588_PMU1_IOC + 0x0020;
1198 				ds_base = RK3588_PMU1_IOC + 0x0010;
1199 				smt_base = RK3588_PMU1_IOC + 0x0030;
1200 			} else {
1201 				/* PMU2 */
1202 				p_base = RK3588_PMU2_IOC + 0x0024;
1203 				ds_base = RK3588_PMU2_IOC + 0x0008;
1204 				smt_base = RK3588_PMU2_IOC + 0x003c;
1205 			}
1206 		} else {
1207 			bus_size_t base = rk3588_base(bank, idx);
1208 			KASSERT(base != (bus_size_t)-1);
1209 
1210 			p_base = base + 0x0100;
1211 			ds_base = base + 0x0000;
1212 			smt_base = base + 0x0200;
1213 		}
1214 
1215 		s = splhigh();
1216 
1217 		/* IOMUX control */
1218 		off = bank * 0x20 + (idx / 4) * 0x04;
1219 		mask = (0xf << ((idx % 4) * 4));
1220 		bits = (mux << ((idx % 4) * 4));
1221 		regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1222 		if (bank == 0 && idx > 12) {
1223 			iomux_base = RK3588_PMU2_IOC;
1224 			off = (idx - 12) / 4 * 0x04;
1225 			mux = (mux < 8) ? mux : 8;
1226 			bits = (mux << ((idx % 4) * 4));
1227 			regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1228 		}
1229 
1230 		/* GPIO pad pull down and pull up control */
1231 		if (pull >= 0) {
1232 			off = bank * 0x10 + (idx / 8) * 0x04;
1233 			mask = (0x3 << ((idx % 8) * 2));
1234 			bits = (pull << ((idx % 8) * 2));
1235 			regmap_write_4(rm, p_base + off, mask << 16 | bits);
1236 		}
1237 
1238 		/* GPIO drive strength control */
1239 		if (strength >= 0) {
1240 			off = bank * 0x20 + (idx / 4) * 0x04;
1241 			mask = (0xf << ((idx % 4) * 4));
1242 			bits = (strength << ((idx % 4) * 4));
1243 			regmap_write_4(rm, ds_base + off, mask << 16 | bits);
1244 		}
1245 
1246 		/* GPIO Schmitt trigger. */
1247 		if (schmitt >= 0) {
1248 			off = bank * 0x10 + (idx / 8) * 0x04;
1249 			mask = (0x1 << (idx % 8));
1250 			bits = (schmitt << (idx % 8));
1251 			regmap_write_4(rm, smt_base + off, mask << 16 | bits);
1252 		}
1253 
1254 		splx(s);
1255 	}
1256 
1257 	free(pins, M_TEMP, len);
1258 	return 0;
1259 
1260 fail:
1261 	free(pins, M_TEMP, len);
1262 	return -1;
1263 }
1264