1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2018 Emmanuel Vadot <[email protected]>
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 = 2,
195 },
196 {
197 .bank_num = 3,
198 .subbank_num = 3,
199 .offset = 0x4c,
200 .nbits = 2,
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
rk3328_get_pd_offset(struct rk_pinctrl_softc * sc,uint32_t bank)320 rk3328_get_pd_offset(struct rk_pinctrl_softc *sc, uint32_t bank)
321 {
322 return (0x100);
323 }
324
325 static struct syscon *
rk3328_get_syscon(struct rk_pinctrl_softc * sc,uint32_t bank)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
rk3399_get_pd_offset(struct rk_pinctrl_softc * sc,uint32_t bank)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 *
rk3399_get_syscon(struct rk_pinctrl_softc * sc,uint32_t bank)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
rk_pinctrl_parse_bias(phandle_t node)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
rk_pinctrl_parse_drive(struct rk_pinctrl_softc * sc,phandle_t node,uint32_t bank,uint32_t subbank,uint32_t * drive,uint32_t * offset)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
rk_pinctrl_get_fixup(struct rk_pinctrl_softc * sc,uint32_t bank,uint32_t pin,uint32_t * reg,uint32_t * mask,uint32_t * bit)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
rk_pinctrl_configure_pin(struct rk_pinctrl_softc * sc,uint32_t * pindata)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, ®, &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, ®) == 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
rk_pinctrl_configure_pins(device_t dev,phandle_t cfgxref)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
rk_pinctrl_probe(device_t dev)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
rk_pinctrl_attach(device_t dev)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
rk_pinctrl_detach(device_t dev)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