xref: /freebsd/sys/arm64/rockchip/rk_pinctrl.c (revision 0957b409)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <manu@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36 
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/rman.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 
43 #include <machine/bus.h>
44 #include <machine/resource.h>
45 #include <machine/intr.h>
46 
47 #include <dev/fdt/simplebus.h>
48 
49 #include <dev/ofw/ofw_bus.h>
50 #include <dev/ofw/ofw_bus_subr.h>
51 
52 #include <dev/fdt/fdt_pinctrl.h>
53 
54 #include <dev/extres/syscon/syscon.h>
55 
56 #include "syscon_if.h"
57 
58 #include "opt_soc.h"
59 
60 struct rk_pinctrl_pin_drive {
61 	uint32_t	bank;
62 	uint32_t	subbank;
63 	uint32_t	offset;
64 	uint32_t	value;
65 	uint32_t	ma;
66 };
67 
68 struct rk_pinctrl_bank {
69 	uint32_t	bank_num;
70 	uint32_t	subbank_num;
71 	uint32_t	offset;
72 	uint32_t	nbits;
73 };
74 
75 struct rk_pinctrl_pin_fixup {
76 	uint32_t	bank;
77 	uint32_t	subbank;
78 	uint32_t	pin;
79 	uint32_t	reg;
80 	uint32_t	bit;
81 	uint32_t	mask;
82 };
83 
84 struct rk_pinctrl_softc;
85 
86 struct rk_pinctrl_conf {
87 	struct rk_pinctrl_bank		*iomux_conf;
88 	uint32_t			iomux_nbanks;
89 	struct rk_pinctrl_pin_fixup	*pin_fixup;
90 	uint32_t			npin_fixup;
91 	struct rk_pinctrl_pin_drive	*pin_drive;
92 	uint32_t			npin_drive;
93 	uint32_t			(*get_pd_offset)(struct rk_pinctrl_softc *, uint32_t);
94 	struct syscon			*(*get_syscon)(struct rk_pinctrl_softc *, uint32_t);
95 };
96 
97 struct rk_pinctrl_softc {
98 	struct simplebus_softc	simplebus_sc;
99 	device_t		dev;
100 	struct syscon		*grf;
101 	struct syscon		*pmu;
102 	struct rk_pinctrl_conf	*conf;
103 };
104 
105 static struct rk_pinctrl_bank rk3328_iomux_bank[] = {
106 	{
107 		.bank_num = 0,
108 		.subbank_num = 0,
109 		.offset = 0x00,
110 		.nbits = 2,
111 	},
112 	{
113 		.bank_num = 0,
114 		.subbank_num = 1,
115 		.offset = 0x04,
116 		.nbits = 2,
117 	},
118 	{
119 		.bank_num = 0,
120 		.subbank_num = 2,
121 		.offset = 0x08,
122 		.nbits = 2,
123 	},
124 	{
125 		.bank_num = 0,
126 		.subbank_num = 3,
127 		.offset = 0xc,
128 		.nbits = 2,
129 	},
130 	{
131 		.bank_num = 1,
132 		.subbank_num = 0,
133 		.offset = 0x10,
134 		.nbits = 2,
135 	},
136 	{
137 		.bank_num = 1,
138 		.subbank_num = 1,
139 		.offset = 0x14,
140 		.nbits = 2,
141 	},
142 	{
143 		.bank_num = 1,
144 		.subbank_num = 2,
145 		.offset = 0x18,
146 		.nbits = 2,
147 	},
148 	{
149 		.bank_num = 1,
150 		.subbank_num = 3,
151 		.offset = 0x1C,
152 		.nbits = 2,
153 	},
154 	{
155 		.bank_num = 2,
156 		.subbank_num = 0,
157 		.offset = 0x20,
158 		.nbits = 2,
159 	},
160 	{
161 		.bank_num = 2,
162 		.subbank_num = 1,
163 		.offset = 0x24,
164 		.nbits = 3,
165 	},
166 	{
167 		.bank_num = 2,
168 		.subbank_num = 2,
169 		.offset = 0x2c,
170 		.nbits = 3,
171 	},
172 	{
173 		.bank_num = 2,
174 		.subbank_num = 3,
175 		.offset = 0x34,
176 		.nbits = 2,
177 	},
178 	{
179 		.bank_num = 3,
180 		.subbank_num = 0,
181 		.offset = 0x38,
182 		.nbits = 3,
183 	},
184 	{
185 		.bank_num = 3,
186 		.subbank_num = 1,
187 		.offset = 0x40,
188 		.nbits = 3,
189 	},
190 	{
191 		.bank_num = 3,
192 		.subbank_num = 2,
193 		.offset = 0x48,
194 		.nbits = 3,
195 	},
196 	{
197 		.bank_num = 3,
198 		.subbank_num = 3,
199 		.offset = 0x4c,
200 		.nbits = 3,
201 	},
202 };
203 
204 static struct rk_pinctrl_pin_fixup rk3328_pin_fixup[] = {
205 	{
206 		.bank = 2,
207 		.pin = 12,
208 		.reg = 0x24,
209 		.bit = 8,
210 		.mask = 0x300,
211 	},
212 	{
213 		.bank = 2,
214 		.pin = 15,
215 		.reg = 0x28,
216 		.bit = 0,
217 		.mask = 0x7,
218 	},
219 	{
220 		.bank = 2,
221 		.pin = 23,
222 		.reg = 0x30,
223 		.bit = 14,
224 		.mask = 0x6000,
225 	},
226 };
227 
228 #define	RK_PINDRIVE(_bank, _subbank, _offset, _value, _ma)	\
229 	{	\
230 		.bank = _bank,		\
231 		.subbank = _subbank,	\
232 		.offset = _offset,	\
233 		.value = _value,	\
234 		.ma = _ma,		\
235 	},
236 
237 static struct rk_pinctrl_pin_drive rk3328_pin_drive[] = {
238 	RK_PINDRIVE(0, 0, 0x200, 0, 2)
239 	RK_PINDRIVE(0, 0, 0x200, 1, 4)
240 	RK_PINDRIVE(0, 0, 0x200, 2, 8)
241 	RK_PINDRIVE(0, 0, 0x200, 3, 12)
242 
243 	RK_PINDRIVE(0, 1, 0x204, 0, 2)
244 	RK_PINDRIVE(0, 1, 0x204, 1, 4)
245 	RK_PINDRIVE(0, 1, 0x204, 2, 8)
246 	RK_PINDRIVE(0, 1, 0x204, 3, 12)
247 
248 	RK_PINDRIVE(0, 2, 0x208, 0, 2)
249 	RK_PINDRIVE(0, 2, 0x208, 1, 4)
250 	RK_PINDRIVE(0, 2, 0x208, 2, 8)
251 	RK_PINDRIVE(0, 2, 0x208, 3, 12)
252 
253 	RK_PINDRIVE(0, 3, 0x20C, 0, 2)
254 	RK_PINDRIVE(0, 3, 0x20C, 1, 4)
255 	RK_PINDRIVE(0, 3, 0x20C, 2, 8)
256 	RK_PINDRIVE(0, 3, 0x20C, 3, 12)
257 
258 	RK_PINDRIVE(1, 0, 0x210, 0, 2)
259 	RK_PINDRIVE(1, 0, 0x210, 1, 4)
260 	RK_PINDRIVE(1, 0, 0x210, 2, 8)
261 	RK_PINDRIVE(1, 0, 0x210, 3, 12)
262 
263 	RK_PINDRIVE(1, 1, 0x214, 0, 2)
264 	RK_PINDRIVE(1, 1, 0x214, 1, 4)
265 	RK_PINDRIVE(1, 1, 0x214, 2, 8)
266 	RK_PINDRIVE(1, 1, 0x214, 3, 12)
267 
268 	RK_PINDRIVE(1, 2, 0x218, 0, 2)
269 	RK_PINDRIVE(1, 2, 0x218, 1, 4)
270 	RK_PINDRIVE(1, 2, 0x218, 2, 8)
271 	RK_PINDRIVE(1, 2, 0x218, 3, 12)
272 
273 	RK_PINDRIVE(1, 3, 0x21C, 0, 2)
274 	RK_PINDRIVE(1, 3, 0x21C, 1, 4)
275 	RK_PINDRIVE(1, 3, 0x21C, 2, 8)
276 	RK_PINDRIVE(1, 3, 0x21C, 3, 12)
277 
278 	RK_PINDRIVE(2, 0, 0x220, 0, 2)
279 	RK_PINDRIVE(2, 0, 0x220, 1, 4)
280 	RK_PINDRIVE(2, 0, 0x220, 2, 8)
281 	RK_PINDRIVE(2, 0, 0x220, 3, 12)
282 
283 	RK_PINDRIVE(2, 1, 0x224, 0, 2)
284 	RK_PINDRIVE(2, 1, 0x224, 1, 4)
285 	RK_PINDRIVE(2, 1, 0x224, 2, 8)
286 	RK_PINDRIVE(2, 1, 0x224, 3, 12)
287 
288 	RK_PINDRIVE(2, 2, 0x228, 0, 2)
289 	RK_PINDRIVE(2, 2, 0x228, 1, 4)
290 	RK_PINDRIVE(2, 2, 0x228, 2, 8)
291 	RK_PINDRIVE(2, 2, 0x228, 3, 12)
292 
293 	RK_PINDRIVE(2, 3, 0x22C, 0, 2)
294 	RK_PINDRIVE(2, 3, 0x22C, 1, 4)
295 	RK_PINDRIVE(2, 3, 0x22C, 2, 8)
296 	RK_PINDRIVE(2, 3, 0x22C, 3, 12)
297 
298 	RK_PINDRIVE(3, 0, 0x230, 0, 2)
299 	RK_PINDRIVE(3, 0, 0x230, 1, 4)
300 	RK_PINDRIVE(3, 0, 0x230, 2, 8)
301 	RK_PINDRIVE(3, 0, 0x230, 3, 12)
302 
303 	RK_PINDRIVE(3, 1, 0x234, 0, 2)
304 	RK_PINDRIVE(3, 1, 0x234, 1, 4)
305 	RK_PINDRIVE(3, 1, 0x234, 2, 8)
306 	RK_PINDRIVE(3, 1, 0x234, 3, 12)
307 
308 	RK_PINDRIVE(3, 2, 0x238, 0, 2)
309 	RK_PINDRIVE(3, 2, 0x238, 1, 4)
310 	RK_PINDRIVE(3, 2, 0x238, 2, 8)
311 	RK_PINDRIVE(3, 2, 0x238, 3, 12)
312 
313 	RK_PINDRIVE(3, 3, 0x23C, 0, 2)
314 	RK_PINDRIVE(3, 3, 0x23C, 1, 4)
315 	RK_PINDRIVE(3, 3, 0x23C, 2, 8)
316 	RK_PINDRIVE(3, 3, 0x23C, 3, 12)
317 };
318 
319 static uint32_t
320 rk3328_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
321 {
322 	return (0x100);
323 }
324 
325 static struct syscon *
326 rk3328_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
327 {
328 	return (sc->grf);
329 }
330 
331 struct rk_pinctrl_conf rk3328_conf = {
332 	.iomux_conf = rk3328_iomux_bank,
333 	.iomux_nbanks = nitems(rk3328_iomux_bank),
334 	.pin_fixup = rk3328_pin_fixup,
335 	.npin_fixup = nitems(rk3328_pin_fixup),
336 	.pin_drive = rk3328_pin_drive,
337 	.npin_drive = nitems(rk3328_pin_drive),
338 	.get_pd_offset = rk3328_get_pd_offset,
339 	.get_syscon = rk3328_get_syscon,
340 };
341 
342 static struct rk_pinctrl_bank rk3399_iomux_bank[] = {
343 	{
344 		.bank_num = 0,
345 		.subbank_num = 0,
346 		.offset = 0x00,
347 		.nbits = 2,
348 	},
349 	{
350 		.bank_num = 0,
351 		.subbank_num = 1,
352 		.offset = 0x04,
353 		.nbits = 2,
354 	},
355 	{
356 		.bank_num = 0,
357 		.subbank_num = 2,
358 		.offset = 0x08,
359 		.nbits = 2,
360 	},
361 	{
362 		.bank_num = 0,
363 		.subbank_num = 3,
364 		.offset = 0x0c,
365 		.nbits = 2,
366 	},
367 	{
368 		.bank_num = 1,
369 		.subbank_num = 0,
370 		.offset = 0x10,
371 		.nbits = 2,
372 	},
373 	{
374 		.bank_num = 1,
375 		.subbank_num = 1,
376 		.offset = 0x14,
377 		.nbits = 2,
378 	},
379 	{
380 		.bank_num = 1,
381 		.subbank_num = 2,
382 		.offset = 0x18,
383 		.nbits = 2,
384 	},
385 	{
386 		.bank_num = 1,
387 		.subbank_num = 3,
388 		.offset = 0x1c,
389 		.nbits = 2,
390 	},
391 	{
392 		.bank_num = 2,
393 		.subbank_num = 0,
394 		.offset = 0xe000,
395 		.nbits = 2,
396 	},
397 	{
398 		.bank_num = 2,
399 		.subbank_num = 1,
400 		.offset = 0xe004,
401 		.nbits = 2,
402 	},
403 	{
404 		.bank_num = 2,
405 		.subbank_num = 2,
406 		.offset = 0xe008,
407 		.nbits = 2,
408 	},
409 	{
410 		.bank_num = 2,
411 		.subbank_num = 3,
412 		.offset = 0xe00c,
413 		.nbits = 2,
414 	},
415 	{
416 		.bank_num = 3,
417 		.subbank_num = 0,
418 		.offset = 0xe010,
419 		.nbits = 2,
420 	},
421 	{
422 		.bank_num = 3,
423 		.subbank_num = 1,
424 		.offset = 0xe014,
425 		.nbits = 2,
426 	},
427 	{
428 		.bank_num = 3,
429 		.subbank_num = 2,
430 		.offset = 0xe018,
431 		.nbits = 2,
432 	},
433 	{
434 		.bank_num = 3,
435 		.subbank_num = 3,
436 		.offset = 0xe01c,
437 		.nbits = 2,
438 	},
439 	{
440 		.bank_num = 4,
441 		.subbank_num = 0,
442 		.offset = 0xe020,
443 		.nbits = 2,
444 	},
445 	{
446 		.bank_num = 4,
447 		.subbank_num = 1,
448 		.offset = 0xe024,
449 		.nbits = 2,
450 	},
451 	{
452 		.bank_num = 4,
453 		.subbank_num = 2,
454 		.offset = 0xe028,
455 		.nbits = 2,
456 	},
457 	{
458 		.bank_num = 4,
459 		.subbank_num = 3,
460 		.offset = 0xe02c,
461 		.nbits = 2,
462 	},
463 };
464 
465 static struct rk_pinctrl_pin_fixup rk3399_pin_fixup[] = {};
466 
467 static struct rk_pinctrl_pin_drive rk3399_pin_drive[] = {
468 	/* GPIO0A */
469 	RK_PINDRIVE(0, 0, 0x80, 0, 5)
470 	RK_PINDRIVE(0, 0, 0x80, 1, 10)
471 	RK_PINDRIVE(0, 0, 0x80, 2, 15)
472 	RK_PINDRIVE(0, 0, 0x80, 3, 20)
473 
474 	/* GPIOB */
475 	RK_PINDRIVE(0, 1, 0x88, 0, 5)
476 	RK_PINDRIVE(0, 1, 0x88, 1, 10)
477 	RK_PINDRIVE(0, 1, 0x88, 2, 15)
478 	RK_PINDRIVE(0, 1, 0x88, 3, 20)
479 
480 	/* GPIO1A */
481 	RK_PINDRIVE(1, 0, 0xA0, 0, 3)
482 	RK_PINDRIVE(1, 0, 0xA0, 1, 6)
483 	RK_PINDRIVE(1, 0, 0xA0, 2, 9)
484 	RK_PINDRIVE(1, 0, 0xA0, 3, 12)
485 
486 	/* GPIO1B */
487 	RK_PINDRIVE(1, 1, 0xA8, 0, 3)
488 	RK_PINDRIVE(1, 1, 0xA8, 1, 6)
489 	RK_PINDRIVE(1, 1, 0xA8, 2, 9)
490 	RK_PINDRIVE(1, 1, 0xA8, 3, 12)
491 
492 	/* GPIO1C */
493 	RK_PINDRIVE(1, 2, 0xB0, 0, 3)
494 	RK_PINDRIVE(1, 2, 0xB0, 1, 6)
495 	RK_PINDRIVE(1, 2, 0xB0, 2, 9)
496 	RK_PINDRIVE(1, 2, 0xB0, 3, 12)
497 
498 	/* GPIO1D */
499 	RK_PINDRIVE(1, 3, 0xB8, 0, 3)
500 	RK_PINDRIVE(1, 3, 0xB8, 1, 6)
501 	RK_PINDRIVE(1, 3, 0xB8, 2, 9)
502 	RK_PINDRIVE(1, 3, 0xB8, 3, 12)
503 };
504 
505 static uint32_t
506 rk3399_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
507 {
508 	if (bank < 2)
509 		return (0x40);
510 
511 	return (0xe040);
512 }
513 
514 static struct syscon *
515 rk3399_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank)
516 {
517 	if (bank < 2)
518 		return (sc->pmu);
519 
520 	return (sc->grf);
521 }
522 
523 struct rk_pinctrl_conf rk3399_conf = {
524 	.iomux_conf = rk3399_iomux_bank,
525 	.iomux_nbanks = nitems(rk3399_iomux_bank),
526 	.pin_fixup = rk3399_pin_fixup,
527 	.npin_fixup = nitems(rk3399_pin_fixup),
528 	.pin_drive = rk3399_pin_drive,
529 	.npin_drive = nitems(rk3399_pin_drive),
530 	.get_pd_offset = rk3399_get_pd_offset,
531 	.get_syscon = rk3399_get_syscon,
532 };
533 
534 static struct ofw_compat_data compat_data[] = {
535 #ifdef SOC_ROCKCHIP_RK3328
536 	{"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf},
537 #endif
538 #ifdef SOC_ROCKCHIP_RK3399
539 	{"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf},
540 #endif
541 	{NULL,             0}
542 };
543 
544 static int
545 rk_pinctrl_parse_bias(phandle_t node)
546 {
547 	if (OF_hasprop(node, "bias-disable"))
548 		return (0);
549 	if (OF_hasprop(node, "bias-pull-up"))
550 		return (1);
551 	if (OF_hasprop(node, "bias-pull-down"))
552 		return (2);
553 
554 	return (-1);
555 }
556 
557 static int rk_pinctrl_parse_drive(struct rk_pinctrl_softc *sc, phandle_t node,
558   uint32_t bank, uint32_t subbank, uint32_t *drive, uint32_t *offset)
559 {
560 	uint32_t value;
561 	int i;
562 
563 	if (OF_getencprop(node, "drive-strength", &value,
564 	    sizeof(value)) != 0)
565 		return (-1);
566 
567 	/* Map to the correct drive value */
568 	for (i = 0; i < sc->conf->npin_drive; i++) {
569 		if (sc->conf->pin_drive[i].bank != bank &&
570 		    sc->conf->pin_drive[i].subbank != subbank)
571 			continue;
572 		if (sc->conf->pin_drive[i].ma == value) {
573 			*drive = sc->conf->pin_drive[i].value;
574 			return (0);
575 		}
576 	}
577 
578 	return (-1);
579 }
580 
581 static void
582 rk_pinctrl_get_fixup(struct rk_pinctrl_softc *sc, uint32_t bank, uint32_t pin,
583     uint32_t *reg, uint32_t *mask, uint32_t *bit)
584 {
585 	int i;
586 
587 	for (i = 0; i < sc->conf->npin_fixup; i++)
588 		if (sc->conf->pin_fixup[i].bank == bank &&
589 		    sc->conf->pin_fixup[i].pin == pin) {
590 			*reg = sc->conf->pin_fixup[i].reg;
591 			*mask = sc->conf->pin_fixup[i].mask;
592 			*bit = sc->conf->pin_fixup[i].bit;
593 
594 			return;
595 		}
596 }
597 
598 static void
599 rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata)
600 {
601 	phandle_t pin_conf;
602 	struct syscon *syscon;
603 	uint32_t bank, subbank, pin, function, bias;
604 	uint32_t bit, mask, reg, drive;
605 	int i;
606 
607 	bank = pindata[0];
608 	pin = pindata[1];
609 	function = pindata[2];
610 	pin_conf = OF_node_from_xref(pindata[3]);
611 	subbank = pin / 8;
612 
613 	for (i = 0; i < sc->conf->iomux_nbanks; i++)
614 		if (sc->conf->iomux_conf[i].bank_num == bank &&
615 		    sc->conf->iomux_conf[i].subbank_num == subbank)
616 			break;
617 
618 	if (i == sc->conf->iomux_nbanks) {
619 		device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin,
620 		    bank);
621 		return;
622 	}
623 
624 	/* Find syscon */
625 	syscon = sc->conf->get_syscon(sc, bank);
626 
627 	/* Parse pin function */
628 	reg = sc->conf->iomux_conf[i].offset;
629 	switch (sc->conf->iomux_conf[i].nbits) {
630 	case 3:
631 		if ((pin % 8) >= 5)
632 			reg += 4;
633 		bit = (pin % 8 % 5) * 3;
634 		mask = (0x7 << bit) << 16;
635 		break;
636 	case 2:
637 	default:
638 		bit = (pin % 8) * 2;
639 		mask = (0x3 << bit) << 16;
640 		break;
641 	}
642 	rk_pinctrl_get_fixup(sc, bank, pin, &reg, &mask, &bit);
643 	SYSCON_WRITE_4(syscon, reg, function << bit | mask);
644 
645 	/* Pull-Up/Down */
646 	bias = rk_pinctrl_parse_bias(pin_conf);
647 	if (bias >= 0) {
648 		reg = sc->conf->get_pd_offset(sc, bank);
649 
650 		reg += bank * 0x10 + ((pin / 8) * 0x4);
651 		bit = (pin % 8) * 2;
652 		mask = (0x3 << bit) << 16;
653 		SYSCON_WRITE_4(syscon, reg, bias << bit | mask);
654 	}
655 
656 	/* Drive Strength */
657 	if (rk_pinctrl_parse_drive(sc, pin_conf, bank, subbank, &drive, &reg) == 0) {
658 		bit = (pin % 8) * 2;
659 		mask = (0x3 << bit) << 16;
660 		SYSCON_WRITE_4(syscon, reg, bias << bit | mask);
661 	}
662 }
663 
664 static int
665 rk_pinctrl_configure_pins(device_t dev, phandle_t cfgxref)
666 {
667 	struct rk_pinctrl_softc *sc;
668 	phandle_t node;
669 	uint32_t *pins;
670 	int i, npins;
671 
672 	sc = device_get_softc(dev);
673 	node = OF_node_from_xref(cfgxref);
674 
675 	npins = OF_getencprop_alloc_multi(node, "rockchip,pins",  sizeof(*pins),
676 	    (void **)&pins);
677 	if (npins <= 0)
678 		return (ENOENT);
679 
680 	for (i = 0; i != npins; i += 4)
681 		rk_pinctrl_configure_pin(sc, pins + i);
682 
683 	return (0);
684 }
685 
686 static int
687 rk_pinctrl_probe(device_t dev)
688 {
689 
690 	if (!ofw_bus_status_okay(dev))
691 		return (ENXIO);
692 
693 	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
694 		return (ENXIO);
695 
696 	device_set_desc(dev, "RockChip Pinctrl controller");
697 	return (BUS_PROBE_DEFAULT);
698 }
699 
700 static int
701 rk_pinctrl_attach(device_t dev)
702 {
703 	struct rk_pinctrl_softc *sc;
704 	phandle_t node;
705 	device_t cdev;
706 
707 	sc = device_get_softc(dev);
708 	sc->dev = dev;
709 
710 	node = ofw_bus_get_node(dev);
711 
712 	if (OF_hasprop(node, "rockchip,grf") &&
713 	    syscon_get_by_ofw_property(dev, node,
714 	    "rockchip,grf", &sc->grf) != 0) {
715 		device_printf(dev, "cannot get grf driver handle\n");
716 		return (ENXIO);
717 	}
718 
719 	// RK3399 has banks in PMU. RK3328 does not have a PMU.
720 	if (ofw_bus_node_is_compatible(node, "rockchip,rk3399-pinctrl")) {
721 		if (OF_hasprop(node, "rockchip,pmu") &&
722 		    syscon_get_by_ofw_property(dev, node,
723 		    "rockchip,pmu", &sc->pmu) != 0) {
724 			device_printf(dev, "cannot get pmu driver handle\n");
725 			return (ENXIO);
726 		}
727 	}
728 
729 	sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev,
730 	    compat_data)->ocd_data;
731 
732 	fdt_pinctrl_register(dev, "rockchip,pins");
733 	fdt_pinctrl_configure_tree(dev);
734 
735 	simplebus_init(dev, node);
736 
737 	bus_generic_probe(dev);
738 
739 	/* Attach child devices */
740 	for (node = OF_child(node); node > 0; node = OF_peer(node)) {
741 		if (!ofw_bus_node_is_compatible(node, "rockchip,gpio-bank"))
742 			continue;
743 		cdev = simplebus_add_device(dev, node, 0, NULL, -1, NULL);
744 		if (cdev != NULL)
745 			device_probe_and_attach(cdev);
746 	}
747 
748 	return (bus_generic_attach(dev));
749 }
750 
751 static int
752 rk_pinctrl_detach(device_t dev)
753 {
754 
755 	return (EBUSY);
756 }
757 
758 static device_method_t rk_pinctrl_methods[] = {
759 	/* Device interface */
760 	DEVMETHOD(device_probe,		rk_pinctrl_probe),
761 	DEVMETHOD(device_attach,	rk_pinctrl_attach),
762 	DEVMETHOD(device_detach,	rk_pinctrl_detach),
763 
764         /* fdt_pinctrl interface */
765 	DEVMETHOD(fdt_pinctrl_configure,rk_pinctrl_configure_pins),
766 
767 	DEVMETHOD_END
768 };
769 
770 static devclass_t rk_pinctrl_devclass;
771 
772 DEFINE_CLASS_1(rk_pinctrl, rk_pinctrl_driver, rk_pinctrl_methods,
773     sizeof(struct rk_pinctrl_softc), simplebus_driver);
774 
775 EARLY_DRIVER_MODULE(rk_pinctrl, simplebus, rk_pinctrl_driver,
776     rk_pinctrl_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
777 MODULE_VERSION(rk_pinctrl, 1);
778