xref: /openbsd-src/sys/dev/fdt/rkpinctrl.c (revision ff0e7be1ebbcc809ea8ad2b6dafe215824da9e46)
1 /*	$OpenBSD: rkpinctrl.c,v 1.11 2023/03/04 22:51:12 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 #ifdef __armv7__
33 #include <arm/simplebus/simplebusvar.h>
34 #else
35 #include <arm64/dev/simplebusvar.h>
36 #endif
37 
38 /* Pin numbers (from devicetree bindings) */
39 #define RK_PA0		0
40 #define RK_PA1		1
41 #define RK_PA2		2
42 #define RK_PA3		3
43 #define RK_PA4		4
44 #define RK_PA5		5
45 #define RK_PA6		6
46 #define RK_PA7		7
47 #define RK_PB0		8
48 #define RK_PB1		9
49 #define RK_PB2		10
50 #define RK_PB3		11
51 #define RK_PB4		12
52 #define RK_PB5		13
53 #define RK_PB6		14
54 #define RK_PB7		15
55 #define RK_PC0		16
56 #define RK_PC1		17
57 #define RK_PC2		18
58 #define RK_PC3		19
59 #define RK_PC4		20
60 #define RK_PC5		21
61 #define RK_PC6		22
62 #define RK_PC7		23
63 #define RK_PD0		24
64 #define RK_PD1		25
65 #define RK_PD2		26
66 #define RK_PD3		27
67 #define RK_PD4		28
68 #define RK_PD5		29
69 #define RK_PD6		30
70 #define RK_PD7		31
71 
72 /* RK3288 registers */
73 #define RK3288_GRF_GPIO1A_IOMUX		0x0000
74 #define RK3288_PMUGRF_GPIO0A_IOMUX	0x0084
75 
76 /* RK3308 registers */
77 #define RK3308_GRF_GPIO0A_IOMUX		0x0000
78 
79 /* RK3328 registers */
80 #define RK3328_GRF_GPIO0A_IOMUX		0x0000
81 
82 /* RK3399 registers */
83 #define RK3399_GRF_GPIO2A_IOMUX		0xe000
84 #define RK3399_PMUGRF_GPIO0A_IOMUX	0x0000
85 
86 /* RK3568 registers */
87 #define RK3568_GRF_GPIO1A_IOMUX_L	0x0000
88 #define RK3568_GRF_GPIO1A_P		0x0080
89 #define RK3568_GRF_GPIO1A_IE		0x00c0
90 #define RK3568_GRF_GPIO1A_DS_0		0x0200
91 #define RK3568_PMUGRF_GPIO0A_IOMUX_L	0x0000
92 #define RK3568_PMUGRF_GPIO0A_P		0x0020
93 #define RK3568_PMUGRF_GPIO0A_IE		0x0030
94 #define RK3568_PMUGRF_GPIO0A_DS_0	0x0070
95 
96 struct rockchip_route_table {
97 	u_int bank : 3;
98 	u_int idx : 5;
99 	u_int mux : 3;
100 	u_int grf : 1;
101 #define ROUTE_GRF	0
102 #define ROUTE_PMU	1
103 	uint16_t reg;
104 	uint32_t val;
105 #define ROUTE_VAL(bit, val)	((0x3 << (bit)) << 16 | ((val) << (bit)))
106 };
107 
108 struct rkpinctrl_softc {
109 	struct simplebus_softc	sc_sbus;
110 
111 	struct regmap		*sc_grf;
112 	struct regmap		*sc_pmu;
113 };
114 
115 int	rkpinctrl_match(struct device *, void *, void *);
116 void	rkpinctrl_attach(struct device *, struct device *, void *);
117 
118 const struct cfattach	rkpinctrl_ca = {
119 	sizeof (struct rkpinctrl_softc), rkpinctrl_match, rkpinctrl_attach
120 };
121 
122 struct cfdriver rkpinctrl_cd = {
123 	NULL, "rkpinctrl", DV_DULL
124 };
125 
126 int	rk3288_pinctrl(uint32_t, void *);
127 int	rk3308_pinctrl(uint32_t, void *);
128 int	rk3328_pinctrl(uint32_t, void *);
129 int	rk3399_pinctrl(uint32_t, void *);
130 int	rk3568_pinctrl(uint32_t, void *);
131 int	rk3588_pinctrl(uint32_t, void *);
132 
133 int
134 rkpinctrl_match(struct device *parent, void *match, void *aux)
135 {
136 	struct fdt_attach_args *faa = aux;
137 
138 	return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl") ||
139 	    OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl") ||
140 	    OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl") ||
141 	    OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl") ||
142 	    OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl") ||
143 	    OF_is_compatible(faa->fa_node, "rockchip,rk3588-pinctrl"));
144 }
145 
146 void
147 rkpinctrl_attach(struct device *parent, struct device *self, void *aux)
148 {
149 	struct rkpinctrl_softc *sc = (struct rkpinctrl_softc *)self;
150 	struct fdt_attach_args *faa = aux;
151 	uint32_t grf, pmu;
152 
153 	grf = OF_getpropint(faa->fa_node, "rockchip,grf", 0);
154 	pmu = OF_getpropint(faa->fa_node, "rockchip,pmu", 0);
155 	sc->sc_grf = regmap_byphandle(grf);
156 	sc->sc_pmu = regmap_byphandle(pmu);
157 
158 	if (sc->sc_grf == NULL && sc->sc_pmu == NULL) {
159 		printf(": no registers\n");
160 		return;
161 	}
162 
163 	if (OF_is_compatible(faa->fa_node, "rockchip,rk3288-pinctrl"))
164 		pinctrl_register(faa->fa_node, rk3288_pinctrl, sc);
165 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3308-pinctrl"))
166 		pinctrl_register(faa->fa_node, rk3308_pinctrl, sc);
167 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3328-pinctrl"))
168 		pinctrl_register(faa->fa_node, rk3328_pinctrl, sc);
169 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-pinctrl"))
170 		pinctrl_register(faa->fa_node, rk3399_pinctrl, sc);
171 	else if (OF_is_compatible(faa->fa_node, "rockchip,rk3568-pinctrl"))
172 		pinctrl_register(faa->fa_node, rk3568_pinctrl, sc);
173 	else
174 		pinctrl_register(faa->fa_node, rk3588_pinctrl, sc);
175 
176 	/* Attach GPIO banks. */
177 	simplebus_attach(parent, &sc->sc_sbus.sc_dev, faa);
178 }
179 
180 /*
181  * Rockchip RK3288
182  */
183 
184 int
185 rk3288_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
186 {
187 	int node;
188 
189 	node = OF_getnodebyphandle(phandle);
190 	if (node == 0)
191 		return -1;
192 
193 	/* XXX */
194 	if (bank == 0)
195 		return -1;
196 
197 	if (OF_getproplen(node, "bias-disable") == 0)
198 		return 0;
199 	if (OF_getproplen(node, "bias-pull-up") == 0)
200 		return 1;
201 	if (OF_getproplen(node, "bias-pull-down") == 0)
202 		return 2;
203 
204 	return -1;
205 }
206 
207 int
208 rk3288_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
209 {
210 	int strength, level;
211 	int levels[4] = { 2, 4, 8, 12 };
212 	int node;
213 
214 	node = OF_getnodebyphandle(phandle);
215 	if (node == 0)
216 		return -1;
217 
218 	/* XXX */
219 	if (bank == 0)
220 		return -1;
221 
222 	strength = OF_getpropint(node, "drive-strength", -1);
223 	if (strength == -1)
224 		return -1;
225 
226 	/* Convert drive strength to level. */
227 	for (level = 3; level >= 0; level--) {
228 		if (strength >= levels[level])
229 			break;
230 	}
231 	return level;
232 }
233 
234 int
235 rk3288_pinctrl(uint32_t phandle, void *cookie)
236 {
237 	struct rkpinctrl_softc *sc = cookie;
238 	uint32_t *pins;
239 	int node, len, i;
240 
241 	KASSERT(sc->sc_grf);
242 	KASSERT(sc->sc_pmu);
243 
244 	node = OF_getnodebyphandle(phandle);
245 	if (node == 0)
246 		return -1;
247 
248 	len = OF_getproplen(node, "rockchip,pins");
249 	if (len <= 0)
250 		return -1;
251 
252 	pins = malloc(len, M_TEMP, M_WAITOK);
253 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
254 		goto fail;
255 
256 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
257 		struct regmap *rm;
258 		bus_size_t base, off;
259 		uint32_t bank, idx, mux;
260 		int pull, strength;
261 		uint32_t mask, bits;
262 		int s;
263 
264 		bank = pins[i];
265 		idx = pins[i + 1];
266 		mux = pins[i + 2];
267 		pull = rk3288_pull(bank, idx, pins[i + 3]);
268 		strength = rk3288_strength(bank, idx, pins[i + 3]);
269 
270 		if (bank > 8 || idx > 32 || mux > 7)
271 			continue;
272 
273 		/* Bank 0 lives in the PMU. */
274 		if (bank < 1) {
275 			rm = sc->sc_pmu;
276 			base = RK3288_PMUGRF_GPIO0A_IOMUX;
277 		} else {
278 			rm = sc->sc_grf;
279 			base = RK3288_GRF_GPIO1A_IOMUX - 0x10;
280 		}
281 
282 		s = splhigh();
283 
284 		/* IOMUX control */
285 		off = bank * 0x10 + (idx / 8) * 0x04;
286 
287 		/* GPIO3D, GPIO4A and GPIO4B are special. */
288 		if ((bank == 3 && idx >= 24) || (bank == 4 && idx < 16)) {
289 			mask = (0x7 << ((idx % 4) * 4));
290 			bits = (mux << ((idx % 4) * 4));
291 		} else {
292 			mask = (0x3 << ((idx % 8) * 2));
293 			bits = (mux << ((idx % 8) * 2));
294 		}
295 		if (bank > 3 || (bank == 3 && idx >= 28))
296 			off += 0x04;
297 		if (bank > 4 || (bank == 4 && idx >= 4))
298 			off += 0x04;
299 		if (bank > 4 || (bank == 4 && idx >= 12))
300 			off += 0x04;
301 		regmap_write_4(rm, base + off, mask << 16 | bits);
302 
303 		/* GPIO pad pull down and pull up control */
304 		if (pull >= 0) {
305 			off = 0x140 + bank * 0x10 + (idx / 8) * 0x04;
306 			mask = (0x3 << ((idx % 8) * 2));
307 			bits = (pull << ((idx % 8) * 2));
308 			regmap_write_4(rm, base + off, mask << 16 | bits);
309 		}
310 
311 		/* GPIO drive strength control */
312 		if (strength >= 0) {
313 			off = 0x1c0 + bank * 0x10 + (idx / 8) * 0x04;
314 			mask = (0x3 << ((idx % 8) * 2));
315 			bits = (strength << ((idx % 8) * 2));
316 			regmap_write_4(rm, base + off, mask << 16 | bits);
317 		}
318 
319 		splx(s);
320 	}
321 
322 	free(pins, M_TEMP, len);
323 	return 0;
324 
325 fail:
326 	free(pins, M_TEMP, len);
327 	return -1;
328 }
329 
330 /*
331  * Rockchip RK3308
332  */
333 
334 int
335 rk3308_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
336 {
337 	int node;
338 
339 	node = OF_getnodebyphandle(phandle);
340 	if (node == 0)
341 		return -1;
342 
343 	if (OF_getproplen(node, "bias-disable") == 0)
344 		return 0;
345 	if (OF_getproplen(node, "bias-pull-up") == 0)
346 		return 1;
347 	if (OF_getproplen(node, "bias-pull-down") == 0)
348 		return 2;
349 
350 	return -1;
351 }
352 
353 int
354 rk3308_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
355 {
356 	int strength, level;
357 	int levels[4] = { 2, 4, 8, 12 };
358 	int node;
359 
360 	node = OF_getnodebyphandle(phandle);
361 	if (node == 0)
362 		return -1;
363 
364 	strength = OF_getpropint(node, "drive-strength", -1);
365 	if (strength == -1)
366 		return -1;
367 
368 	/* Convert drive strength to level. */
369 	for (level = 3; level >= 0; level--) {
370 		if (strength >= levels[level])
371 			break;
372 	}
373 	return level;
374 }
375 
376 int
377 rk3308_pinctrl(uint32_t phandle, void *cookie)
378 {
379 	struct rkpinctrl_softc *sc = cookie;
380 	uint32_t *pins;
381 	int node, len, i;
382 
383 	KASSERT(sc->sc_grf);
384 
385 	node = OF_getnodebyphandle(phandle);
386 	if (node == 0)
387 		return -1;
388 
389 	len = OF_getproplen(node, "rockchip,pins");
390 	if (len <= 0)
391 		return -1;
392 
393 	pins = malloc(len, M_TEMP, M_WAITOK);
394 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
395 		goto fail;
396 
397 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
398 		struct regmap *rm = sc->sc_grf;
399 		bus_size_t base, off;
400 		uint32_t bank, idx, mux;
401 		int pull, strength;
402 		uint32_t mask, bits;
403 		int s;
404 
405 		bank = pins[i];
406 		idx = pins[i + 1];
407 		mux = pins[i + 2];
408 		pull = rk3308_pull(bank, idx, pins[i + 3]);
409 		strength = rk3308_strength(bank, idx, pins[i + 3]);
410 
411 		if (bank > 4 || idx > 32 || mux > 7)
412 			continue;
413 
414 		base = RK3308_GRF_GPIO0A_IOMUX;
415 
416 		s = splhigh();
417 
418 		/* IOMUX control */
419 		off = bank * 0x20 + (idx / 8) * 0x08;
420 
421 		/* GPIO1B, GPIO1C and GPIO3B are special. */
422 		if ((bank == 1) && (idx == 14)) {
423 			mask = (0xf << 12);
424 			bits = (mux << 12);
425 		} else if ((bank == 1) && (idx == 15)) {
426 			off += 4;
427 			mask = 0x3;
428 			bits = mux;
429 		} else if ((bank == 1) && (idx >= 16 && idx <= 17)) {
430 			mask = (0x3 << ((idx - 16) * 2));
431 			bits = (mux << ((idx - 16) * 2));
432 		} else if ((bank == 1) && (idx >= 18 && idx <= 20)) {
433 			mask = (0xf << (((idx - 18) * 4) + 4));
434 			bits = (mux << (((idx - 18) * 4) + 4));
435 		} else if ((bank == 1) && (idx >= 21 && idx <= 23)) {
436 			off += 4;
437 			mask = (0xf << ((idx - 21) * 4));
438 			bits = (mux << ((idx - 21) * 4));
439 		} else if ((bank == 3) && (idx >= 12 && idx <= 13)) {
440 			mask = (0xf << (((idx - 12) * 4) + 8));
441 			bits = (mux << (((idx - 12) * 4) + 8));
442 		} else {
443 			mask = (0x3 << ((idx % 8) * 2));
444 			bits = (mux << ((idx % 8) * 2));
445 		}
446 		regmap_write_4(rm, base + off, mask << 16 | bits);
447 
448 		/* GPIO pad pull down and pull up control */
449 		if (pull >= 0) {
450 			off = 0xa0 + bank * 0x10 + (idx / 8) * 0x04;
451 			mask = (0x3 << ((idx % 8) * 2));
452 			bits = (pull << ((idx % 8) * 2));
453 			regmap_write_4(rm, base + off, mask << 16 | bits);
454 		}
455 
456 		/* GPIO drive strength control */
457 		if (strength >= 0) {
458 			off = 0x100 + bank * 0x10 + (idx / 8) * 0x04;
459 			mask = (0x3 << ((idx % 8) * 2));
460 			bits = (strength << ((idx % 8) * 2));
461 			regmap_write_4(rm, base + off, mask << 16 | bits);
462 		}
463 
464 		splx(s);
465 	}
466 
467 	free(pins, M_TEMP, len);
468 	return 0;
469 
470 fail:
471 	free(pins, M_TEMP, len);
472 	return -1;
473 }
474 
475 /*
476  * Rockchip RK3328
477  */
478 
479 int
480 rk3328_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
481 {
482 	int node;
483 
484 	node = OF_getnodebyphandle(phandle);
485 	if (node == 0)
486 		return -1;
487 
488 	if (OF_getproplen(node, "bias-disable") == 0)
489 		return 0;
490 	if (OF_getproplen(node, "bias-pull-up") == 0)
491 		return 1;
492 	if (OF_getproplen(node, "bias-pull-down") == 0)
493 		return 2;
494 
495 	return -1;
496 }
497 
498 int
499 rk3328_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
500 {
501 	int strength, level;
502 	int levels[4] = { 2, 4, 8, 12 };
503 	int node;
504 
505 	node = OF_getnodebyphandle(phandle);
506 	if (node == 0)
507 		return -1;
508 
509 	strength = OF_getpropint(node, "drive-strength", -1);
510 	if (strength == -1)
511 		return -1;
512 
513 	/* Convert drive strength to level. */
514 	for (level = 3; level >= 0; level--) {
515 		if (strength >= levels[level])
516 			break;
517 	}
518 	return level;
519 }
520 
521 int
522 rk3328_pinctrl(uint32_t phandle, void *cookie)
523 {
524 	struct rkpinctrl_softc *sc = cookie;
525 	uint32_t *pins;
526 	int node, len, i;
527 
528 	KASSERT(sc->sc_grf);
529 
530 	node = OF_getnodebyphandle(phandle);
531 	if (node == 0)
532 		return -1;
533 
534 	len = OF_getproplen(node, "rockchip,pins");
535 	if (len <= 0)
536 		return -1;
537 
538 	pins = malloc(len, M_TEMP, M_WAITOK);
539 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
540 		goto fail;
541 
542 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
543 		struct regmap *rm = sc->sc_grf;
544 		bus_size_t base, off;
545 		uint32_t bank, idx, mux;
546 		int pull, strength;
547 		uint32_t mask, bits;
548 		int s;
549 
550 		bank = pins[i];
551 		idx = pins[i + 1];
552 		mux = pins[i + 2];
553 		pull = rk3288_pull(bank, idx, pins[i + 3]);
554 		strength = rk3288_strength(bank, idx, pins[i + 3]);
555 
556 		if (bank > 3 || idx > 32 || mux > 3)
557 			continue;
558 
559 		base = RK3328_GRF_GPIO0A_IOMUX;
560 
561 		s = splhigh();
562 
563 		/* IOMUX control */
564 		off = bank * 0x10 + (idx / 8) * 0x04;
565 
566 		/* GPIO2B, GPIO2C, GPIO3A and GPIO3B are special. */
567 		if (bank == 2 && idx == 15) {
568 			mask = 0x7;
569 			bits = mux;
570 		} else if (bank == 2 && idx >= 16 && idx <= 20) {
571 			mask = (0x7 << ((idx - 16) * 3));
572 			bits = (mux << ((idx - 16) * 3));
573 		} else if (bank == 2 && idx >= 21 && idx <= 23) {
574 			mask = (0x7 << ((idx - 21) * 3));
575 			bits = (mux << ((idx - 21) * 3));
576 		} else if (bank == 3 && idx <= 4) {
577 			mask = (0x7 << (idx * 3));
578 			bits = (mux << (idx * 3));
579 		} else if (bank == 3 && idx >= 5 && idx <= 7) {
580 			mask = (0x7 << ((idx - 5) * 3));
581 			bits = (mux << ((idx - 5) * 3));
582 		} else if (bank == 3 && idx >= 8 && idx <= 12) {
583 			mask = (0x7 << ((idx - 8) * 3));
584 			bits = (mux << ((idx - 8) * 3));
585 		} else if (bank == 3 && idx >= 13 && idx <= 15) {
586 			mask = (0x7 << ((idx - 13) * 3));
587 			bits = (mux << ((idx - 13) * 3));
588 		} else {
589 			mask = (0x3 << ((idx % 8) * 2));
590 			bits = (mux << ((idx % 8) * 2));
591 		}
592 		if (bank > 2 || (bank == 2 && idx >= 15))
593 			off += 0x04;
594 		if (bank > 2 || (bank == 2 && idx >= 21))
595 			off += 0x04;
596 		if (bank > 3 || (bank == 3 && idx >= 5))
597 			off += 0x04;
598 		if (bank > 3 || (bank == 3 && idx >= 13))
599 			off += 0x04;
600 		regmap_write_4(rm, base + off, mask << 16 | bits);
601 
602 		/* GPIO pad pull down and pull up control */
603 		if (pull >= 0) {
604 			off = 0x100 + bank * 0x10 + (idx / 8) * 0x04;
605 			mask = (0x3 << ((idx % 8) * 2));
606 			bits = (pull << ((idx % 8) * 2));
607 			regmap_write_4(rm, base + off, mask << 16 | bits);
608 		}
609 
610 		/* GPIO drive strength control */
611 		if (strength >= 0) {
612 			off = 0x200 + bank * 0x10 + (idx / 8) * 0x04;
613 			mask = (0x3 << ((idx % 8) * 2));
614 			bits = (strength << ((idx % 8) * 2));
615 			regmap_write_4(rm, base + off, mask << 16 | bits);
616 		}
617 
618 		splx(s);
619 	}
620 
621 	free(pins, M_TEMP, len);
622 	return 0;
623 
624 fail:
625 	free(pins, M_TEMP, len);
626 	return -1;
627 }
628 
629 /*
630  * Rockchip RK3399
631  */
632 
633 int
634 rk3399_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
635 {
636 	int pull_up, pull_down;
637 	int node;
638 
639 	node = OF_getnodebyphandle(phandle);
640 	if (node == 0)
641 		return -1;
642 
643 	if (bank == 2 && idx >= 16) {
644 		pull_up = 3;
645 		pull_down = 1;
646 	} else {
647 		pull_up = 1;
648 		pull_down = 2;
649 	}
650 
651 	if (OF_getproplen(node, "bias-disable") == 0)
652 		return 0;
653 	if (OF_getproplen(node, "bias-pull-up") == 0)
654 		return pull_up;
655 	if (OF_getproplen(node, "bias-pull-down") == 0)
656 		return pull_down;
657 
658 	return -1;
659 }
660 
661 /* Magic because the drive strength configurations vary wildly. */
662 
663 const int rk3399_strength_levels[][8] = {
664 	{ 2, 4, 8, 12 },			/* default */
665 	{ 3, 6, 9, 12 },			/* 1.8V or 3.0V */
666 	{ 5, 10, 15, 20 },			/* 1.8V only */
667 	{ 4, 6, 8, 10, 12, 14, 16, 18 },	/* 1.8V or 3.0V auto */
668 	{ 4, 7, 10, 13, 16, 19, 22, 26 },	/* 3.3V */
669 };
670 
671 const int rk3399_strength_types[][4] = {
672 	{ 2, 2, 0, 0 },
673 	{ 1, 1, 1, 1 },
674 	{ 1, 1, 2, 2 },
675 	{ 4, 4, 4, 1 },
676 	{ 1, 3, 1, 1 },
677 };
678 
679 const int rk3399_strength_regs[][4] = {
680 	{ 0x0080, 0x0088, 0x0090, 0x0098 },
681 	{ 0x00a0, 0x00a8, 0x00b0, 0x00b8 },
682 	{ 0x0100, 0x0104, 0x0108, 0x010c },
683 	{ 0x0110, 0x0118, 0x0120, 0x0128 },
684 	{ 0x012c, 0x0130, 0x0138, 0x013c },
685 };
686 
687 int
688 rk3399_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
689 {
690 	int strength, type, level;
691 	const int *levels;
692 	int node;
693 
694 	node = OF_getnodebyphandle(phandle);
695 	if (node == 0)
696 		return -1;
697 
698 	strength = OF_getpropint(node, "drive-strength", -1);
699 	if (strength == -1)
700 		return -1;
701 
702 	/* Convert drive strength to level. */
703 	type = rk3399_strength_types[bank][idx / 8];
704 	levels = rk3399_strength_levels[type];
705 	for (level = 7; level >= 0; level--) {
706 		if (strength >= levels[level] && levels[level] > 0)
707 			break;
708 	}
709 	return level;
710 }
711 
712 int
713 rk3399_pinctrl(uint32_t phandle, void *cookie)
714 {
715 	struct rkpinctrl_softc *sc = cookie;
716 	uint32_t *pins;
717 	int node, len, i;
718 
719 	KASSERT(sc->sc_grf);
720 	KASSERT(sc->sc_pmu);
721 
722 	node = OF_getnodebyphandle(phandle);
723 	if (node == 0)
724 		return -1;
725 
726 	len = OF_getproplen(node, "rockchip,pins");
727 	if (len <= 0)
728 		return -1;
729 
730 	pins = malloc(len, M_TEMP, M_WAITOK);
731 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
732 		goto fail;
733 
734 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
735 		struct regmap *rm;
736 		bus_size_t base, off;
737 		uint32_t bank, idx, mux;
738 		int pull, strength, type, shift;
739 		uint32_t mask, bits;
740 		int s;
741 
742 		bank = pins[i];
743 		idx = pins[i + 1];
744 		mux = pins[i + 2];
745 		pull = rk3399_pull(bank, idx, pins[i + 3]);
746 		strength = rk3399_strength(bank, idx, pins[i + 3]);
747 
748 		if (bank > 5 || idx > 32 || mux > 3)
749 			continue;
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
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
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
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
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
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 		pull = rk3568_pull(bank, idx, pins[i + 3]);
994 		strength = rk3568_strength(bank, idx, pins[i + 3]);
995 		schmitt = rk3568_schmitt(bank, idx, pins[i + 3]);
996 
997 		if (bank > 5 || idx > 32 || mux > 7)
998 			continue;
999 
1000 		/* Bank 0 lives in the PMU. */
1001 		if (bank < 1) {
1002 			rm = sc->sc_pmu;
1003 			iomux_base = RK3568_PMUGRF_GPIO0A_IOMUX_L;
1004 			p_base = RK3568_PMUGRF_GPIO0A_P;
1005 			ds_base = RK3568_PMUGRF_GPIO0A_DS_0;
1006 			ie_base = RK3568_PMUGRF_GPIO0A_IE;
1007 		} else {
1008 			rm = sc->sc_grf;
1009 			iomux_base = RK3568_GRF_GPIO1A_IOMUX_L;
1010 			p_base = RK3568_GRF_GPIO1A_P;
1011 			ds_base = RK3568_GRF_GPIO1A_DS_0;
1012 			ie_base = RK3568_GRF_GPIO1A_IE;
1013 			bank = bank - 1;
1014 		}
1015 
1016 		s = splhigh();
1017 
1018 		/* IOMUX control */
1019 		rk3568_route(sc, &pins[i]);
1020 		off = bank * 0x20 + (idx / 4) * 0x04;
1021 		mask = (0x7 << ((idx % 4) * 4));
1022 		bits = (mux << ((idx % 4) * 4));
1023 		regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1024 
1025 		/* GPIO pad pull down and pull up control */
1026 		if (pull >= 0) {
1027 			off = bank * 0x10 + (idx / 8) * 0x04;
1028 			mask = (0x3 << ((idx % 8) * 2));
1029 			bits = (pull << ((idx % 8) * 2));
1030 			regmap_write_4(rm, p_base + off, mask << 16 | bits);
1031 		}
1032 
1033 		/* GPIO drive strength control */
1034 		if (strength >= 0) {
1035 			off = bank * 0x40 + (idx / 2) * 0x04;
1036 			mask = (0x3f << ((idx % 2) * 8));
1037 			bits = ((1 << (strength + 1)) - 1) << ((idx % 2) * 8);
1038 			regmap_write_4(rm, ds_base + off, mask << 16 | bits);
1039 		}
1040 
1041 		/* GPIO Schmitt trigger. */
1042 		if (schmitt >= 0) {
1043 			off = bank * 0x10 + (idx / 8) * 0x04;
1044 			mask = (0x3 << ((idx % 8) * 2));
1045 			bits = schmitt << ((idx % 8) * 2);
1046 			regmap_write_4(rm, ie_base + off, mask << 16 | bits);
1047 		}
1048 
1049 		splx(s);
1050 	}
1051 
1052 	free(pins, M_TEMP, len);
1053 	return 0;
1054 
1055 fail:
1056 	free(pins, M_TEMP, len);
1057 	return -1;
1058 }
1059 
1060 
1061 /*
1062  * Rockchip RK3588
1063  */
1064 
1065 int
1066 rk3588_pull(uint32_t bank, uint32_t idx, uint32_t phandle)
1067 {
1068 	int node;
1069 
1070 	node = OF_getnodebyphandle(phandle);
1071 	if (node == 0)
1072 		return -1;
1073 
1074 	if (OF_getproplen(node, "bias-disable") == 0)
1075 		return 0;
1076 	if (OF_getproplen(node, "bias-pull-up") == 0)
1077 		return 3;
1078 	if (OF_getproplen(node, "bias-pull-down") == 0)
1079 		return 1;
1080 
1081 	return -1;
1082 }
1083 
1084 int
1085 rk3588_strength(uint32_t bank, uint32_t idx, uint32_t phandle)
1086 {
1087 	int node;
1088 
1089 	node = OF_getnodebyphandle(phandle);
1090 	if (node == 0)
1091 		return -1;
1092 
1093 	return OF_getpropint(node, "drive-strength", -1);
1094 }
1095 
1096 int
1097 rk3588_schmitt(uint32_t bank, uint32_t idx, uint32_t phandle)
1098 {
1099 	int node;
1100 
1101 	node = OF_getnodebyphandle(phandle);
1102 	if (node == 0)
1103 		return -1;
1104 
1105 	if (OF_getproplen(node, "input-schmitt-disable") == 0)
1106 		return 0;
1107 	if (OF_getproplen(node, "input-schmitt-enable") == 0)
1108 		return 1;
1109 
1110 	return -1;
1111 }
1112 
1113 #define RK3588_PMU1_IOC		0x0000
1114 #define RK3588_PMU2_IOC		0x4000
1115 #define RK3588_BUS_IOC		0x8000
1116 #define RK3588_VCCIO1_4_IOC	0x9000
1117 #define RK3588_VCCIO3_5_IOC	0xa000
1118 #define RK3588_VCCIO2_IOC	0xb000
1119 #define RK3588_VCCIO6_IOC	0xc000
1120 #define RK3588_EMMC_IOC		0xd000
1121 
1122 bus_size_t
1123 rk3588_base(uint32_t bank, uint32_t idx)
1124 {
1125 	if (bank == 1 && idx < 32)
1126 		return RK3588_VCCIO1_4_IOC;
1127 	if (bank == 2 && idx < 6)
1128 		return RK3588_EMMC_IOC;
1129 	if (bank == 2 && idx < 24)
1130 		return RK3588_VCCIO3_5_IOC;
1131 	if (bank == 2 && idx < 32)
1132 		return RK3588_EMMC_IOC;
1133 	if (bank == 3 && idx < 32)
1134 		return RK3588_VCCIO3_5_IOC;
1135 	if (bank == 4 && idx < 18)
1136 		return RK3588_VCCIO6_IOC;
1137 	if (bank == 4 && idx < 24)
1138 		return RK3588_VCCIO3_5_IOC;
1139 	if (bank == 4 && idx < 32)
1140 		return RK3588_VCCIO2_IOC;
1141 
1142 	return (bus_size_t)-1;
1143 }
1144 
1145 int
1146 rk3588_pinctrl(uint32_t phandle, void *cookie)
1147 {
1148 	struct rkpinctrl_softc *sc = cookie;
1149 	struct regmap *rm = sc->sc_grf;
1150 	uint32_t *pins;
1151 	int node, len, i;
1152 
1153 	KASSERT(sc->sc_grf);
1154 
1155 	node = OF_getnodebyphandle(phandle);
1156 	if (node == 0)
1157 		return -1;
1158 
1159 	len = OF_getproplen(node, "rockchip,pins");
1160 	if (len <= 0)
1161 		return -1;
1162 
1163 	pins = malloc(len, M_TEMP, M_WAITOK);
1164 	if (OF_getpropintarray(node, "rockchip,pins", pins, len) != len)
1165 		goto fail;
1166 
1167 	for (i = 0; i < len / sizeof(uint32_t); i += 4) {
1168 		bus_size_t iomux_base, p_base, ds_base, smt_base, off;
1169 		uint32_t bank, idx, mux;
1170 		int pull, strength, schmitt;
1171 		uint32_t mask, bits;
1172 		int s;
1173 
1174 		bank = pins[i];
1175 		idx = pins[i + 1];
1176 		mux = pins[i + 2];
1177 		pull = rk3568_pull(bank, idx, pins[i + 3]);
1178 		strength = rk3568_strength(bank, idx, pins[i + 3]);
1179 		schmitt = rk3568_schmitt(bank, idx, pins[i + 3]);
1180 
1181 		if (bank > 5 || idx > 32 || mux > 15)
1182 			continue;
1183 
1184 		if (bank == 0 && idx < 12) {
1185 			/* PMU1 */
1186 			iomux_base = RK3588_PMU1_IOC;
1187 		} else {
1188 			/* BUS */
1189 			iomux_base = RK3588_BUS_IOC;
1190 		}
1191 
1192 		if (bank == 0) {
1193 			if (idx < 12) {
1194 				/* PMU1 */
1195 				p_base = RK3588_PMU1_IOC + 0x0020;
1196 				ds_base = RK3588_PMU1_IOC + 0x0010;
1197 				smt_base = RK3588_PMU1_IOC + 0x0030;
1198 			} else {
1199 				/* PMU2 */
1200 				p_base = RK3588_PMU2_IOC + 0x0024;
1201 				ds_base = RK3588_PMU2_IOC + 0x0008;
1202 				smt_base = RK3588_PMU2_IOC + 0x003c;
1203 			}
1204 		} else {
1205 			bus_size_t base = rk3588_base(bank, idx);
1206 			KASSERT(base != (bus_size_t)-1);
1207 
1208 			p_base = base + 0x0100;
1209 			ds_base = base + 0x0000;
1210 			smt_base = base + 0x0200;
1211 		}
1212 
1213 		s = splhigh();
1214 
1215 		/* IOMUX control */
1216 		off = bank * 0x20 + (idx / 4) * 0x04;
1217 		mask = (0xf << ((idx % 4) * 4));
1218 		bits = (mux << ((idx % 4) * 4));
1219 		regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1220 		if (bank == 0 && idx > 12) {
1221 			iomux_base = RK3588_PMU2_IOC;
1222 			off = (idx - 12) / 4 * 0x04;
1223 			mux = (mux < 8) ? mux : 8;
1224 			bits = (mux << ((idx % 4) * 4));
1225 			regmap_write_4(rm, iomux_base + off, mask << 16 | bits);
1226 		}
1227 
1228 		/* GPIO pad pull down and pull up control */
1229 		if (pull >= 0) {
1230 			off = bank * 0x10 + (idx / 8) * 0x04;
1231 			mask = (0x3 << ((idx % 8) * 2));
1232 			bits = (pull << ((idx % 8) * 2));
1233 			regmap_write_4(rm, p_base + off, mask << 16 | bits);
1234 		}
1235 
1236 		/* GPIO drive strength control */
1237 		if (strength >= 0) {
1238 			off = bank * 0x20 + (idx / 4) * 0x04;
1239 			mask = (0xf << ((idx % 4) * 4));
1240 			bits = ((1 << (strength + 1)) - 1) << ((idx % 4) * 4);
1241 			regmap_write_4(rm, ds_base + off, mask << 16 | bits);
1242 		}
1243 
1244 		/* GPIO Schmitt trigger. */
1245 		if (schmitt >= 0) {
1246 			off = bank * 0x10 + (idx / 8) * 0x04;
1247 			mask = (0x1 << (idx % 8));
1248 			bits = schmitt << (idx % 8);
1249 			regmap_write_4(rm, smt_base + off, mask << 16 | bits);
1250 		}
1251 
1252 		splx(s);
1253 	}
1254 
1255 	free(pins, M_TEMP, len);
1256 	return 0;
1257 
1258 fail:
1259 	free(pins, M_TEMP, len);
1260 	return -1;
1261 }
1262